Agent 工作循环
用“理解—计划—行动—观察—判断”循环推进任务,并受停止条件约束。
学习目标
- 能说明Agent 工作循环解决什么问题,以及何时适用。
- 能解释为什么“没有最大步数”是误区。
学习前需要掌握
背景与问题
有些任务的下一步依赖刚获得的结果:查到资料不全就换查询,发现文件冲突就暂停写入。单次模型生成无法预先知道这些外部反馈,因此需要可中断、可检查的工作循环。
循环也会带来新的失败方式,例如不断重复同一查询、在错误输出上继续推理,或直到预算耗尽才停。设计重点是让每轮产生可观察进展,并明确谁有权宣布结束。
概念定义
Agent loop 是运行器重复执行模型决策、工具调用与结果反馈,直到产生最终输出、错误、审批中断或达到限制。
直观理解
像做实验:提出下一步、动手、观察、判断,再决定继续还是结束。
核心原理
每轮先从任务状态整理当前输入,模型或控制逻辑再选择下一动作。运行器验证调用后执行工具,把真实结果加入观察;只有消费了结果,下一轮才能据此调整计划。
工具完成与任务完成需要分开。搜索工具找到一篇文章,只证明查询成功;若任务还要求比较两种方案,就必须检查证据是否覆盖比较条件。某个工具返回 done 标记也只能代表其约定范围内的完成。
停止条件包括验收通过、需要审批、信息不足、不可恢复错误,以及轮次、时间或成本达到限制。达到预算是受限停止,应保留进展和未完成项,不能伪装成正常完成。
进展检测可以比较新增证据、未解决问题和状态变化。连续重复同一输入并得到同一失败结果时,应改写查询、切换路径或停止。下方代码仅演示确定性循环骨架:固定查询一次命中就结束,没有实现模型规划或通用任务验收。
案例:比较两个城市的周末天气
任务要求比较甲城与乙城周末是否适合徒步。第一轮查询甲城得到周末预报,状态中只标记甲城证据已获得;第二轮查询乙城却返回工作日数据,运行器应把它记为范围不匹配,而不是第二份有效证据。
下一轮更正日期后获得乙城预报,再核对两份数据的日期与更新时间,才生成比较。如果乙城始终无法查询,循环在预算内停止并说明缺失数据;重复同一错误请求不算推进。这里的“理解—行动—观察”由结果驱动,不要求每轮都输出一大段计划。
理解与实践步骤
- 接收任务
- 分析任务
- 制定计划
- 选择工具
- 调用工具
- 接收工具结果
- 判断是否完成
- 输出结果或继续
代码实现
示例 1
有停止条件的本地工作循环
example_01.py用途:观察任务状态、工具返回和最大步数如何共同决定循环何时结束。
from dataclasses import dataclass
@dataclass
class StepResult:
observation: str
done: bool
def search_notes(topic: str) -> StepResult:
notes = {"Agent": "Agent 组织模型、状态与工具来完成目标。"}
text = notes.get(topic, "本地资料中没有结果")
return StepResult(text, topic in notes)
def run_agent(task: str, max_steps: int = 4) -> str:
state = {"task": task, "step": 0, "observations": []}
while state["step"] < max_steps:
state["step"] += 1
result = search_notes("Agent")
state["observations"].append(result.observation)
if result.done:
return f"第 {state['step']} 步完成:{result.observation}"
return "达到步数上限,安全停止"
print(run_agent("解释 Agent"))代码解析
解析始终位于完整代码下方,并按实际代码段逐项对应。
输入数据与任务
观察任务状态、工具返回和最大步数如何共同决定循环何时结束。
Step 1 · 1–1 行
导入当前步骤需要的数值计算、预处理、模型或评价工具。依赖集中写在代码开头,便于复现。
from dataclasses import dataclassStep 2 · 3–6 行
循环保留历史观察,完成后立即返回;未完成时受最大步数限制。
@dataclass
class StepResult:
observation: str
done: boolStep 3 · 8–11 行
这是确定性的循环骨架,不包含模型推理或自主规划。
def search_notes(topic: str) -> StepResult:
notes = {"Agent": "Agent 组织模型、状态与工具来完成目标。"}
text = notes.get(topic, "本地资料中没有结果")
return StepResult(text, topic in notes)Step 4 · 13–21 行
按学习率和梯度更新参数。步长过小会缓慢,过大会越过最低点并震荡或发散。
def run_agent(task: str, max_steps: int = 4) -> str:
state = {"task": task, "step": 0, "observations": []}
while state["step"] < max_steps:
state["step"] += 1
result = search_notes("Agent")
state["observations"].append(result.observation)
if result.done:
return f"第 {state['step']} 步完成:{result.observation}"
return "达到步数上限,安全停止"Step 5 · 23–23 行
输出中间参数、形状或最终指标,用于核对代码是否符合预期。
print(run_agent("解释 Agent"))预期输出或运行结果
第 1 步完成:Agent 组织模型、状态与工具来完成目标。
常见错误 · 3 条
- 只设“模型给出答案”这一种停止条件,导致错误或未验证结果提前结束。
- 相同调用不断失败仍原样重试,没有进展检测、时间或轮次上限。
- 把工具成功等同于整体完成,或把达到上限后的部分结果描述为完整交付。
实际应用
- 多步研究
- 本地自动化
常见错误
- 只设“模型给出答案”这一种停止条件,导致错误或未验证结果提前结束。
- 相同调用不断失败仍原样重试,没有进展检测、时间或轮次上限。
- 把工具成功等同于整体完成,或把达到上限后的部分结果描述为完整交付。
输入、输出与执行边界
输入
- 当前状态
- 工具列表
- 上一步观察
输出
- 工具调用、状态更新或最终输出
能力
- 多步研究
- 本地自动化
安全风险与信任边界
每轮观察可能含网页、文件或工具返回的诱导指令,循环应将其视为证据而非新的控制规则。停止条件既要考虑目标是否完成,也要检测无进展、重复动作和未确认的副作用,避免把一次误判扩展成连续操作。
性能与失败模式
更多轮次只增加尝试机会,并不保证更好结果。记录每轮状态变化、调用数和新增证据,按总时间或成本限制循环;若连续几轮没有减少不确定性,应切换策略或明确失败,而不是无限生成相似计划。
推荐学习资料
OpenAI Agents SDK 文档
系统介绍 Agent、工具、Handoff、Guardrail、Session 与追踪等核心组件。
OpenAI · OpenAI