Skip to content

工具调用

这一组文章把语言模型和外部世界连接起来:先理解工具描述,再掌握循环和协议。

文章重点
Function Calling:工具的定义与触发工具 schema、触发决策和参数生成
工具调用循环(Tool Loop)—— Agent 的心跳调用、执行、回传和继续
MCP(Model Context Protocol)用标准协议接入外部工具

文章学习清单

清单集中放在这里,练习时仍可回到对应文章查看上下文。每个问题后面都给出验收时应达到的程度,不只检查“代码能跑”。

Function Calling:工具的定义与触发

  • 定义一个工具,故意把 description 写得含糊,观察模型是否乱调或漏调

    • 参考答案:准备“应该调用”“不应该调用”和“边界模糊”三类问题,记录模型是否调用、选了哪个工具以及参数。含糊描述通常让模型分不清触发条件、能力边界和参数含义,可能在本该直接回答时调用,也可能在需要实时数据时漏调。最后要能指出是用途、触发条件还是限制描述缺失导致错误,并确认服务端没有因误调用执行危险操作。
  • 把同一工具的 description 写清楚,对比触发准确率

    • 参考答案:清晰描述应包含能力、触发时机、返回内容、适用范围、不可处理的情况和参数示例。保持模型、系统提示、工具集合和测试集不变,统计调用准确率、参数完整率、无效调用率以及新增描述的 token 成本;触发率变高不等于所有问题都该强制调用。
  • 给字段加上 enum,再引导模型传一个范围外的值

    • 参考答案enum 会给模型明确的合法值提示,但不能替代服务端校验。分别测试合法值、大小写变化、自然语言别名、越界值和缺失值,区分 Schema 不合法、业务不允许和权限不足三类失败;执行层应在真正调用前拦截非法参数。
  • 打印模型返回的 tool_calls,确认 arguments 是字符串并处理一轮多个调用

    • 参考答案:每个调用通常包含唯一 id、工具名和 JSON 字符串形式的 arguments,需要先解析再做 Schema 与业务校验。一轮可能有多个互不依赖的调用,结果必须按各自 tool_call_id 回传。验收应覆盖合法/非法 JSON、缺字段、未知工具和两个并行调用,确保不会串结果。
  • tool_choice 强制调用某个工具,观察行为变化

    • 参考答案none 禁止调用,auto 交给模型决定,required 要求至少调用一个,指定函数则固定目标。强制调用不代表用户提供了合法参数,模型可能编造缺失信息。实验要为每种模式找到合理场景,并在执行前加参数校验、权限检查和必要的用户追问,说明固定流程与无关强制调用的风险。

工具调用循环(Tool Loop)

  • 不用框架,纯 SDK 写通一次完整循环

    • 参考答案:程序应跑通“用户问题 → tool call → 本地执行 → 追加 tool 结果 → 模型总结”,模型直接回答时也能正常退出。保留 assistant 工具调用消息、tool_call_id、原始参数和每轮 usage;用只读工具与失败工具覆盖正常结束、非法参数、未知工具和 API 错误,并设置最大轮数、超时和总预算。
  • 让模型完成一个需要连续调用两个工具的任务

    • 参考答案:设计“先查订单,再用订单号查物流”这种有依赖的任务,trace 中应能看出第二步使用了第一步结果。说明为什么第二个调用不能提前执行,并记录每轮延迟、输入/输出 token、工具耗时和最终结果;结果缺失时应停止或追问,不能编造。无依赖的两个工具可能在同一轮并行,不能把两个工具误认为两个循环。
  • 打印每轮 messages,观察它如何增长

    • 参考答案:每轮会追加 assistant 消息和一个或多个 tool 消息,历史重发会推高输入 token、延迟和成本。日志需脱敏,并记录角色、调用 id、摘要、token 数和 trace id;验收时要能还原链路,并提出摘要、裁剪旧消息、压缩结果或外置状态的方案,同时保留仍会影响决策的约束和工具结果。
  • 用本地 mock 工具诱导死循环,理解终止条件

    • 参考答案:让工具持续返回相同或无效结果,观察模型重复调用导致费用和延迟失控。实验只用本地 mock、极小预算和短超时;恢复保护后至少有最大轮数、总 token/费用预算、单工具超时、重复调用检测和取消机制,达到限制时返回可解释的失败状态并保存 trace。
  • 处理工具执行报错,把错误回传给模型并验证自我纠正

    • 参考答案:网络超时、参数校验失败、业务拒绝应转换成结构化结果,说明错误类型、是否可重试和需要补充什么;不能把堆栈、密钥或内部路径暴露给模型或用户。至少区分可重试、不可重试、需人工确认和权限不足,验证不会重复执行非幂等操作,最终回答如实说明工具是否成功。

MCP(Model Context Protocol)

  • 说清 2026-07-28 为何取消 initialize 握手,以及如何兼容 legacy Server

    • 参考答案:现代 MCP 是无协议级 session 的逐请求模型,每个请求通过 _meta 自描述,HTTP 另带 MCP-Protocol-Version;服务端不支持版本时返回版本错误,客户端选择支持版本重试。兼容旧 Server 时,STDIO 可先探测 server/discover,HTTP 可检查 400 响应体,只有确认 legacy 才回退 initializenotifications/initialized
  • 写出 server/discover 请求和 DiscoverResult 的关键字段

    • 参考答案:请求方法为 server/discover,业务参数为空但带标准 _meta;结果至少检查 resultType: "complete"supportedVersionscapabilities,通常还包含 serverInfoinstructionsttlMscacheScopeserverInfo 只是服务端自报身份,不能作为安全决策依据。
  • 区分 Tools、Resources、Prompts 的驱动方和安全入口

    • 参考答案:Tools 由模型提出调用,但 Host 负责确认、参数校验、鉴权、超时和审计;Resources 由 Host/用户选择读取,重点防 URI 越权和数据传播;Prompts 由用户主动选择,重点检查模板来源、参数和 prompt injection。三者都可能承载不可信文本,不能直接当系统指令。
  • 解释 tools/call 的协议错误与工具执行错误

    • 参考答案:未知方法、未知工具和参数结构非法属于 JSON-RPC error;工具已找到但下游 API、业务校验或执行失败,应返回正常 result 并设置 isError: true,让模型得到可行动反馈。Host 仍要限制重试次数和副作用。
  • 说清 resultTypestructuredContentoutputSchema 的关系

    • 参考答案:现代结果使用 resultType,普通完成为 complete,需要客户端补充输入为 input_requiredoutputSchema 描述结构化结果,Server 必须让 structuredContent 符合它,Client 应验证;这不是模型供应商的 Structured Outputs。为兼容旧 Client,最好同时返回可读的 TextContent。
  • 描述 MRTR 往返以及 requestState 安全要求

    • 参考答案:Server 在工具、资源或提示词结果中返回 InputRequiredResultinputRequests 携带 elicitation、sampling 或 roots 请求;Client 完成输入后用新的 JSON-RPC id 重试原方法并带 inputResponsesrequestState 必须原样回显,Server 应做完整性保护、绑定用户和原请求、设置 TTL 并防重放。
  • 对比 resources/subscribesubscriptions/listen

    • 参考答案:旧版通过 resources/subscribe/unsubscribe(HTTP 还可能有独立 GET SSE);2026-07-28 用 subscriptions/listen 建立长生命周期响应流,由 Client 选择资源或列表变更类型,Server 用订阅 id 关联推送。请求级 progress/log 仍在原请求响应流中。
  • 说清 Streamable HTTP 与 HTTP+SSE 的差异和部署安全点

    • 参考答案:当前 Streamable HTTP 使用单一 POST endpoint,每个请求独立 POST,响应可为 JSON 或该请求范围内的 SSE;没有独立 GET 流、Mcp-Session-IdLast-Event-ID 和独立 Server Request。必须校验 Origin、认证、协议版本及 Mcp-* 头体一致性,本地只监听 localhost;HTTP+SSE 已弃用。
  • 解释 MCP 授权发现链路和 token passthrough 风险

    • 参考答案:受保护 Server 发布 RFC 9728 Protected Resource Metadata,Client 由此发现授权服务器;授权服务器至少支持 RFC 8414 或 OIDC Discovery,Client 使用 OAuth 2.1、PKCE、state 和严格重定向校验。Client 凭据按 issuer 隔离,MCP Server 不能把 Client token 原样转发给第三方 API,下游凭据应由 Server 独立 OAuth 流程取得并绑定用户。
  • 对比 form mode 与 URL mode elicitation,列出禁止事项

    • 参考答案:form mode 只适合可查看、可修改的非敏感结构化输入,禁止密码、API Key、访问令牌和支付凭据;URL mode 让用户在 Server 安全页面处理敏感信息,URL 不能放秘密、PII 或预认证链接。Client 要展示 Server 和完整 URL、征得同意、禁止预取或让 LLM 读取页面,并处理取消、拒绝和身份绑定。
  • 设计一个无协议 session 的有状态工具

    • 参考答案:创建工具生成高熵 opaque handle,在 structuredContent 返回;后续工具把 handle 当普通参数,每次根据认证主体校验,设置 TTL、权限和一次性约束。过期返回 isError: true 的可行动错误,不能依赖 HTTP 连接或 Mcp-Session-Id 保存状态,也不能把 handle 当成无需鉴权的 bearer token。
  • 判断什么时候用 MCP、什么时候用本地 function 或 A2A

    • 参考答案:能力需要跨多个 Host/Agent/IDE 复用、统一发现和权限边界、或由独立团队维护时,MCP 更合适;单应用内稳定小函数、极低延迟路径可直接写 function;需要委派自治 Agent、持续任务、产物和状态时考虑 A2A。三者都不能替代授权、幂等、数据最小化和审计。

持续学习,持续实践。