前置知识: AI Agent

工具接口 — Agent为何需要结构化I/O

17 minIntermediate

理解Agent工具调用的四步循环:描述、决策、执行、观察,以及纯工具与后果工具的安全区分

工具接口 — Agent为何需要结构化I/O

语言模型产生token。程序执行动作。两者之间的鸿沟就是工具接口:一个让模型请求动作、宿主执行动作的契约。2026年的每一个技术栈 — OpenAI、Anthropic和Gemini上的函数调用;MCP的 tools/call;A2A的任务部件 — 都是同一个四步循环的不同编码。本课命名这个循环,并展示运行它所需的最小机制。

类型: 学习 语言: Python(标准库,无LLM) 前置条件: Phase 11(LLM completion API) 时间: ~45分钟

学习目标

  • 解释为什么只能生成文本的LLM无法自行对真实世界采取行动。
  • 绘制四步工具调用循环(describe → decide → execute → observe)并命名每一步的负责人。
  • 将工具描述写成三部分:名称、JSON Schema输入和确定性执行器函数。
  • 区分纯工具和有副作用的工具,并说明这种区分对安全的重要性。

问题所在

LLM输出的是下一个token的概率分布。这就是其全部输出面。如果你问聊天模型”班加罗尔现在的天气如何”,它可以写出一个看似合理的句子,但无法拨入天气API。这个句子可能碰巧正确,也可能已经过时三天。

弥合这一鸿沟就是工具接口的目的。宿主程序 — 你的Agent运行时、Claude Desktop、ChatGPT、Cursor或自定义脚本 — 向模型通告可调用工具列表。模型在决定需要执行动作时,发出一个结构化负载,命名工具及其参数。宿主解析该负载,真正运行工具,并将结果反馈回去。循环持续,直到模型决定不再需要调用。

该契约的第一个版本于2023年6月作为OpenAI的”functions”参数发布。Anthropic在Claude 2.1中跟随推出了 tool_use 块。Gemini几个月后添加了 functionDeclarations。现在每个提供商都暴露相同的形状:JSON Schema类型的工具列表输入,JSON负载的工具调用输出。Model Context Protocol(2024年11月)将该契约泛化,使一个工具注册表服务于每个模型。A2A(2026年4月,v1.0)为Agent间委托叠加了相同原语。

四步循环是所有这些之下的不变量。Phase 13的其余内容都是对此的扩展。

核心概念

第一步:描述

宿主用三个字段声明每个工具。

  • 名称。 稳定的、机器可读的标识符。get_weather,而不是”天气那个东西”。
  • 描述。 一段自然语言简述。“当用户询问特定城市的当前状况时使用。不要用于历史数据。”
  • 输入模式。 描述工具参数的JSON Schema对象(draft 2020-12)。

模型接收该列表。现代提供商使用特定于提供商的模板将这些声明序列化到系统提示中,因此作为调用者,你只需处理结构化形式。

第二步:决策

给定用户消息和可用工具,模型选择三种行为之一。

  1. 直接以文本回答。 无工具调用。
  2. 调用一个或多个工具。 发出结构化调用对象。在 parallel_tool_calls: true(OpenAI和Gemini默认开启,Anthropic需选择启用)下,模型可以在一个轮次中发出多个调用。
  3. 拒绝。 严格模式的结构化输出可以产生型化的 refusal 块而不是调用。

工具调用负载有三个稳定字段:调用 id、工具 name 和JSON arguments 对象。id的存在是为了让宿主可以将后续结果与特定调用关联,这在并行调用乱序返回时很重要。

第三步:执行

宿主接收调用,根据声明的模式验证参数,并运行执行器。无效参数意味着模型幻觉了一个字段或使用了错误的型 — 这是弱模型上非常常见的失败模式。生产宿主对无效参数做三件事之一:快速失败并将错误呈现给模型,用约束解析器修复JSON,或重试模型并在提示中包含验证错误。

执行器本身是普通代码。Python、TypeScript、shell命令、数据库查询。它产生一个结果,通常是字符串,但也可以是任何JSON值或结构化内容块(MCP中的文本、像或资源引用)。结果必须是可序列化的。

第四步:观察

宿主将工具结果附加到对话中(作为带有匹配 idtool 角色消息)并重新调用模型。模型现在在上下文中有了工具输出,可以产生最终答案或请求更多调用。这持续到模型停止发出调用或宿主达到迭代计数的安全限制。

信任分割

工具分为两种对安全有意义的型。

  • 纯工具。 只读、确定性、无副作用。get_weathersearch_docsget_current_time。可以安全地投机调用。
  • 后果工具。 改变状态、花费金钱、接触用户数据。send_emaildelete_fileexecute_trade。必须设门控。

Meta 2026年的Agent安全”二规则”说,单个轮次最多只能组合以下三者中的两个:不可信输入、敏感数据、后果动作。工具接口是你执行该规则的地方 — 通过拒绝调用、要求用户确认或升级作用域。详见Phase 13 · 15的完整安全章节和Phase 14 · 09的Agent级权限策略。

循环所在位置

上下文谁描述谁决策谁执行
单轮函数调用(OpenAI/Anthropic/Gemini)应用开发者LLM应用开发者
MCPMCP服务器LLM通过MCP客户端MCP服务器
A2AAgent Card发布者调用Agent被调用Agent
Web浏览器(函数调用Agent)浏览器扩展/WebMCPLLM浏览器运行时

到处都是相同的四步。列名改变;结构不变。

为什么不直接提示模型输出JSON?

“让模型以JSON回复”是函数调用之前的模式。它在前沿模型上大约5%到15%的时间失败,在更小的模型上失败率更高。失败模式包括缺少大括号、尾随逗号、幻觉字段和错误型。然后你需要JSON修复过程、重试或约束解码器。

原生函数调用更好的原因有三。首先,提供商在确切的调用形状上端到端训练模型,因此在严格模式下有效JSON率攀升到98%到99%。其次,调用负载位于其自己的协议槽中,不在自由文本内 — 因此工具调用永远不会泄漏到用户可见的回复中。第三,提供商通过约束解码强制模式合规(OpenAI的严格模式、Anthropic的 tool_use、Gemini的 responseSchema)。输出保证通过验证。

Phase 13 · 02并行对比三个提供商API。Phase 13 · 04深入结构化输出。

熔断器

当模型停止发出调用或宿主达到最大轮次计数时,循环终止。生产宿主将其设置为5到20轮之间。超过这个数字,你几乎肯定处于模型无法退出的循环中。Claude Code默认为20;OpenAI Assistants为10;Cursor的Agent模式为25。

替代方案 — 无界循环 — 每六个月就会出现一次”Agent一夜之间花了400美元API调用”的事后分析。不要在没有上限的情况下发布。

Phase 14 · 12深入介绍错误恢复和自愈;Phase 17涵盖生产速率限制。

Phase 13接下来去哪里

  • 第02到05课完善提供商级工具调用表面。
  • 第06到14课将循环泛化到MCP。
  • 第15到18课防御循环免受恶意服务器、对抗用户和未认证远程认证表面的攻击。
  • 第19到22课将模式扩展到Agent间协作、可观测性、路由和打包。
  • 第23课使用每个原语发布完整生态系统。

剩余的每一课都是这个四步循环的扩展。把它记为不变量。

实践

code/main.py 在没有LLM的情况下运行四步循环。一个假的”决策器”函数通过模式匹配用户消息来模拟模型;执行器、模式验证器和观察步骤线束都是真实的。运行它以查看完整的请求/响应编排和可打印的中间状态,然后在后续课程中将假决策器替换为任何真正的提供商。

关注点:

  • 工具注册表每个工具持有三个字段:名称、描述、模式和执行器引用
  • 验证器是一个最小的JSON Schema子集(型、必需、枚举、最小/最大),仅用标准库编写。Phase 13 · 04提供了更完整的版本。
  • 循环将迭代计数限制为5。生产Agent正是需要这种熔断器。

交付

本课产生 outputs/skill-tool-interface-reviewer.md。给定一个草稿工具定义(名称 + 描述 + 模式 + 执行器大纲),该技能审计其循环适配性:名称是否机器稳定,描述是否完整的使用简述,模式是否正确使用JSON Schema 2020-12,纯工具与后果工具的分是否明确。

练习

  1. code/main.py 中添加第四个工具 get_stock_price(ticker)。将其描述写为”当用户通过股票代码询问当前股价时使用。不要用于历史价格或市场摘要。“运行线束并确认假决策器将提及股票代码的查询路由到新工具。

  2. 破坏模式验证器。传递一个 arguments 对象缺少必需字段的调用,并确认宿主在执行前拒绝它。然后传递一个包含额外未知字段的调用。决定:宿主应该拒绝还是忽略?用安全论证来证明你的选择。

  3. 将线束中的每个工具分为纯工具或后果工具。在需要它的注册表条目中添加 consequential: true 标志,并更改循环,使其在选择后果工具时打印”将向用户确认”行。这就是每个生产宿主所需的确认门的形状。

  4. 在纸上绘制四步循环,填写上面提供商列表表格中你最喜欢的客户端(Claude Desktop、Cursor、ChatGPT或自定义栈)。与Phase 13 · 06中MCP特定变体交叉参考。

  5. 从头到尾阅读OpenAI的函数调用指南。识别一个存在于请求中但不在本文所述四步循环中的字段。解释它添加了什么以及为什么它方便而非必要。

关键术语

术语人们怎么说实际含义
Tool”模型可以调用的东西”名称 + JSON Schema类型输入 + 执行器函数的三元组
Function calling”原生工具使用”提供商级API支持,用于发出结构化工具调用而非散文
Tool call”模型的行动请求”模型发出的带有 idnamearguments 的JSON负载
Tool result”工具返回了什么”执行器的输出,包装在带有匹配id的 tool 角色消息中
Parallel tool calls”一次多个调用”一个模型轮次中的多个调用对象,独立且可按id排序
Strict mode”保证JSON”约束解码,强制模型输出通过声明的模式验证
Pure tool”只读工具”无副作用;安全重跑
Consequential tool”动作工具”改变外部状态;需要门控、审计或用户确认
Four-step loop”工具调用循环”describe → decide → execute → observe
Host”Agent运行时”持有工具注册表、调用模型并运行执行器的程序

延伸阅读