第 7 章:工具(Tools)、批准与程序化调用(PTC)
1. 本章定位
工具是模型意图通往真实副作用的安全边界;新版以程序化工具调用(Programmatic Tool Calling,PTC)统一批量/程序化调度,不再沿用旧版 Code Mode 叙述。
2. 学习目标
- 编写带输入/输出 Schema 的工具。
- 区分 allow、deny、ask 与 Guard。
- 追踪 prepare、dispatch、finalize 三阶段。
- 解释 PTC、后台任务和 UI 展示元数据。
3. 前置知识
可把 Tool Registry 类比命令总线,把 pre/execute/post 类比中间件。局限是这里还要处理模型 Schema、权限批准、并发、取消、durable result 与跨进程 UI 合同。
4. 对应源码
packages/core/tools/src/index.ts:210:presentationMeta。packages/core/tools/src/index.ts:261:并发声明。packages/core/tools/src/index.ts:780:ToolRuntime。packages/core/tools/src/index.ts:1028:register()。packages/core/tools/src/index.ts:1333:执行入口。packages/core/tools/src/index.ts:1450、:1560、:1600:prepare/dispatch/finalize。packages/core/tools/src/index.ts:1797:结果展示元数据。
5. 工作原理
工具调用先解析并验证参数,再经过 tools/pre-execute 得到 allow/deny/ask;ask 交给 Approval UI。Guard 采用单调拒绝:任何 deny 都不能被后层重新放行。允许后进入调度与 body,随后 post-execute、输出验证、materialize,最终写入 tool/result。PTC 和后台任务仍受相同策略、日志与结果语义约束。
6. 执行流程
无图回退:tool/call 或 PTC → Schema → pre-execute → Guard → ask/allow/deny → execute → post-execute → canonical output → tool/result.meta → 下一模型 Step 和工具卡片。
7. 关键源码讲解
可见性、lookup 和执行限制必须来自同一 Scope。output.render 生成模型可读文本,presentationMeta 是持久的 UI 提示;二者都不能替代 canonical output。PTC 只是调用表达方式,不是绕过批准或日志的后门。
8. 调试与观察方法
断点:执行入口、prepare、dispatch、finalize。记录工具名、解析参数、Scope、策略决策、body 是否进入、canonical value、materialized content 与最终 result。外部副作用已发生却无结果时,优先检查 post/output/finalize,避免盲目重试。
9. 本章实践任务
先实现返回固定值的 workspace_summary,覆盖未知工具、非法参数、ask→approve、Guard deny、输出错误、abort 六条路径;再接只读目录统计。完整实现见第 11 节。
10. 常见误区
- 把 PTC 当作旧
run_codetransport 的改名。 - 只在 Prompt 隐藏危险工具,不做执行时策略。
- 认为用户批准后可跳过路径与 Schema 校验。
11. 自测题
- pre-execute、Guard、execute、post-execute 各管什么?
- 为什么 Guard 必须单调拒绝?
- PTC 如何保持相同日志语义?
output.render与presentationMeta有何区别?- 工具产生副作用后输出校验失败,应怎样设计幂等性?