从一次 API 调用到完整 Agent Loop:上下文到底如何流动

从一次 API 调用到完整 Agent Loop:上下文到底如何流动

摘要

Agent Loop 常被简化成"模型返回工具调用就执行,否则结束"的 while True。这个 Demo 能解释主干,却省略了生产最关键的部分:供应商消息协议并不相同,工具调用与结果必须正确关联,最终文本不一定代表任务完成,错误需要分类恢复,循环还要受轮次、时间、token 和费用约束。本文从消息角色差异出发,建立供应商无关的内部事件模型,再给出包含校验、观测、恢复与安全停止的 Loop 状态机。

关键词

上下文工程、消息角色、工具调用、Agent Loop、调用轨迹、终止条件、max iterations、错误恢复

CSDN 分类建议:人工智能 / 大模型应用

推荐标签:AI Agent、LLM、智能体、大模型、Agent Engineering

本文知识地图

我们先拆"消息是什么",再看一次工具调用怎样往返,最后把这个往返放进状态机。两张图分别回答:谁产生什么消息,以及循环在什么时候继续、恢复、完成或安全停止。

图 1:Agent 工具调用消息时序。来源:作者依据 OpenAI 与 Anthropic 官方工具调用文档整理。

读图重点是 call_42:模型输出的调用请求、执行器结果和下一轮上下文必须保持关联。由图可得的工程结论是,工具结果不能作为一段无来源普通文本塞回模型;否则并行调用、重试和审计都可能串线。

先纠正"消息有四种角色"

源稿以 OpenAI Chat Completions 风格说明 systemuserassistanttool 四种角色。这对理解特定接口有用,却不是跨供应商标准。

Anthropic Messages API 的官方参考明确说明:系统提示通过顶层 system 参数提供,常规输入消息可用 userassistant,并不存在把系统提示作为输入消息 role: "system" 的通用做法。事实;Anthropic Messages API 工具调用则出现在内容块里:模型返回 tool_use,应用执行客户端工具,再用 tool_result 回传。事实;Handle Tool Calls

OpenAI Chat Completions、Responses API 和 Agents SDK 又有各自的消息或 Item 结构。工程结论不是发明一个"万能 role",而是在应用内部规范化少量语义事件,再由适配器转换:

text 复制代码
Instruction     开发者/系统约束
UserInput       用户或外部事件
ModelOutput     文本、结构化输出或调用请求
ToolCall        call_id + tool + args
ToolResult      call_id + result/error
StateUpdate     任务进度、预算、环境状态

这样业务状态机不依赖某家字段名。适配器负责遵守供应商的顺序、内容块、签名或调用 ID 规则;日志层保存规范化事件与原始响应引用。

上下文不是"消息列表"这么简单

不论状态存在哪里,模型在某个决策点实际可见的内容仍是关键。Anthropic 把上下文描述为采样时包含的 token 集合,并强调它有限且需要策展。事实;Effective Context Engineering 生产系统还要保存模型看不见但 Harness 必须知道的控制状态,例如租户、授权票据、幂等键、剩余预算和审计元数据。这些不应全塞进 prompt。

因此建议分成三层:

  1. 模型上下文:模型决策需要的最小信息;
  2. 运行状态:循环、预算、权限、取消信号、幂等和恢复点;
  3. 审计记录:原始请求响应、策略判定、版本和环境证据。

一次工具调用怎样完整往返

以客户端工具为例,通用时序是:

  1. Harness 组装当前模型上下文和工具定义;
  2. 模型返回文本、工具调用,或两者按协议允许的组合;
  3. Harness 解析调用,验证 Schema、业务语义、权限和预算;
  4. 执行器在受控环境运行工具,记录耗时与副作用;
  5. 将结果或错误与原调用 ID 关联,追加到下一轮上下文;
  6. 模型依据新观测给出最终输出或继续调用。

Anthropic 官方工具文档区分客户端与服务端工具:客户端工具由应用执行,服务端工具由 Anthropic 基础设施执行。事实;Tool Use Overview 所以"模型不执行工具"只对客户端工具这一层成立,文章和代码应写清执行位置。

OpenAI Function Calling 的 Structured Outputs 在 strict: true 时可保证参数匹配所给 JSON Schema。事实;OpenAI Function Calling 但 Harness 仍必须验证:订单属于当前用户吗?金额在余额内吗?此动作需要确认吗?工具参数结构正确不等于动作安全。

并行调用的关联规则

模型可能一次请求多个无依赖工具。执行器可并行运行,但结果返回顺序可能不同。不要按数组位置猜对应关系,应以调用 ID 关联。上下文适配器还要遵守供应商对调用与结果相邻、顺序和内容块的要求。

工具输出不要无限回灌

网页、日志或数据库结果可能非常大,也可能包含提示注入。工具层先做长度限制、结构化提取、来源标记和敏感信息处理;原始结果保存到外部制品存储,给模型的是任务所需摘要与可追溯引用。摘要是有损的,涉及证据核验时允许模型按需读取原文片段。

核心循环:从 while 变成状态机

图 2:Agent Loop 状态机。来源:作者依据 OpenAI Agents SDK 生命周期与生产错误处理模式整理。

读图重点是两个出口:完成与安全停止。由图可得的工程结论是,"模型没有返回工具调用"最多表示一个最终输出候选,不能自动证明外部任务完成;相反,预算耗尽时即使任务未完成,也必须退出并报告可恢复状态。

OpenAI Agents SDK 的官方运行文档说明,Runner 会在模型输出最终结果时结束,在产生工具调用时执行并追加结果后重跑;超过 max_turns 会抛出 MaxTurnsExceeded事实;Running Agents 这验证了轮次上限是当前生产 SDK 的一等概念,但具体默认值与异常类型属于 SDK,实现自己的 Loop 时不能照搬字段名。

供应商无关的伪代码可以写成:

python 复制代码
state = load_or_create_run()
while True:
    enforce_deadline_budget_and_max_turns(state)
    response = model(generate_context(state), available_tools(state))
    events = adapter.normalize(response)

    if events.final_candidate:
        verdict = verify_completion(events.final_candidate, state)
        if verdict.accepted:
            return finalize(verdict, state)
        state.observe(verdict.as_error())

    for call in events.tool_calls:
        verdict = policy.validate(call, state)
        result = executor.run(call) if verdict.allowed else verdict.as_error()
        state.observe(link(call.id, result))

伪代码省略了并发、流式、取消和持久化,却保留五个硬点:每轮检查预算;供应商响应先规范化;最终输出独立验证;调用先过策略;成功与错误都成为观测。

终止条件应该是组合条件

只用 if not tool_calls: break 会产生两类错误:模型过早给出文本,或用文本询问澄清却被当作完成。生产 Loop 常组合以下条件:

  • 完成信号 :模型返回指定结构、调用 submit_result,或工作流到达终态;
  • 环境验证:文件存在且测试通过、交易状态已提交、引用可访问;
  • 用户交互:需要澄清或审批时进入暂停,而非完成;
  • 安全停止 :达到 max_turns、deadline、token、金额或调用预算;
  • 不可恢复错误:权限永久拒绝、资源不存在且无替代路径、策略禁止。

完成信号是候选,环境验证才决定能否交付。安全停止要返回当前状态、已发生副作用、未完成事项和恢复标识,方便之后续跑。

max iterations 不是随手填一个数字

轮次上限过低会截断正常任务,过高会放大循环成本和风险。工程经验是从任务族统计分布出发:记录成功任务所需轮数、长尾失败和每轮成本,为不同工具风险设置差异化预算。例如只读检索可以给更多轮,高风险写操作不仅轮次更低,还应限制每类工具次数。

除了总轮次,还要检测"无进展循环":同一工具与同一参数重复、错误签名重复、状态哈希不变、计划反复切换。检测到后可注入明确观测、切换策略、请求用户信息或停止。不要让模型自己数历史调用次数;Harness 应用代码维护计数。

错误恢复:先分类,再决定动作

错误类别 例子 合理动作
瞬时基础设施 429、短暂超时、连接重置 指数退避、抖动、遵守 Retry-After
参数/格式 Schema 失败、枚举值错误 把精确错误送回模型,限制纠参次数
业务拒绝 余额不足、状态不允许 不盲目重试,换方案或询问用户
权限/策略 越权、缺审批、高风险禁止 停止执行,走授权或人工路径
部分成功 邮件已发但数据库更新失败 查幂等状态,补偿或人工处置
模型协议 调用 ID 丢失、内容块非法 适配器拒绝,保存原始响应并回退

恢复必须知道副作用是否已经发生。超时不等于失败:支付请求可能服务端已成功,只是客户端没收到响应。执行器应使用幂等键并先查询状态,避免重复执行。

上下文增长与恢复点

长 Loop 不应只存在进程内存。每轮完成后持久化规范化事件、预算、工具副作用和可恢复游标。恢复时重建供应商上下文,但不要把所有审计字段喂给模型。对非常长的轨迹,使用结构化状态、压缩摘要与按需制品引用;第四、五篇会继续讨论缓存、压缩和隔离。

常见误区与修正

误区一:所有厂商都有四种相同角色。 修正:按官方规范实现适配器;Anthropic Messages 的系统提示在顶层,工具用内容块表达。

误区二:每次 API 调用都绝对无状态。 修正:客户端全量历史是一种方式;当前接口也可续接服务端 response、conversation 或 session 状态,权衡可编辑性与治理。

误区三:无工具调用就是完成。 修正:它只是最终输出候选;结合结构、环境证据和业务终态验证。

误区四:工具错误直接变普通文本。 修正:保留调用 ID、错误类型、是否可重试和副作用状态。

误区五:max_iterations=10 能解决循环。 修正:还要有时间、费用、工具次数和无进展检测,并按任务族校准。

生产检查清单

  • 每家模型接口有独立适配器和契约测试,不假设角色相同。
  • 内部事件区分指令、用户输入、模型输出、调用、结果和状态更新。
  • 并行工具调用以 call_id 关联,不依赖返回顺序。
  • 工具输出限制长度、标记来源、脱敏并保留原始制品引用。
  • 最终输出经过结构、业务和环境证据验证。
  • Loop 同时限制轮次、时间、token、费用和高风险工具次数。
  • 检测重复参数、重复错误和状态无进展。
  • 瞬时、业务、权限、部分成功和协议错误采用不同恢复策略。
  • 工具有超时、取消、幂等键与副作用查询接口。
  • 每轮持久化恢复点;停止时报告已完成、未完成和已发生副作用。

本文小结

Agent Loop 的本质不是一个 while,而是一套消息协议适配、运行状态、策略校验、工具执行、环境观测和终止判定。供应商 API 的角色与内容块并不通用,应用应规范化语义事件并保留原始关联。最终文本只是完成候选;环境证据、硬预算和错误分类共同决定循环是交付、继续、暂停、恢复还是安全停止。下一篇将深入循环的推理成本:Chat Template、KV Cache、跨请求 Prompt Cache 与前缀稳定性。

延伸阅读与参考资料

官方 API 与 SDK 文档

  1. Create a Message,Anthropic Messages API。(V1-R015)
  2. Tool use overview,Anthropic。(V1-R003)
  3. Handle tool calls,Anthropic。(V1-R017)
  4. Running agents,OpenAI Agents SDK。(V1-R018)
  5. Function Calling in the OpenAI API,OpenAI。(V1-R004)

官方工程文章

  1. Effective context engineering for AI agents,Anthropic。(V1-R005)

系列导航

相关推荐
Misnearch1 小时前
mcp-server
llm·jenkins·mcp
uncle_ll2 小时前
深入探索 Hugging Face核心组件及实践
llm·nlp·bert·huggingface·hf-mirror·hf
CoovallyAIHub3 小时前
当制造业遇上 AI 智能体:Coco 把工艺知识留在了工厂里
llm·agent
拾年2753 小时前
从"AI写代码我喝咖啡"到 Harness Engineering:Vibe Coding 不翻车的工程化生存指南
llm
CoderJia程序员甲4 小时前
GitHub 热榜项目 - 周榜(2026-07-26)
ai·大模型·llm·github·ai教程
武子康4 小时前
生产环境的模型路由不是一次难度分类:从硬约束可行域到状态检查点升级
人工智能·llm·agent
寒水馨7 小时前
Linux下载、安装 Codex CLI(附安装包codex-x86_64-unknown-linux-musl.tar.gz)
linux·openai·终端·ai编程·codex·智能体·codex cli
大龄码农有梦想7 小时前
企业如何利用 AI 大模型提升业务效率?企业 AI 应用应该从哪些场景切入
人工智能·ai agent·ai智能体·ai应用·ai工作流·ai赋能·智能体平台
To_OC15 小时前
啃完流式输出:从一个卡顿的 LLM 接口开始,我搞懂了数据流到底怎么 “流”
前端·javascript·llm