Appearance
02. 核心循环与核心组件
版本:
v1.1最后更新:
2026-07-09适用对象:已经理解 Agent 基础边界,准备继续学习 Agent loop、运行时组件、状态管理与工具协作方式的产品、研发、平台工程与技术负责人
1. 先理解控制循环
无论你使用 OpenAI Agents SDK、LangGraph,还是自己写循环,Agent 的底层都可以抽象成一个控制循环。
最常见的版本是:
- 接收目标
- 读取上下文和状态
- 决定下一步动作
- 调用工具或执行节点
- 读取结果
- 更新状态
- 判断是否结束
如果不理解这个循环,学任何框架都容易停留在“会调 API”的层面。
2. 一个通用的 Agent 循环模型
可以记成:
Goal -> Plan -> Act -> Observe -> Update -> Finish
Goal
系统要完成什么目标?
例如:
- 查找问题根因
- 汇总多个来源
- 生成一份报告
- 处理一条工单
Plan
当前最合理的下一步是什么?
它可能只是一个局部决定,而不是完整总计划。
Act
要不要调用工具?
如果要:
- 调哪个工具
- 传什么参数
Observe
工具返回了什么?
这一步最容易被低估,但实际上非常关键,因为后续判断全依赖这里。
Update
当前状态需要怎么变化?
例如:
- 记录已经查过的网站
- 记录失败次数
- 记录已完成步骤
- 更新中间结论
Finish
任务是否已经达到完成条件?
3. Thought-Action-Observation 的本质
很多资料会提到:
ThoughtActionObservation
你不必执着于这个命名,但要理解它的意义:
Thought:系统决定下一步Action:系统实际做动作Observation:系统读取动作结果
即使某个框架不显式展示“Thought”,这个结构通常依然在。
4. Agent 的 7 个核心组件
4.1 模型
模型负责:
- 理解意图
- 选择动作
- 组织工具参数
- 综合工具结果
- 生成最终输出
学习重点:
- 工具调用是否稳定
- 结构化输出是否稳定
- 长上下文能力如何
- 成本和延迟是否可接受
4.2 工具
工具负责让 Agent 能访问外部世界。
常见工具类型:
- 搜索
- 网页读取
- 文件检索
- 数据库查询
- 业务 API
- 代码执行
- 浏览器自动化
学习重点:
- 工具 schema 设计
- 参数质量
- 工具副作用边界
- 错误信息设计
4.3 状态
状态是当前运行中的“任务事实”。
常见状态字段:
- 任务 ID
- 当前轮次
- 已完成步骤
- 已使用工具
- 中间结果
- 错误计数
- 审批状态
学习重点:
- 什么需要进状态
- 什么不能只依赖模型记忆
4.4 记忆
记忆通常分为:
- 短期记忆
- 长期记忆
短期记忆用于当前任务,长期记忆用于跨任务。
学习重点:
- 什么信息适合长期保存
- 什么信息必须每次重新确认
4.5 规划器
规划器负责决定下一步,而不是一定要输出完整计划书。
它可能很轻:
- 要不要搜
- 先搜什么
- 要不要重试
也可能很重:
- 拆任务
- 生成子任务
- 协调多个 specialist
4.6 执行器
执行器是运行时引擎,负责:
- 驱动循环
- 调用工具
- 更新状态
- 记录 trace
- 判断结束
4.7 护栏
护栏负责限制和校验。
典型护栏包括:
- 步数上限
- 成本上限
- 超时
- 工具白名单
- 敏感动作审批
- 输出格式校验
4.8 提示词契约也是核心组件的一部分
很多入门资料会把 Prompt 放在“模型”里一笔带过,但在生产 Agent 里,提示词更像 控制契约。
它至少要说清楚 5 件事:
- 当前目标到底是什么
- 什么时候该调用工具,什么时候不该调用
- 遇到信息不足、工具失败、结果冲突时怎么处理
- 什么条件下可以结束
- 哪些动作必须审批,哪些动作绝对不能做
如果这些规则写不清楚,执行循环就会出现两个常见问题:
- 模型知道“能用工具”,但不知道“何时该用”
- 模型知道“要完成任务”,但不知道“何时可以停”
一个实用判断标准是:
提示词不是为了让 Agent 更会说,而是为了让 Agent 更会决策
根据 OpenAI Prompt guidance 和 Agents 相关指南在 2026-07-07 可访问的说明,更稳的做法通常是把目标、成功标准、工具边界和用户可见前导语分开写,而不是把所有要求混成一大段抽象指令。
根据 Anthropic Tool Use 文档在 2026-07-07 可访问的说明,工具描述本身也属于提示词契约的一部分。工具说明越清楚,模型越容易判断何时调用、传什么参数、失败后如何回退。
4.9 观察归一化与暂停恢复,决定 Agent 能不能跑长任务
很多系统的 loop 不稳定,不是因为“不会规划”,而是因为 Observe 做得太差。
工具返回的原始结果往往很脏:
- 搜索结果太长
- HTML / JSON 字段太杂
- 日志里混着无关噪音
- 多个工具结果格式完全不同
如果执行器把这些原始结果直接塞回下一轮上下文,模型就会越来越难判断重点。
更稳的做法是先做 观察归一化,把工具结果整理成下一轮真正需要消费的字段,例如:
json
{
"status": "success | retryable_error | terminal_error",
"summary": "这一轮工具返回了什么",
"evidence": ["下一轮决策必须看的关键事实"],
"next_options": ["可以继续搜索", "可以请求审批", "可以结束"],
"raw_ref": "原始结果存储位置或 trace id"
}这样做有几个好处:
- 模型看到的是决策所需信息,不是整包噪音
- trace 更容易复盘
- 后续评测可以直接基于结构化观察结果做切片
长任务里还要考虑 暂停与恢复。
现实里的 Agent 经常会停在这些地方:
- 等待人工审批
- 等待异步工具完成
- 超时后等待重试
- 后台任务执行较久,需要稍后恢复
根据 OpenAI Conversation State 文档在 2026-07-07 可访问的说明,持久化状态时不应只保存用户消息,还要保存 messages、tool calls、tool outputs 以及后续恢复执行所需的数据。
所以一个能跑生产任务的执行器,至少要回答清楚:
- 暂停时保存哪些状态字段
- 恢复时哪些内容回放给模型,哪些只保存在应用层
- 工具结果是完整回放,还是压缩成摘要后回放
- 审批通过后从哪一个节点继续,而不是整条链路重跑
4.10 输出契约和结果面,决定 loop 能不能被系统消费
很多 Agent Demo 只关心最后那一句自然语言回答。
但从工程视角看,一个 run 至少会暴露三层不同结果面:
用户可见结果运行时可恢复状态审计与调试记录
根据 OpenAI 当前 Results and state 指南,更值得先建立的心智是:
finalOutput / final_output只是完成态结果interruptions表示 run 被审批或 review 暂停state / to_state()是可序列化的可恢复快照
这意味着:
- 一个 run 即使没有最终答案,也可能是“正确暂停”的
- 没有
final output不一定代表失败,也可能代表正在等待批准 - 真正能恢复执行的,不是用户看的那段总结,而是 runtime state
所以更稳的 Agent 系统通常不会只设计:
- “最后输出什么文字”
而会同时设计:
- 什么时候产出 final answer
- 什么时候只返回 interruptions
- 什么时候只保存 state,等后续恢复
4.11 记忆不是“把对话越存越长”,而是有选择地写回
很多系统会把记忆理解成:
- 只要不断累积 transcript 就行
这往往是错的。
真正麻烦的问题不是“记不记”,而是:
什么值得写回写回到哪一层什么时候必须重新确认
一个更稳的记忆写回策略通常会这样分:
| 信息类型 | 更适合放哪里 | 原因 |
|---|---|---|
| 当前任务步骤、失败次数、等待项 | 运行时状态 | 只对本次 run 有效 |
| 用户稳定偏好、长期角色信息 | 长期记忆 | 跨任务复用价值高 |
| 这次搜索得到的暂时性结论 | 观察结果或中间状态 | 需要后续继续验证 |
| 审批结论、工单号、回滚号 | 可审计持久层 | 后续必须追溯 |
| 猜测、未证实推断 | 不应直接写成长记忆 | 容易污染未来决策 |
一个很实用的判断标准是:
只有未来多次复用且相对稳定的信息,才值得升级成长记忆
否则你很容易得到一个“越跑越自信,但记住了很多错事”的系统。
4.12 并行工具调用不是越多越好,而是要看依赖关系和副作用
当团队开始优化 Agent loop 时,常见想法是:
- 能不能把多个工具并行调掉
这个方向是对的,但前提是先区分:
彼此独立的读操作有顺序依赖的动作带副作用的动作
更稳的判断通常是:
| 情况 | 更适合怎么做 | 原因 |
|---|---|---|
| 多个独立搜索 / 读接口 | 可并行 | 互不依赖,能缩短时延 |
| 第二步依赖第一步输出 | 串行 | 否则参数基础不成立 |
| 写数据库、发消息、改权限 | 优先串行并加审批 | 错误代价高 |
| 需要比较多个候选证据 | 可并行读取,再统一归一化 | 方便模型后续综合 |
一个常见误区是:
- 把所有工具都并行化,当成纯性能优化
但真实后果可能是:
- 产生多份重复证据
- 工具竞争同一资源
- 写动作先后顺序混乱
- trace 和补偿逻辑变复杂
所以 parallelism 不是“让 Agent 更炫”的能力,而是执行器的一项调度责任。
4.13 trace 不是日志堆砌,而是 loop 的可解释骨架
如果一个 Agent 跑错了,你最终需要回答的通常不是:
- “模型为什么突然不聪明了”
而是:
- 它在哪一轮做了哪个决策
- 当时看到了什么证据
- 为什么发生 handoff / guardrail / approval
- 成本和时间消耗在哪一步骤放大了
根据 OpenAI 当前 Integrations and observability 指南,默认 trace 至少会包含:
- overall run / workflow
- model calls
- tool calls 及其 outputs
- handoffs
- guardrails
- custom spans
这说明对生产系统来说,trace 更像:
- 一条可以复盘状态转移的结构化时间线
而不是:
- 一堆随手打印的字符串日志
如果你把 trace 设计成结构化对象,后面很多事情都会容易得多:
- 评测时按步骤切片
- 审核时追责任边界
- 回放时只重演部分 run
- 看清楚成本到底耗在模型、工具还是等待上
5. 一个最小可运行 Agent 长什么样
一个最小 Agent 通常只需要:
- 一个模型
- 一个或几个工具
- 一个循环
- 一个结束条件
例如:
- 用户说“帮我搜索这个主题并总结”
- Agent 调用搜索工具
- Agent 读取结果
- Agent 判断是否还缺信息
- 如果缺,再搜一次
- 不缺则输出总结
这个结构远比“多 Agent 开会”更值得先掌握。
但如果你想把它从 Demo 推到更像生产的第一版,至少还要补一层 最小 runtime skeleton:
run_idgoalstatusstep_countbudgettool_historyobservation_summarypause_reasonresume_state_ref
这层骨架的意义在于:
- 它让 loop 不只是“会继续”
- 而是“继续到什么程度、为什么停、从哪里恢复”都能被系统接住
6. 如何判断 Agent 循环设计得好不好
可以看这 8 个问题:
- 结束条件清不清楚?
- 状态有没有明确边界?
- 工具失败后怎么处理?
- 工具调用次数会不会失控?
- 输出是否可以校验?
- 人工是否能在关键点介入?
- 观察结果是否已经归一化,而不是直接把原始噪音塞回模型?
- trace 是否能还原关键状态转移和成本放大点?
只要其中几个问题没有答案,系统就很容易不稳定。
7. 典型失败点
失败点 1:循环没有明确停止条件
后果:
- 成本失控
- 延迟过高
- 反复调用同一个工具
失败点 2:把所有信息都丢给模型上下文
后果:
- 状态不稳定
- 长任务丢信息
- 历史被污染
失败点 3:工具定义过于模糊
后果:
- 参数乱填
- 选错工具
- 结果难以复用
失败点 4:执行器不记录中间过程
后果:
- 无法调试
- 无法评测
- 无法复盘
失败点 5:把所有中间结论都写成长期记忆
后果:
- 未来任务被错误历史污染
- 未证实推断被当成稳定事实
- 用户越来越难纠正系统
失败点 6:并行执行没分清读写边界
后果:
- 写操作顺序混乱
- 资源竞争放大
- 出问题时很难补偿
8. 从框架角度如何映射这些组件
OpenAI Agents SDK
你会接触到:
- agent definitions
- tools
- results and state
- orchestration
- guardrails
- traces / observability
这些概念都能映射到本章的组件模型。
LangGraph
你会接触到:
- graph
- nodes
- edges
- shared state
- persistence
- interrupts / checkpoints
这些概念更接近“显式控制流 + 显式状态”的表达方式。
9. 学完这一章应该建立的能力
学完本章后,你至少应该能:
- 画出一个 Agent 控制循环图
- 列出一个 Agent 的状态字段
- 为一个具体业务任务写出“结束条件”
- 判断一个工具应该属于读操作还是写操作
- 说清楚“模型、工具、状态、执行器、护栏”分别负责什么
这五点能做到,后面学架构和项目时就不会飘。
10. 一个成熟执行循环还要管理预算,而不只是管理步骤
很多入门循环只写:
- 再想一步
- 再调一次工具
但进入真实环境之后,loop 还必须管理预算,否则很容易出现:
- 步数越来越多
- token 成本越来越高
- 某个工具被反复试错
- 一次任务拖太久还不肯结束
更稳的执行器通常至少要有三类预算:
| 预算类型 | 常见字段 | 作用 |
|---|---|---|
| 步数预算 | max_steps | 防止无意义循环 |
| 成本预算 | max_tokens、max_cost | 防止单任务成本失控 |
| 时间预算 | deadline_at、timeout_ms | 防止长时间占用执行资源 |
根据 OpenAI Running agents 与 Agents SDK 相关资料在 2026-07-07 可访问的说明,运行时并不只是在“帮你多调几次模型”,而是在替应用管理多轮执行、工具调用和结果续接。所以预算本质上不是附属参数,而是 loop 的一部分。
一个非常实用的判断标准是:
- loop 不是“能继续就继续”
- 而是“在预算内证明继续是值得的”
11. turn、run、workflow 不是一回事
很多系统之所以状态越做越乱,是因为把这三层混成了一层:
- 一次模型回合
- 一次 agent run
- 一个完整业务任务
更清楚的分层通常是:
turn
- 单次模型请求与响应
- 可能包含一轮工具请求或工具结果消费
run
- 为完成某个子目标而持续推进的一段 agent 执行
- 可能跨多个 turn
workflow
- 一个更完整的业务流程
- 可能包含多个 run、审批节点、异步等待和人工接管
如果这三层不分开,后面最容易乱在这些地方:
- 到底从哪一层恢复。
- 哪一层记录成本和责任边界。
- 哪一层触发审批或 handoff。
对初学者来说,一个很有帮助的做法是:
- turn 只负责本轮对话与工具往返
- run 负责阶段性目标推进
- workflow 负责端到端业务结果
12. handoff 本质上也是一种状态转移
很多资料会把 handoff 讲成“把任务丢给另一个 agent”,但从工程视角看,它更像一次显式状态转移。
根据 OpenAI Orchestration and handoffs 指南在 2026-07-07 可访问的说明,handoff 的价值并不只是“像团队协作”,而是:
- 把不同职责、工具面和策略边界分开
所以一次 handoff 至少应该回答这些问题:
- 为什么当前 agent 不继续做。
- 下一个 agent 接手后拥有哪些不同能力。
- 传过去的是完整历史,还是压缩后的任务现场。
- handoff 后原 agent 是否还有权继续执行动作。
更稳妥的 handoff 对象通常包括:
| 字段 | 作用 |
|---|---|
handoff_from | 从哪个 agent 转出 |
handoff_to | 转给哪个 agent |
handoff_reason | 为什么转移 |
context_snapshot | 接手所需最小上下文 |
approval_required | 接手后是否触发新的审批边界 |
一旦把 handoff 当成状态转移而不是“会话效果”,很多治理动作都会更清楚:
- trace 更容易读
- 权限更容易切
- 评测更容易判断 handoff 是否合理
13. 推荐继续追问的 6 个问题
如果你已经理解了核心循环,下一步最值得继续追问的是:
- loop 在什么条件下该停,而不是一直想下去。
- 工具失败时,系统是重试、补偿还是转人工。
- 长任务暂停后,哪些状态回放给模型,哪些只保存在应用层。
- 不同 agent、不同工具和不同审批边界,如何在同一条 trace 里串起来。
- 哪些中间结论允许写回长期记忆,哪些只能留在本次 run。
- 哪些工具可以并行,哪些必须串行并加审批。
把这 6 个问题继续想透,你就会从“理解 Agent 是什么”,真正进入“理解 Agent 为什么能稳定跑”。
14. 重点官方资源
以下资源已按 2026-07-09 复核到当前正式入口;其中部分 OpenAI 页面对脚本访问会返回 403,但浏览器入口仍可正常打开:
- OpenAI Agents SDK:https://developers.openai.com/api/docs/guides/agents
- OpenAI Running agents:https://developers.openai.com/api/docs/guides/agents/running-agents
- OpenAI Results and state:https://developers.openai.com/api/docs/guides/agents/results
- OpenAI Conversation state:https://developers.openai.com/api/docs/guides/conversation-state
- OpenAI Orchestration and handoffs:https://developers.openai.com/api/docs/guides/agents/orchestration
- OpenAI Guardrails and human review:https://developers.openai.com/api/docs/guides/agents/guardrails-approvals
- OpenAI Integrations and observability:https://developers.openai.com/api/docs/guides/agents/integrations-observability
- OpenAI Evaluate agent workflows:https://developers.openai.com/api/docs/guides/agents/evals
- OpenAI Function calling:https://developers.openai.com/api/docs/guides/function-calling
- OpenAI Using tools:https://developers.openai.com/api/docs/guides/tools
- LangGraph Workflows and agents:https://docs.langchain.com/oss/python/langgraph/workflows-agents
- LangGraph Persistence:https://docs.langchain.com/oss/python/langgraph/persistence
- LangGraph Interrupts:https://docs.langchain.com/oss/python/langgraph/interrupts
- Anthropic Building Effective Agents:https://www.anthropic.com/engineering/building-effective-agents
- Anthropic Writing effective tools for AI agents:https://www.anthropic.com/engineering/writing-tools-for-agents