跳转至

第1章 Agent 生命周期

学习目标

  • 理解 Agent 的完整设计流程与生命周期阶段
  • 掌握 Agent 循环(Perceive-Decide-Act)的运行机制
  • 学会使用 OpenAI Agents SDK 实现 Agent 迭代执行
  • 理解终止条件设计与错误处理、重试策略
  • 能够为真实业务设计可观测、可恢复的 Agent

问题导入

某团队上线了一个"工单处理助手",让 LLM 直接生成回复就返回。结果上线一周暴露三大问题:①遇到需要多次查询数据库的工单,Agent 只查一次就回答,答非所问;②工具偶发超时,Agent 直接报错退出,用户体验差;③没有明确的"完成"判断,有时模型明明已给出答案却继续空转,Token 成本飙升。

这些问题的根因都在于:团队只写了"一次调用",而没有设计 Agent 生命周期。Agent 不是"调一次 LLM",而是一个会"感知—决策—行动—观察"持续迭代的循环系统。生命周期管理决定了 Agent 何时启动、如何推进、何时终止、出错怎么办。本章将系统讲解 Agent 生命周期的每个阶段,并用 OpenAI Agents SDK 实现一个可控、可观测的 Agent 循环。

核心概念

1. Agent 设计流程

构建一个 Agent 通常包含五步:

  1. 目标定义:明确 Agent 要解决什么问题(如"处理用户工单")
  2. 能力设计:确定 Agent 需要哪些工具、哪些知识
  3. 指令编写:用 system prompt 约束 Agent 行为边界
  4. 循环设计:定义感知—决策—行动的迭代结构
  5. 终止与恢复:设计完成条件、最大轮数、错误重试与断点续跑

2. 初始化阶段

初始化阶段负责装配 Agent 运行所需的全部要素:

  • 指令(Instructions):定义角色、规则、输出格式
  • 工具集(Tools):Agent 可调用的函数列表
  • 上下文(Context):注入用户身份、会话状态等运行时数据
  • 模型配置:选择 model、temperature、max_tokens

OpenAI Agents SDK 通过 Agent 类完成初始化,所有配置以声明式参数传入。

3. Agent 循环(Perceive-Decide-Act)

Agent 的核心是一个不断迭代的循环,每个迭代包含三个阶段:

  • Perceive(感知):接收用户输入或上一轮工具结果,更新上下文
  • Decide(决策):LLM 基于当前上下文决定下一步——调用工具还是给出最终答案
  • Act(行动):执行工具调用,将结果作为新的"感知"喂回模型

这个循环会持续进行,直到模型判定任务完成或触发终止条件。

4. 终止条件

合理的终止条件防止 Agent 死循环:

  • 自然终止:模型不再发起工具调用,直接输出 final_output
  • 最大轮数(max_turns):硬性上限,SDK 的 Runner.run 支持
  • 超时控制:整体执行时间上限
  • 完成信号:通过特定工具或关键字标记完成

5. 错误处理与重试

工具调用可能失败(网络超时、参数错误、权限不足),需设计:

  • 捕获异常:把错误信息作为 observation 回传给模型,让其自我修正
  • 重试策略:对瞬时错误指数退避重试,对参数错误让模型重新决策
  • 熔断降级:连续失败 N 次后停止,返回兜底响应
  • 可观测性:记录每轮的输入、输出、耗时,便于事后排查

原理图

stateDiagram-v2
    [*] --> 初始化
    初始化 --> 感知 : 装配指令/工具/上下文

    state 循环 {
        感知 --> 决策 : 更新上下文
        决策 --> 行动 : 调用工具
        行动 --> 感知 : 工具结果回传
        决策 --> 完成 : 无工具调用
    }

    感知 --> 错误处理 : 工具异常
    错误处理 --> 决策 : 重试/回传错误
    错误处理 --> 终止 : 熔断/超限

    完成 --> [*] : 输出 final_output
    终止 --> [*] : 兜底响应

    note right of 循环
        Perceive-Decide-Act
        持续迭代直到完成
    end note

图:Agent 生命周期状态机——从初始化进入感知—决策—行动循环,遇错回传或重试,满足终止条件后退出

示例代码

1. 最小 Agent 循环(OpenAI Agents SDK)

"""
第1章示例:用 OpenAI Agents SDK 实现最小 Agent 循环
依赖:pip install openai-agents
"""
import asyncio
from agents import Agent, Runner, function_tool


@function_tool
def query_order(order_id: str) -> str:
    """查询订单状态。参数 order_id:订单号"""
    # 模拟数据库查询
    db = {
        "A1001": "已发货,预计明日送达",
        "A1002": "处理中,预计 2 天后发货",
    }
    return db.get(order_id, f"订单 {order_id} 不存在")


@function_tool
def refund_order(order_id: str, reason: str) -> str:
    """发起退款。参数 order_id:订单号,reason:退款原因"""
    return f"已为订单 {order_id} 创建退款工单,原因:{reason},预计 3 个工作日到账"


# 初始化 Agent:声明指令、工具、模型
agent = Agent(
    name="客服助手",
    instructions=(
        "你是一个电商客服助手。处理用户订单查询与退款请求。"
        "如果用户只查询,调用 query_order;如果用户要求退款,先查询再调用 refund_order。"
        "每次行动后基于结果决定下一步,信息充分时给出最终回答。"
    ),
    tools=[query_order, refund_order],
    model="gpt-4o-mini",
)


async def main():
    # Runner 负责驱动整个 Perceive-Decide-Act 循环
    result = await Runner.run(
        agent,
        "我的订单 A1001 还没到,如果明天还不到就退款,原因是物流太慢。",
        max_turns=8,  # 终止条件:最多 8 轮
    )
    print("最终回复:", result.final_output)
    print("总轮数:", len(result.raw_responses))


if __name__ == "__main__":
    asyncio.run(main())

运行结果示例:

最终回复: 您的订单 A1001 当前状态为"已发货,预计明日送达"。
          若明日仍未送达,我已为您创建退款工单(原因:物流太慢),
          预计 3 个工作日到账,请留意短信通知。
总轮数: 3

2. 带错误处理与重试的 Agent 循环

"""
带错误处理与重试的 Agent 循环:手动管理迭代,便于自定义错误策略
"""
import asyncio
from openai import AsyncOpenAI
from agents import Agent, Runner, function_tool, ToolError

client = AsyncOpenAI()


@function_tool
def unreliable_api(query: str) -> str:
    """模拟不稳定的 API:偶发失败"""
    import random
    if random.random() < 0.5:
        raise RuntimeError("API 超时")
    return f"查询 {query} 的结果:OK"


agent = Agent(
    name="容错助手",
    instructions="遇到工具错误时,向用户说明并最多重试 2 次,仍失败则给出兜底回答。",
    tools=[unreliable_api],
    model="gpt-4o-mini",
)


async def run_with_guardrail(agent, user_input, max_turns=6):
    """带熔断机制的运行器:连续失败 3 次即终止"""
    try:
        result = await Runner.run(
            agent,
            user_input,
            max_turns=max_turns,
        )
        return result.final_output
    except ToolError as e:
        # SDK 会把工具异常转为 observation,此处兜底
        return f"工具连续异常,已熔断:{e}"
    except Exception as e:
        return f"Agent 异常终止:{e}"


if __name__ == "__main__":
    out = asyncio.run(run_with_guardrail(agent, "请调用 unreliable_api 查询 weather"))
    print(out)

企业案例

案例 1:客服 Agent 生命周期管理

某电商平台客服 Agent 需处理咨询、查询、退款、投诉四类工单。团队基于生命周期设计:

  • 初始化:按工单类型加载不同工具集(查询类用 query_order,退款类用 refund_order + query_order)
  • 循环控制:max_turns=10,单工单最多 10 轮交互
  • 终止策略:模型输出 final_output 即完成;超过 10 轮升级人工
  • 错误处理:订单系统超时重试 3 次(指数退避 1s/2s/4s),仍失败则提示用户稍后重试
  • 可观测:每轮记录 tool_name、latency、token_usage,接入 Prometheus

上线后工单自动解决率从 42% 提升到 78%,平均处理时长下降 35%。关键经验:生命周期可观测比单纯提升准确率更重要——知道 Agent 在哪一步卡住,才能持续优化。

案例 2:数据分析 Agent 的断点续跑

某数据团队的 Agent 需执行"取数—清洗—分析—出图"长流程,单次可能跑 20+ 轮。团队将每轮的上下文快照存入 Redis,若进程崩溃可从最近 checkpoint 恢复,避免从头重跑。这是生命周期管理在"长任务"场景下的延伸:状态持久化 + 断点续跑。

常见问题

Q1:Agent 和单次 LLM 调用的本质区别是什么?

A:单次调用是"问—答"一对一映射;Agent 是一个循环系统,能根据中间结果动态决定下一步,可多次调用工具、多轮推进,直到满足终止条件。Agent 的核心价值在于"自主迭代"。

Q2:max_turns 设多少合适?

A:取决于任务复杂度。简单查询 3-5 轮,多步推理 8-12 轮,长流程任务 20+ 轮并配合 checkpoint。原则是够用即可,过大会导致成本失控,过小会截断必要推理。

Q3:工具调用失败时,应该重试还是把错误告诉模型?

A:两者结合。瞬时错误(网络抖动、超时)用指数退避重试;参数错误(模型传错参数)把错误信息作为 observation 回传,让模型自我修正;业务错误(订单不存在)直接回传让模型据此回答。所有错误都应可观测。

Q4:如何判断 Agent "卡住"了?

A:三个信号:①连续 N 轮调用同一工具且参数几乎相同;②模型输出"我再试试"等无进展语句;③Token 消耗突增但 final_output 未产出。检测到后应强制终止并降级。

Q5:Agent 循环必须用 LLM 做决策吗?

A:不一定。简单路由可用规则决策(如关键字匹配),复杂推理才需 LLM。混合架构(规则 + LLM)能显著降低成本,企业中常用"LLM 决策 + 规则兜底"。

面试题

  1. 简答题:描述 Agent 的 Perceive-Decide-Act 循环,并说明每个阶段的输入输出。

参考要点:Perceive 接收用户输入或工具结果更新上下文;Decide 由 LLM 决定调用工具或给出答案;Act 执行工具并把结果回传作为下一轮感知。

  1. 设计题:一个 Agent 调用工具 5 次都失败,应该如何处理?请给出完整策略。

参考要点:区分错误类型(瞬时/参数/业务);瞬时错误指数退避重试;参数错误回传让模型修正;连续失败触发熔断,返回兜底响应并告警。

  1. 实现题:用 OpenAI Agents SDK 实现一个带 max_turns 和超时控制的 Agent 运行器。

  2. 原理题:为什么说"Agent 生命周期的可观测性比准确率更重要"?

参考要点:准确率是结果指标,可观测性是过程指标;Agent 多轮迭代,无法定位卡点就无法优化;生产环境需要知道每轮的输入输出耗时才能排障。

  1. 对比题:Agent 的"自然终止"和"强制终止"有何区别?分别何时使用?

练习题

  1. 基础实现:用 OpenAI Agents SDK 实现一个"天气查询 Agent",工具为 get_weather(city),设置 max_turns=5,观察不同问题下的实际轮数。

  2. 错误注入:在示例 2 基础上,构造一个 80% 概率失败的工具,验证熔断机制是否生效,并统计平均重试次数。

  3. 可观测性:为 Agent 循环增加日志,记录每轮的 tool_name、耗时、token 数,输出为 JSONL 文件便于分析。

小结

Agent 生命周期是构建可靠 Agent 的地基。本章核心:Agent 不是一次调用,而是"初始化—感知—决策—行动"的迭代循环;终止条件(max_turns、完成信号)防止失控;错误处理(重试、回传、熔断)保障鲁棒;可观测性支撑持续优化。掌握生命周期后,下一步要解决"Agent 如何规划多步任务"——这正是第 2 章的主题。