很多 AI 应用看起来像“聊天窗口”,但一旦需要查询实时信息、读写业务数据或执行外部操作,单次模型调用就不够用了。系统必须在模型、工具和上下文之间反复传递结果,并决定下一步继续做什么。
这套运行机制通常被称为 Agent Loop。它不是某个框架专属的 API,而是智能体应用的基础控制流:模型提出行动,程序执行行动,把结果作为新的观察信息交回模型,直到任务完成或触发保护性终止条件。
Agent Loop 解决的是什么问题
普通问答应用的流程通常只有一次模型请求:准备提示词、调用模型、返回文本。这样的模式适合总结、改写和知识问答,却无法可靠完成“先查天气,再计算预算,最后给出建议”这类多步骤任务。
Agent 则把一次请求拆成一连串可观察的步骤:
用户请求 → 模型判断 → 选择工具 → 程序执行 → 返回结果 → 模型继续判断其中,模型负责理解目标并提出下一步行动;应用程序负责校验工具、检查参数、执行真实操作和控制权限。两者职责分开,才能避免把数据库写入、文件操作或外部 API 调用完全交给模型自行决定。
一个最小 Agent 通常包含以下部分:
- 模型调用器:向大模型提交上下文、工具定义和当前任务。
- 工具集合:天气查询、数据库读取、计算、文件处理等可执行能力。
- Tool Registry:根据模型返回的工具名称找到实际函数,并管理工具元数据。
- 上下文或会话记录:保存用户消息、工具调用和工具结果。
- 运行控制器:负责循环、异常处理、超时、重试和结束判断。
从 Tool 定义到可执行的循环
工具不能只靠自然语言描述。程序需要显式声明工具名称、用途和参数结构,再由运行时完成注册。例如天气工具可以要求 city 参数必须是字符串;计算工具则可以要求输入两个数字。模型可以选择工具,但不能凭空创造一个没有实现的工具。
伪代码可以写成这样:
messages = [user_message]
steps = 0
while steps < MAX_STEPS:
response = call_model(messages, tools=tool_schemas)
if not response.tool_calls:
return response.text
for call in response.tool_calls:
tool = registry.get(call.name)
if tool is None:
result = {"error": "unknown tool"}
else:
result = execute_with_timeout(tool, call.arguments)
messages.append(call.as_message())
messages.append(tool_result_message(call.id, result))
steps += 1
raise AgentTimeout("maximum steps exceeded")这里最关键的不是 while 语句本身,而是工具结果必须重新进入上下文。工具返回的内容只是中间事实,不一定是最终答案。模型只有看到这些 Observation,才能判断是否还要调用下一个工具,或者已经具备生成结论所需的信息。
因此,Agent 的核心闭环可以概括为:
Model → Action → Observation → Model如果执行结果只返回给用户、不交还给模型,循环就会在第一次工具调用后断开,系统也无法完成多步任务。
生产环境不能只相信模型会停止
教学示例中,模型不再请求工具时就可以结束。但上线后的 Agent 还要防止异常循环、重复写入和高额调用。至少应设置以下保护措施:
- 最大步数:限制单次任务能够执行的循环次数。
- 超时控制:限制模型请求和工具执行的最长时间。
- 重试上限:区分可恢复的临时失败与不可重试的业务错误。
- 权限校验:在执行高风险操作前验证用户身份、资源范围和动作类型。
- 人工确认:删除数据、发起付款、发送外部消息等动作可以要求二次确认。
- 幂等设计:避免模型重复调用导致重复扣款、重复写入或重复提交。
工具失败时,也不一定要立即结束任务。可以把结构化错误作为 Observation 交回模型,让它改用备用工具、修正参数或向用户说明缺少条件。但错误信息不能成为无限重试的理由,仍需由重试次数、总耗时和最大步数共同兜底。
日志与可观测性要记录执行链
普通接口记录请求和响应还不够。一次 Agent 请求可能包含多个模型步骤和工具调用,排查问题时需要知道:模型当时看到了什么、选择了哪个工具、传入了哪些参数、工具实际返回了什么,以及哪一步触发了终止。
建议至少记录以下字段:
- 请求与会话标识;
- Agent、模型和提示词版本;
- 当前 Step、工具名称及参数摘要;
- 执行耗时、状态和错误类型;
- 工具结果的脱敏摘要;
- 权限检查、人工确认和策略命中记录;
- 最终结束原因,例如正常完成、超时或达到步数上限。
对于包含客户数据、访问令牌或内部文档的系统,日志还需要脱敏和分级访问。完整记录执行链的目的不是保存更多文本,而是让团队能够区分“模型选错了工具”“参数生成错误”“工具本身失败”与“模型误读工具结果”。
从最小循环走向 Agent Runtime
当应用开始支持会话恢复、任务取消、分支执行、权限范围、沙箱、持久化和链路追踪时,简单的消息数组会逐渐演变为 Session Log,工具字典也会演变为带有权限和生命周期管理的 Tool Registry,while 循环则会成为完整的 Agent Runtime。
这也是使用 Agent 框架时值得追问的几个问题:
- 当前上下文保存在哪里,如何恢复和回放?
- 工具由谁注册,调用前后有哪些校验?
- 工具结果如何写回下一轮模型上下文?
- 任务由什么条件结束,异常和取消如何处理?
- 高风险操作是否有权限、审批和审计机制?
理解这些边界,比记住某个框架的调用方式更有迁移价值。无论应用部署在云服务器、容器平台还是托管运行环境,Agent 的基础执行模型都不会因此改变;变化主要发生在持久化、网络隔离、弹性扩缩容和运维观测等工程部分。
适合从哪里开始实现
如果目标是学习或验证方案,可以先选择两个低风险工具,例如天气查询和四则计算,完成以下最小闭环:模型判断是否需要工具、程序校验工具名和参数、执行结果回写上下文、模型生成最终答复。随后再补充最大步数、超时和错误处理。
不要一开始就把知识库、多智能体、复杂记忆和所有业务接口都塞进示例。先把“上下文—工具—观察—再次决策”跑通,再逐项增加权限、持久化和可观测能力,系统边界会更容易验证。
Agent 首先是一种运行机制,其次才是某个框架中的对象。模型提供理解和决策能力,工具提供外部动作,上下文保存状态,而 Agent Loop 负责把这些部分连接起来。把这个闭环理解清楚,后续再选择具体的 Agent 框架或云上部署方式,会更容易判断它究竟替你封装了哪些工作。