工具:Agent 的手,以及手的安全规程
这一章讲三件事: 一件工具怎么描述才能被模型用对;一个工具生态(MCP) 怎么既省钱又防毒;一双「手」(执行工具)怎么在不烧掉生产环境的前提下干活。 全章的暗线是同一个矛盾:模型按同步训练,世界按异步运转。
1. 这一章讲什么
第 01 章把工具分成五类,这一章讲「怎么把工具做好」。书里开篇给了两个核心挑战: 工具选择(数千工具怎么不撑爆上下文、不错选)与异步事件(外部世界不会 排队等 Agent 想完)1。前者的答案在描述与生态(3.1-3.4 节),后者的答案在 事件驱动架构(3.6 节),中间夹着本章最重的部分:执行工具的安全(3.5 节)。
2. 顶层全景
模型:「我要调 shell_exec,参数 rm -rf /tmp/data」
│
┌──────▼──── ───────────────────────────────────┐
│ 第 1 层 输入验证:路径合法?参数注入? │
│ 第 2 层 权限控制:工作目录内?黑名单外? │
│ 第 3 层 提议者-审核者:不可逆?另一个模型审 │
│ 第 4 层 Sidecar:执行瞬间,轻量模型门控 │
│ 第 5 层 沙盒:就算执行了,也炸在隔离区里 │
│ 第 6 层 幂等/两段式:万一重复执行,也无害 │
└──────────────────────────────────────────────┘
图说:没有哪一层是万能的;设计假设是「每一层都会漏」。
3. 核心原理
3.1 能力用什么形态表达:专用工具还是 Skill+通用执行器
先于一切粒度讨论,书里摆了一个更基本的选择。专用代码工具:结构化函数调用(模型按固定格式报「函数名+参数」), 行为可复现、可测试,但每个工具占数百 token,数量膨胀还会破坏缓存。
Skill+通用 执行器:用自然语言文档描述操作流程(如「部署应用」:npm run build → docker build → kubectl apply 三步),Agent 用少量通用工具照着执行。三维决策: 参数复杂度(参数有多五花八门)、变更频率、模型能力2。
粒度上,书里给了个数量级判据:工具超过 100 个,即使最先进的模型也会在 选择上出错——所以 extract_pdf/docx/pptx 这类应整合成统一的 read_document, 而 OCR(图片转文字)与视频解析不该合并(参数形态与延迟差异太大)3。通用性上,通用优于 专用,除非有明确的安全、权限或性能理由:code_interpreter 强过十几个专用计算器, 但生产数据库写操作要专用工具的精细权限4。
3.2 描述的艺术:核心是「什么时候用」
工具描述的质量直接决定使用准确性。书里最承重的一句:描述的核心是让模型知道 「什么时候用」,而不只是「能做什么」——「搜索相关内容」远不如「当需要获取 实时信息或查找未知事实时使用」5。
比描述能力更重要的,是列边界——做不到什么、不接受什么。文件搜索工具应 明说「只能按文件名匹配,不能搜文件内容」;缺了反例,模型就会去猜。大多数 调用失败的根因,不是模型不知道工具能做什么,而是不知道它不能做什么6。
其余要点打包:参数用具体例子(「RFC3339 格式,例如 2024-03-15T14:30:00Z」 胜过单写格式名);返回值说明字段;长耗时注明代价(「大型网站可能 5-10 秒; 若只需元信息,改用 get_page_metadata」);附 1-5 个真实调用示例——书里 引用的对照数据是准确率从 72% 提升到 90%,因为 JSON Schema(描述参数类型与取值约束的规范)能说清参数怎么填, 说不清「时间戳是秒还是毫秒」这类调用方式7。调试原则也随之而来:Agent 频繁选错工具,先查描述再怀疑模型——修描述的投入产出比,通常远高于换更强的 模型8。
3.3 主走查:一次静默改写,两个世界失配
事故来自原书引用的 Cursor 2026 年初版本;对话死循环的展开是我们按机制还原的。
工具设计里比功能缺失更隐蔽的反模式:静默输入转换——工具在执行前悄悄 「修正」模型的输入参数9。
模型读到文件:……他说「你好」…… (文件里是中文弯引号)
模型发起编辑:
old_string = 他说「你好」 ← 模型如实传参
(参数传递层悄悄把「 」换成 " ")
工具在文件里找:他说"你好" ← 找不到,文件里没有直引号
工具返回:未找到匹配字符串
│
模型:我明明看到了这段内容,再试一次…… ← 还是弯引号,还是被换,还是找不到
│
死循环
写入方向同样遭殃:模型想写中文弯引号(排版的正确选择),传参层换成直引号; 模型回读验证,看到的是被篡改后的内容——模型陷入「我写的和我看到的不一样、 我以为的世界和真实世界对不上」10。姊妹问题是静默参数注入:某 IDE 的 bash 工具自动给所有 git commit 追加一个标记参数,用户的 Git 版本旧、不认识 它,于是每次提交都失败,而模型完全不知道自己发出的命令被改过11。
书里从这些事故提炼出一条基础原则,值得全文记下:模型感知到的世界与工具操作 的世界之间,不能存在系统性的偏差;确实需要规范化(如统一编码),必须写进 工具描述、并在返回中明确告知12。