第 4 章《工具》学习总结

一、本章核心结论
- **工具应面向 Agent 的目标设计,而不是机械地将每个底层 API 端点包装成工具。**这种设计观被称为 ACI(Agent-Computer Interface)。
- 默认优先通用工具,但安全、权限、审计、复杂参数和平台差异会使专用工具更合适。
- **"能力做成什么形态"与"一次向模型披露多少能力"是两个独立决策。**专用工具、通用执行器和 Skill 解决形态问题;分层组织、按需加载和主动发现解决披露规模问题。
- 工具描述的重点是"什么时候用"和"什么不能做",不只是功能介绍。
- **参数传递必须保真。**工具不能在模型不知情时静默修改、规范化或注入参数。
- 感知工具的核心是控制输出量并明确信息完整性;执行工具的核心是分层安全、可验证和可审计;协作工具的核心是明确交接边界和生命周期。
- 只读工具可以缓存和并行;会改变世界的工具则必须考虑顺序、幂等、超时、取消和副作用。
- **第三方 MCP 和 Skill 都会扩大信任边界。**工具描述、代码、版本和凭证都必须被当成供应链安全问题审视。
二、整体知识框架
text
Agent 能力设计
├─ 能力形态:专用工具 / 通用执行器 / Skill
├─ 能力分发:MCP / Skill Hub
├─ 能力披露:全量 / 分层 / 检索预筛 / 主动发现
├─ 工具接口:描述 / Schema / 示例 / 返回值 / 成本
└─ 运行时治理:权限 / 审批 / 沙箱 / 验证 / 审计 / 取消
本章的五类工具:
| 工具类型 | 谁发起 | 作用对象 | 设计重点 |
|---|---|---|---|
| 感知工具 | Agent 主动调用 | 获取信息 | 输出量、分页、截断、压缩、多模态 |
| 执行工具 | Agent 主动调用 | 改变外部世界 | 验证、权限、审批、沙箱、幂等、审计 |
| 协作工具 | Agent 主动调用 | 其他 Agent 或人类 | 任务交接、消息、取消、发现、超时 |
| 用户沟通工具 | Agent 主动调用 | 向用户传递信息 | 多渠道、异步通知、结构化消息 |
| 事件触发工具 | Agent 注册、外部触发 | 驱动 Agent 开始执行 | 定时、监控、回调和异步运行时 |
本章详细展开前三类主动调用工具;用户沟通和事件触发将在事件驱动架构中继续讨论。
三、ACI:为 Agent 而不是为 API 设计工具
ACI 类似人机交互中的 HCI,关心的是 Agent 如何有效、稳定、安全地使用计算机能力。
一个不理想的方案会将每个 API 端点都包装成微型工具,迫使 Agent 自行协调大量底层操作。更好的工具应:
- 与 Agent 希望完成的目标对齐。
- 屏蔽不必要的平台和底层实现差异。
- 给出足够的返回信息,让 Agent 能判断下一步。
- 在安全、参数和错误边界上比底层 API 更清晰。
四、专用工具、通用执行器与 Skill
1. 三种形态
| 形态 | 特点 | 优势 | 代价 |
|---|---|---|---|
| 专用工具 | 通过结构化 schema 定义固定能力 | 确定性高、参数可校验、易审计和限权 | 工具数量和上下文成本高,扩展需开发部署 |
| 通用执行器 | Shell、Python、代码解释器等元能力 | 少量工具覆盖大量任务,可用代码串联步骤 | 安全面更大,需要沙箱与强约束 |
| Skill | 用自然语言文档描述流程,按需加载 | 人类易编辑、变更成本低、常驻 token 少 | 依赖模型理解和 CLI 参数生成,复杂转义易出错 |
2. 默认原则
在没有明确的安全、权限、审计或性能理由时,优先通用工具和 Skill。
例如,与其为每种数学计算定义工具,不如提供带 NumPy、Pandas 和 SymPy 的沙箱 Python 解释器。这既减少工具数量,又能处理开发者未预见的边界问题。
专用工具的粒度也应偏向整合。如果 PDF、DOCX 和 PPTX 提取工具都是"文件路径输入、文本输出",更好的形态是一个 read_document 工具加 file_type 参数。
3. 何时应使用专用工具
- 安全、权限和审计:例如生产数据库写入需要细粒度授权和审计记录。
- 屏蔽平台差异:例如用专用文件搜索工具统一 Windows、macOS 和 Linux 差异。
- 使用频率极高:高频操作值得有一个低成本、高可见性的独立入口。
- 参数结构复杂:嵌套对象、多字段联合校验和复杂类型适合 JSON Schema。
4. 决策四维度
| 维度 | 更倾向专用工具 | 更倾向 Skill + 通用执行器 |
|---|---|---|
| 安全与权限 | 高风险、不可逆、需强审计 | 低风险、可恢复、权限边界简单 |
| 参数复杂度 | 嵌套、强类型、联合约束 | 简单 CLI 参数或可通过 JSON 文件传入 |
| 变更频率 | 稳定底层能力 | 流程和业务规则频繁变化 |
| 模型能力 | 弱模型需要强 schema 引导 | 强模型能理解流程并生成命令 |
5. 用代码编排多步工具
通用执行器允许模型一次性生成脚本,将多个调用的中间结果保留在执行环境变量中,只将最终汇总结果返回上下文。
这样可以:
- 减少多轮"调用---结果---再调用"往返。
- 避免整页网页、大型表格等中间数据反复进入模型上下文。
- 用循环、分支和异常处理稳定地表达程序化工作流。
但脚本仍必须在受控环境中执行,不能因为减少 token 就绕过安全策略。
五、高质量工具描述怎么写
好的工具描述至少要回答以下问题:
- **什么时候调用?**例如"需要实时信息或模型不知道的事实时使用"。
- **什么时候不应调用?**列出反例、越界场景和不接受的输入。
- **参数是什么?**说明语义、单位、必填条件、范围和相互约束。
- **具体格式是什么?**在 RFC3339、E.164 等术语之后给出可直接模仿的实例。
- **返回什么?**列出字段、错误形态、分页信息和完整性标记。
- **成本如何?**说明耗时、配额、资源代价和更便宜的替代工具。
- **典型调用怎么写?**提供 1--5 个真实的参数组合示例。
一条重要的调试原则是:Agent 频繁选错工具时,首先检查描述、边界和示例,不要立即归因于模型太弱。
章中提到,加入具体工具调用示例后,某些基准的调用准确率可从约 72% 提升到 90%,但实际增益依任务而定。
六、参数传递保真性
工具看到的输入、实际执行的操作和模型认为已执行的操作必须一致。
常见反模式包括:
- 将中文弯引号静默转成英文直引号,导致精确文本匹配失败。
- 在写文件时静默改写模型提供的字符,使文件内容偏离原意。
- 向 Git 或 Shell 命令静默追加额外参数,导致旧版工具报错。
- 只在写入工具做转换,读取工具不做转换,制造模型无法理解的感知偏差。
如果确实需要编码归一化或补全默认参数:
- 必须在工具描述中预先说明。
- 必须在工具返回中报告转换前后的差异。
- 不应对可能改变语义的内容做"智能修正"。
- 无法校验的输入应快速失败,而不是悄悄猜测用户意图。
七、MCP 与 Skill Hub
1. MCP 解决什么
Model Context Protocol 用客户端---服务器架构统一 Agent 与外部工具和数据源的接入方式。
其三类核心原语是:
| 原语 | 含义 |
|---|---|
| Tools | 模型可调用的操作 |
| Resources | 客户端可浏览和读取的数据 |
| Prompts | 由服务器提供、供用户或客户端选用的提示模板 |
MCP 使用 JSON Schema 统一工具参数描述,本地运行可用 stdio,远程服务可用 Streamable HTTP。其核心生态价值是"一次开发,多个兼容客户端使用"。
2. Skill Hub 解决什么
Skill 本质上是包含 SKILL.md、脚本和资源文件的文件夹,因此不需要运行时协议,而是通过注册表或包管理生态进行分发。
与 MCP 工具相比:
- MCP 连接后,工具 schema 可能进入每次会话的上下文。
- Skill 安装后,常驻内容通常只有
name和description,完整内容按需读取。 - Skill 的上下文成本通常更低,但可执行代码使其安全风险可能更高。
3. 第三方能力的风险
- 描述投毒:恶意指令可隐藏在 description 中,以每次会话都生效的方式进行提示注入。
- 供应链攻击:可信服务器、Skill 或其依赖的后续版本可能被篡改。
- 同名工具遮蔽:恶意工具可以伪装成可信工具,窃取调用中的敏感参数。
- 凭证泄露:工具被赋予的账号权限可能超出其真实所需。
- 本地代码执行:Skill 可含本地脚本或运行时下载代码,危险性高于纯远程工具描述。
防护措施:审查描述与代码、锁定版本、升级后重新审查、为每个服务使用最小权限凭证,并在隔离环境中运行不可信 Skill。
八、工具过多时的管理方法
工具超过上百个时,全量平铺会同时破坏三件事:
- 占用大量上下文 token。
- 增加模型选错工具的概率。
- 工具集任何改变都可能破坏 KV/Prompt Cache 前缀。
可采用三层渐进方案。
1. 分层组织与按需加载
启动时只向模型提供名称或类别索引,需要时再读取完整 schema。可按信息源性质将感知工具分为:
- 搜索:主动发现位置和候选。
- 读取:从已知位置获取内容。
- 解析:处理图片、音视频和文档等非结构化数据。
- 查询:访问天气、股价和数据库等结构化数据源。
实验数据显示,将 MCP 工具改为索引常驻、定义按需加载,总 token 消耗可下降 46.9%。
2. 检索式预筛选
根据当前查询的语义相似度,先从大量工具中选出一小批候选,再注入它们的完整定义。本章引用的实验中,按需检索将工具基准准确率从 49% 提升到 74%。
局限是它往往只根据用户最初的查询做一次匹配,无法预知多步任务中后续才出现的能力缺口。
3. 模型主动工具发现
在系统提示词中只保留少数核心工具和一个工具搜索元工具。Agent 执行过程中发现能力缺口时,用自然语言描述所需能力,系统再动态匹配工具。
高效匹配可分为两层:
text
自然语言能力需求
→ 先匹配服务器或工具组
→ 再在组内匹配具体工具
→ 返回少量候选 schema
当相似度低于阈值时,系统应返回"未找到",让 Agent 改写需求、用基础工具自行实现或请求人类。
4. 动态加载与 KV Cache
新工具的完整 schema 应在首次发现时追加到轨迹末尾,之后固定在当时的位置,不应每轮搬动、重排或重新加载。
这使稳定前缀继续命中缓存,新 schema 也会成为后续请求可复用的历史前缀。只有 TTL 过期,或者修改、删除、重排已加载工具时,才需要从变动点重建缓存。
5. Skills 式工具发现
Skills 将工具发现变成"查阅参考资料":
- 启动时只看
name和description目录。 - 需要时读取完整
SKILL.md。 - 再根据任务按需读子文档、脚本和模板。
相比专用工具的嵌入索引、检索元工具和动态 schema 注入,Skills 的基础设施更轻,但它更依赖模型能否正确理解文档和命令。
九、感知工具设计
1. 基本原则
感知工具的突出问题是输出远大于 Agent 的可用上下文。一次搜索、一份 PDF 或一个目录遍历都可能返回大量噪声。
应采用:
- 上下文感知压缩:超过阈值时,根据 Agent 当前查询意图生成定向摘要。
- 候选列表优先:搜索先返回标题、位置和摘要,再由 Agent 选择深读对象。
- 分页或游标:默认只返回少量结果,附带总数和下一页读取方式。
offset/limit:允许 Agent 按范围读取大文件。- 显式截断:说明显示范围、数据总量、省略量和如何继续读取。
**静默截断是严重缺陷。**Agent 会错误地认为自己已看到全部内容,并对不完整数据做出自信判断。
2. 只读性的工程优势
- 相同查询的结果可以安全缓存。
- 多个相互独立的搜索或读取可以并行执行。
- 失败通常不会留下外部副作用,因此重试逻辑相对简单。
但只读不等于无风险:私有数据读取仍需权限控制,外部文档仍可能携带间接提示注入。
十、多模态感知的三条路径
| 方式 | 优势 | 局限 | 适用场景 |
|---|---|---|---|
| 原生多模态 | 保留布局、图表、图像和空间关系,端到端能力最强 | 多模态 token 成本高,依赖支持视觉/音频的主模型 | UI、复杂表格、设计稿、图表联合理解 |
| 提取为文本 | 对文字为主的 PDF 成本低、效率高 | 丢失排版、图像和空间对应关系 | 纯文本文档、语音转录、普通 OCR |
| 工具化多模态分析 | 主 Agent 只保留问题和精简结论,可按需做深入分析 | 端到端综合理解弱于原生多模态 | 主模型不支持多模态或需控制成本的交互场景 |
选择原则:文本为主则优先提取;布局和视觉关系重要则保留图像;主模型不支持多模态时,将对原始文件的针对性问答封装成工具。
十一、执行工具的分层安全
执行工具可能删除文件、中断服务、改写数据、发送消息或产生财务损失。因此不应将安全寄托在单一规则上。
1. 第一层:输入验证
- 检查路径遍历、命令注入、数据类型和格式错误。
- 检查参数之间的业务约束。
- 发现异常后快速失败,不做不透明的自动修正。
2. 第二层:权限和资源约束
- 文件系统限定可读写根目录。
- 外部 API 使用最小权限凭证、配额和速率限制。
- Shell 执行结合禁止模式、语义审查和沙箱,不能只依赖字符串黑名单。
- 限制 CPU、内存、磁盘、网络和运行时间。
3. 第三层:提议者---审核者
对不可逆和高影响操作,引入第二个独立视角。
事前审批:
- Proposer 提议操作,Reviewer 根据相同底层规则和约束审查。
- 两个模型应能力相近、来自不同家族,以增加认知多样性。
- Reviewer 关注风险与规则,Proposer 关注任务完成。
- 审批失败时,将拒绝原因作为工具失败结果返回主 Agent,供其修正方案。
事后验证:
- 不只让另一个模型重读同一输出,而要切换验证模态。
- 代码修改后运行测试或 linter;文档生成后渲染为图像检查布局;配置修改后在沙箱中真实启动验证。
4. Sidecar:单次工具调用的实时门控
Sidecar 是与主 Agent 并行运行的轻量审查模型,它在每次工具执行前对结构化调用做风险分类。
核心设计:
- 只读取
{tool, command, parameters}等结构化字段,不读主模型的自由文本思考。 - 这种输入隔离减少了攻击者用提示注入干扰审查结果的机会。
- 安全分类问题相对封闭,因此可用轻量模型;开放式方案审查则需能力相近的强模型。
- 被审查操作在 Sidecar 放行前不能真正执行。
- 连续拒绝需触发熔断,转向人工判断,不允许 Agent 无限尝试绕过。
5. 两种第二视角的区别
| 维度 | 提议者---审核者 | Sidecar |
|---|---|---|
| 时机 | 操作前审批或操作后验证 | 与主模型流式输出并行,门控单次调用 |
| 对象 | 行动的合理性或最终结果 | 结构化工具调用本身 |
| 模型要求 | 开放式审查,需能力相近的模型 | 闭集分类,轻量模型即可 |
| 输入 | 提案、规则、相关上下文或不同模态结果 | 刻意与主模型自由文本隔离 |
| 用途 | 转账、发信、配置修改、结果质量验收 | 命令风险分类、权限判定、调用门控 |
十二、执行后的验证、输出和隔离
1. 执行---验证---反馈闭环
任何可验证的操作都应尽可能自动验证:
text
执行变更
→ 运行 linter / 测试 / 启动检查 / 渲染验收
→ 将结构化错误和建议返回 Agent
→ Agent 修正后再次验证
工具不应只返回"写入成功",而应返回可用于下一轮修正的行号、错误类型和检查结果。
2. 长输出截断与持久化
长输出应采用"头尾摘要 + 原文落盘":
- 保留开头若干行,展示初始上下文。
- 保留末尾若干行,展示最终错误或成功标志。
- 明确标注中间省略量。
- 将完整输出写入临时文件,并告知 Agent 如何读取。
3. 沙箱层级
| 层级 | 特点 | 适用场景 |
|---|---|---|
| 进程级 | 与本地用户共享文件、网络和进程权限 | 可信输入下的本地开发 |
| 容器 | 独立文件系统和网络栈,但与宿主共享内核 | 生产任务、中等风险代码 |
| microVM / VM | 独立内核和硬件级隔离 | 完全不可信的代码或高风险多租户任务 |
**Python venv 不是沙箱。**它只隔离包依赖,不会限制文件系统、网络、进程或系统调用。
4. 可观测性
每次执行应记录:
- 发起时间、工具名称、参数、结果和耗时。
- 发起者、用户、会话、权限与决策理由。
- 成功率、失败率、超时率、资源使用和拒绝率。
- 频繁失败、异常高频调用、超时和资源超限告警。
十三、幂等、超时与取消语义
执行工具必须明确回答:一次调用超时或被取消时,副作用究竟有没有发生?
网络超时后的转账请求可能已经成功。如果 Agent 将"没收到成功响应"误解为"没有执行",盲目重试就会重复转账。
常见解法:
- 幂等键:为一次业务操作生成唯一 ID,服务端对重复请求返回首次结果,而不是再次执行。
- 先查询后变更:重试前先查询订单、资源或文件的当前状态。
- 预检---确认两段式:对发邮件、打电话、转账等天然不幂等操作,先检查内容、对象和条件,再执行一次。
- 失败不自动重试高风险非幂等操作:返回详细状态,让主 Agent 查询和重新规划。
十四、协作工具
1. 子 Agent 的价值
- 并行处理相互独立的子任务。
- 为不同领域选择不同模型、系统提示词、工具和知识库。
- 隔离会产生大量中间噪声的探索任务,只把结论返回主 Agent。
- 用专业化分工代替一个提示词和工具集无限膨胀的"全能 Agent"。
2. 子 Agent 提示词要素
- 角色清晰:明确说明它专门负责什么。
- 来源标记 :区分
[FROM_MAIN_AGENT]、[FROM_USER]和[TOOL_RESULT]。 - 边界明确:说明哪些在职责范围内,哪些应转交、求助或上报。
- 输出标准化:约定 JSON 或 Markdown 字段,降低主 Agent 的解析和整合负担。
- 任务自包含:子 Agent 看不到全部主上下文,交接内容必须包含目标、限制、已知信息和验收标准。
3. 协作工具原语
| 类别 | 典型原语 |
|---|---|
| 启动与取消 | spawn_subagent、cancel_subagent |
| 消息传递 | send_message_to_subagent 及子 Agent 反向汇报 |
| 发现 | list_agents 返回职责和运行状态 |
| 结果获取 | get_subagent_status 或异步完成事件 |
基于这些原语可实现同步调用、异步任务、流式协作和多轮交互。任务不再需要时应及时取消,避免无意义的 token 和计算消耗。
4. 人在回路(HITL)
人工介入适合:
- 需要人类价值判断、审美选择或专业责任的决策。
- 高风险、不可逆或模型缺乏关键信息的操作。
- 多轮自动审查仍无法收敛的情况。
设计时要包含:
- 超时阈值和保守的默认行为。
- 按风险和时效性排序的优先级队列。
- 紧急任务的多渠道通知。
- 批准、拒绝及其理由的反馈记录。
- 将可归纳的反馈沉淀为知识、Skill 或后训练数据的学习回路。
十五、生产系统检查清单
能力形态与披露
- 每项能力均根据安全、参数、变更频率和模型能力选择形态。
- 可由通用执行器安全完成的任务,没有无意义地拆成大量微型工具。
- 高风险或复杂参数操作被封装为可限权、可审计的专用工具。
- 工具数量较大时使用分层索引、按需加载或主动发现。
- 动态加载的 schema 只在首次出现时追加,后续不搬动和重排。
工具接口
- 描述说明何时用、何时不用,并给出反例。
- 参数描述包含单位、范围、格式和真实示例。
- 返回值、错误格式、执行代价和完整性明确。
- 工具不会静默改写、规范化或注入参数。
- 需要的规范化处理有描述、有返回报告、可审计。
感知工具
- 搜索默认返回结构化候选,而不是全文倾倒。
- 大结果支持分页、游标、
offset和limit。 - 截断、省略和读取后续内容的方式被明确标注。
- 与当前任务无关的超长输出会在工具层定向压缩。
- 只读调用优先使用缓存和并发。
执行工具
- 输入验证、权限控制、安全审查和沙箱不是单点防御。
- 高风险操作进行事前审批,可验证结果进行事后验收。
- Sidecar 只读结构化调用信息,不被主模型的自由文本理由影响。
- 写文件、改配置和生成代码后自动执行验证。
- 长输出保留头尾摘要,完整结果持久化并可按需读取。
- 明确超时、取消和副作用状态,高风险操作不盲目重试。
- 可幂等操作使用唯一幂等键,非幂等操作使用预检---确认流程。
- 所有执行调用有完整日志、审计链、性能指标和异常告警。
供应链与协作
- 第三方 MCP 和 Skill 的描述、代码和依赖经过审查。
- 版本被锁定,升级会重新审查,凭证符合最小权限。
- 子 Agent 任务自包含,明确来源、边界、输出格式和验收标准。
- 子 Agent 支持消息、状态、取消和超时,不需要的任务会被及时停止。
- HITL 有超时默认、优先级、多渠道通知和反馈沉淀机制。
十六、一句话心法
好工具不是让 Agent "什么都能调",而是让它在需要时看到恰当的能力,使用忠实且可理解的参数完成目标,并让每个副作用都受限、可验证、可审计。