工具策略与执行审批:tool policy + approvals
这一章关注“可控性”:把工具能力放出来之前,先把边界定义清楚,才能做到可审计、可回滚。
三层边界(先分清谁负责什么)
- sandbox:隔离执行环境(能力边界)
- tool policy:收敛工具集合(可用性边界)
- approvals:对高风险执行加人工决策(操作边界)
入口:
工具策略流水线(建议当成“安全协议”来实现)
核心思想:先构建工具全集,再按固定顺序逐层收紧,最后再做 hook 注入与审计。
建议把实现明确拆成 5 步(顺序很关键):
- owner-only 裁剪:非 owner 默认看不到高风险工具
- 多层策略 pipeline:profile / provider-profile / global / agent / group / sandbox / subagent 等逐层过滤
- schema 规范化:把工具参数 schema 规范化后再交给 provider(避免 provider 拒绝)
- before_tool_call:允许插件“改参/阻断”,并把改写后的参数用于后续审计
- abort 信号:可选,把取消语义贯穿到工具执行
pipeline 的顺序(用来对齐排障时的“哪一层把工具过滤掉了”)
当你看到“某个工具怎么突然不可用了”,最省时间的定位方式是:按流水线顺序逐层排查。
tools.profiletools.providerProfilestools.allowtools.providers.*agents.*.toolsgroup tools.allowsandbox tools.allowsubagent tools.allow
before_tool_call:改参与阻断的最后一道闸
建议保留两类能力:
- block:直接阻断工具调用(并给出原因)
- params patch:在工具执行前对参数做受控改写
如果你要让 after_tool_call 的审计拿到“改写后的参数”,需要有稳定的参数传递机制(例如按 toolCallId 暂存并消费)。
after_tool_call:成功与失败路径都要审计
要点:
- 成功与失败都触发 after_tool_call(审计完整性)
- 建议 fire-and-forget,避免插件审计拖慢主链路
- 记录 durationMs 等指标,便于定位慢工具与异常
子智能体默认收敛:避免“子任务拿到主控权”
对子智能体建议默认收敛一批工具(尤其是会话/编排类工具),并允许按配置逐步放开。 入口:子智能体。
exec approvals:请求 → 等待 → 决策 → 超时
审批系统建议满足:
- request 返回 accepted 后,客户端可再调用 waitDecision 等待最终结果(两阶段协议)
- 超时返回
null(调用方显式处理 timeout),而不是永远挂起 - 已决条目可保留短暂 grace 窗口,避免 request/resolve/waitDecision 的竞态
入口补充:
最小可验证行为(建议你亲手测一次)
- 当 exec 需要审批时,执行会进入
approval-pending,并广播审批事件,直到被允许/拒绝/超时(参见 执行审批 与 Gateway 协议)。 - 工具 allow/deny/profile 的组合不会“意外放开”未授权工具(参见 工具 与 工具系统)。
常见误区(提前避坑)
- 先响应 accepted 再注册 approval entry:容易出现 waitDecision 找不到 id 的竞态。
- 把审批逻辑写进某个工具内部:导致耦合爆炸、难测难改。
- schema 规范化放在 hook 注入之后:provider 兼容性问题会变得隐蔽且难排。
- 改写参数的暂存机制无上限:高并发下容易内存泄漏。
失败场景与排障入口
- 工具“意外放开/意外消失”:优先从 tool policy pipeline 的每一层找“是哪一步改变了 allow/deny”,再对照 工具系统 与 工具策略。
- 审批卡住/偶发拿不到 decision:确认 request/register/waitDecision 的时序与超时策略;同时用 日志 跟踪一次审批事件流(参见 Gateway 协议)。
读源码入口(可选)
src/agents/pi-tools.tssrc/agents/tool-policy-pipeline.tssrc/infra/exec-approvals.tssrc/gateway/exec-approval-manager.tssrc/gateway/server-methods/exec-approval.ts