跳到主要内容

内容阅读

Agent阿新聊ai

Tool Calling 深入

本文迁移自 mindcarver/91ai · 原始位置 docs/agent/ai app tutorials/agent workflow/tool calling deep dive.md · 由 @阿新聊ai 整理。 Tool Calling 深入 TL;DR: Tool Calling 把模型的语言推理能力...

本文迁移自 mindcarver/91ai · 原始位置 docs/agent/ai-app-tutorials/agent-workflow/tool-calling-deep-dive.md · 由 @阿新聊ai 整理。

Tool Calling 深入

TL;DR: Tool Calling 把模型的语言推理能力连接到外部系统的确定性能力。2025 年的关键变化是 MCP(Model Context Protocol)把工具调用从"硬编码"转向"动态发现"。工具设计的关键是 Schema 质量——名称、描述、参数、返回值都要像 API 一样严谨。安全边界在工具执行层,不在 Prompt 里。

Tool Calling 的本质

Tool Calling 的本质是:把模型的语言推理能力,连接到外部系统的确定性能力。

模型擅长理解意图、归纳信息、判断下一步;工具擅长查询数据、执行计算、读写文件、调用 API。Tool Calling 把两者接起来:模型决定什么时候用工具、用哪个、传什么参数;系统负责真正执行工具,把结果返回给模型。

这带来两层风险:

  • 选择风险:模型可能选错工具。本该查内部知识库,却去搜互联网。
  • 执行风险:工具产生真实副作用。写文件、发邮件、更新数据库、删除记录。

所以设计 Tool Calling 时,不该只关心"模型能不能调用成功",还要关心"它有没有权调用、参数是否合理、结果能否验证、调用是否可审计"。

Tool Schema:工具和模型之间的契约

一个完整 Schema 包括四部分。

name:工具名称

短、明确、可区分。用"动词_名词"格式:search_webquery_customer_profilecalculate_roi

不要用 tool_1helperprocess 这种含糊名字。

description:工具描述

这是模型选择工具时最重要的信息。好的描述要说清三件事:做什么、适合什么场景、不适合什么场景

差的描述:

搜索工具。

好的描述:

根据关键词搜索公开网页,返回标题、摘要、链接和来源。
适用于获取公开资料、最新资讯和行业动态。
不适用于查询企业内部文档、用户私有数据或需要登录的网站内容。

Anthropic 把工具接口设计称为 ACI(Agent-Computer Interface),提出一个检验标准:一个不熟悉系统的实习生能不能仅凭描述正确使用这个工具? 如果不能,描述就不够好。

parameters:输入参数

参数要用结构化格式定义类型、是否必填、取值范围和格式要求。

参数设计的关键原则:

  • 语义明确querytext 清楚,start_datedate1 清楚
  • 格式明确:日期必须是 YYYY-MM-DD 就写清楚,不要指望模型自动猜
  • 范围明确max_results 只能是 1 到 10 就在 Schema 和工具实现里都限制
  • 来源明确user_idsession_idtenant_id 由系统填充,不让模型猜

模型负责语义参数,系统负责身份、权限和环境参数。

returns:输出格式

返回结构要稳定。不要这次返回字符串,下次返回数组。模型需要依赖稳定结构继续推理。

工具选择:为什么模型会选错

模型选择工具主要依赖两个信息:工具描述和当前任务上下文。

描述含糊 → 模型靠名字猜;上下文混乱 → 模型理解错任务。于是出现"莫名其妙"的工具调用。

三种方法提高稳定性:

减少候选工具。 不要把所有工具暴露给所有 Agent。行业研究 Agent 不需要发邮件工具。Anthropic 建议单次上下文工具数量 < 20 个——超过后模型选择准确率明显下降。

让工具职责互斥。 search_infofind_data 都能搜索资料,模型就难选。

在描述里写负例。 "不适用于……"比正面描述更能帮模型排除错误选项。

大规模工具集策略

工具数量 策略
< 20 全部加载
20-100 分类/路由先筛选
100+ MCP 动态发现或 tool_search 延迟加载

OpenAI 的 tool_search(gpt-5.4+)让模型按需搜索工具集,不需要全部加载到上下文。Anthropic 的 MCP 通过 tools/listtools/call 实现类似能力。

结果返回

工具结果是给模型继续推理用的,不是给人看的。

结构稳定。 返回字段固定,类型固定,错误格式固定。

信息够用。 搜索结果不仅要有标题,还要有摘要、链接、来源和时间。

信息不过量。 不要一次返回几百条结果。工具应该先裁剪、排序、摘要,把最相关的返回。

错误返回尤其重要。不要只返回"失败":

{
  "success": false,
  "error_code": "RATE_LIMIT",
  "message": "Search API rate limit exceeded.",
  "retryable": true,
  "retry_after_seconds": 60
}

这样模型才能判断是等待、重试、换工具还是交给人处理。

工具权限:Prompt 不是安全边界

Tool Calling 一旦连接真实系统,就必须有权限控制。不要把权限控制写在 Prompt 里。Prompt 可以提醒模型,但不能作为安全边界。

权限控制至少三层:

工具白名单。 每个 Agent 只能看到和调用自己需要的工具。看不到的工具就不会被模型选择。

参数限制。 工具执行前校验参数。查询数据库时表名只能来自允许列表;发邮件时收件人域名必须符合规则;文件写入路径必须限制在工作目录内。

操作审批。 高风险工具需要人工确认。

实用分级:

级别 类型 示例 审批要求
L0 无副作用查询 读取公开资料 自动执行
L1 读取内部资料 查询知识库 自动执行(带日志)
L2 生成草稿 创建邮件草稿 用户确认
L3 写入业务系统 更新 CRM 审批
L4 不可逆动作 付款、删除、外发 多人审批

MCP 的安全注解可以辅助自动化这个分级:

注解 含义 自动策略
readOnlyHint 只读,无副作用 自动允许
destructiveHint 破坏性操作 强制人工确认
idempotentHint 幂等操作 可自动重试
openWorldHint 访问外部网络 需要网络策略审批

MCP:工具调用的范式转变

MCP(Model Context Protocol)由 Anthropic 于 2024 年 11 月发布,2025 年成为开放标准。它改变了工具调用的三个根本问题:

从硬编码到动态发现。 不再需要在代码里预注册所有工具。Agent 运行时通过 tools/list 发现可用工具,通过 tools/call 调用。

从封闭到开放标准。 任何 MCP 服务器都可以提供工具,任何 MCP 客户端都可以消费。工具生态从"自己写"变成"即插即用"。

从应用到协议的安全边界。 MCP 注解让安全策略可以在协议层自动执行,而不是每个应用自己实现。

OpenAI 已通过 MCP Connector 支持接入 MCP 服务器,两大阵营在工具协议上趋于统一。

MCP 的安全风险

MCP 也带来了新攻击面:

  • 工具注入:恶意 MCP 服务器提供带注入指令的工具描述
  • 工具伪装:伪造高权限工具诱骗模型调用
  • 数据泄露:工具返回值中嵌入窃取 prompt 的指令

缓解措施:只安装可信来源的 MCP 服务器,审计工具代码,使用 annotations 做自动安全策略。

并行工具调用与 tool_choice

OpenAI 默认 parallel_tool_calls=true,模型可以一次返回多个工具调用。适用于独立信息查询;不适用于有依赖的操作(如先创建再关联)。

tool_choice 精细控制:

模式 行为 适用场景
auto 模型自行决定 通用对话
required 必须调用至少一个工具 强制工具使用
none 禁止工具调用 纯文本回复
指定函数名 强制调用特定工具 路由到确定工具

审计:每次调用都要留痕

生产环境里,每次工具调用都应该留下记录:

  • 调用时间
  • Agent 或任务 ID
  • 工具名称
  • 参数摘要
  • 执行结果
  • 错误信息
  • 耗时
  • 调用前后的状态版本

审计日志有两个价值:调试(追溯异常行为的根因)和合规(回答"谁在什么时候让系统做了什么"。

日志也要注意安全。参数里可能包含敏感信息,需要脱敏、权限控制和保留期限。

Tool Calling 与 Agent 的关系

Tool Calling 解决"模型怎么动手"。Agent 解决"模型为什么动手、何时动手、动手后怎么判断"。

一次工具调用只是一个动作。Agent 是围绕目标持续运行的循环:多次选择工具、观察结果、更新状态、决定下一步。

不要把 Tool Calling 设计成一堆孤立 API。要把它放进完整执行循环里:工具结果如何进入状态?失败如何影响下一步?高风险工具如何审批?调用日志如何支持复盘?

常见失败模式

失败模式 根因 修复
工具描述太泛 模型不知何时用、何时不该用 写清适用和不适用场景
工具职责重叠 多个工具都能做同一件事 合并或严格区分
参数过度开放 模型能传任意路径、SQL、收件人 参数白名单和校验
错误信息不可行动 只返回"error" 包含可行动建议
结果过大 原始数据塞回上下文 裁剪、排序、摘要
缺少审计 出问题无法追踪 每次调用留痕

工具设计检查清单

  • 名称是否能清楚表达动作和对象?
  • 描述是否写清适用和不适用场景?
  • 参数是否都是必要的?
  • 参数类型、格式、范围是否明确?
  • 身份、权限、租户信息是否由系统填充?
  • 返回结构是否稳定?
  • 错误信息是否包含可行动建议?
  • 工具有副作用?是否需要审批?
  • 是否记录了调用日志?
  • 是否限制了返回数据量?

Tool Calling 做得好,Agent 才能可靠地接触外部世界;Tool Calling 做得差,Agent 越"自主",风险越大。

延伸阅读

评论

0
登录后可以参与评论和讨论。
💬

还没有评论

欢迎留下第一条评论,帮助这篇内容更快形成讨论。