LAYER 03 · 追踪 Agent 主干

工具执行不是一次函数调用

从发现、前置策略、单调 Guard、环绕执行、后处理到不可变最终结果

22 min3 处源码锚点upstream@47f9438
pre → guards → execute → post → finalize → result
本章要解决的问题

为什么一个后加载插件不能把前面已经 deny 的危险调用重新放行?

先建立直觉

工具调用像一件货物过海关:申报、准入、查验、运输、到港处理和最终签收分属不同权威点;任何环节都不能私自改写已经生效的硬性禁运。

MECHANISM

机制拆解

tools/pre-execute waterfall 可 allow/deny/ask;ask 进入 ctx.approval。随后 monotonic guards 只 deny 或 abstain,身份受保护。

tools/execute 包装真实 dispatch,post-execute 可替换结果;注册表规范化 JSON,ToolDefinition.finalizeContent 强制最后内容不变量,tools/result 只观察冻结结果。

第 1 步 / 共 6 步

先记调用

UI 和审计先看到模型原始参数。

INVARIANTS

无论怎么扩展,都不能破坏

  • 每个 tool/call 最终对应一个权威 tool/result
  • Guard 的 deny 不可被后续监听器撤销
  • tools/result 看到的是冻结的最终结果
FAILURE MODES

最容易踩中的坑

  • ×把权限检查写进某个工具 handler
  • ×在 tools/result 中修改结果
  • ×策略异常导致调用绕过检查
VERIFY IN SOURCE

不要相信结论,去源码里复核

以下链接固定到官方 deepseek-harness@47f9438;查看当前上游时请留意后续 breaking changes。

KNOWLEDGE CHECK

先停十秒,再揭晓答案

tools/post-execute 与 ToolDefinition.finalizeContent 有何不同?

为什么下一章紧接在这里

工具流水线定义控制点;下一层先把审批与权限预设放进这些控制点。

Learn DeepSeek Harness

独立教学项目。解释力来自源码,判断边界以官方仓库为准。