跳转到内容

工具能执行,不代表它该执行

模型提交了一条写入请求。参数看起来没有问题:

{
"name": "write",
"arguments": {
"path": "README.md",
"content": "new\n"
}
}

字段齐全,类型正确,解析函数顺利通过。如果程序下一行就调用 handler,README 会立刻被覆盖。

Schema 能判断参数是否符合工具合同,却不知道当前任务是否允许写这个文件,也不知道用户有没有批准这一次动作。

一条带副作用的调用至少经过:

参数校验
Capability Policy
需要时暂停并取得 Approval
Handler 执行
阶段 它回答的问题
Schema 工具是否存在,字段与类型是否正确
Policy 当前任务能否对这个资源执行这类动作
Approval 这一次具体调用是否获得明确批准
Handler 文件、进程或网络副作用怎样发生

如果把四件事塞进一个 execute(),很难证明拒绝发生在副作用之前。批准提示也不能单独承担权限控制,模型可能理解错,代码里的工具边界仍然要先执行。

Pi 的 Loop 支持 beforeToolCallafterToolCall。前者可以在执行前检查并阻止调用,后者可以统一处理结果。相关配置见 AgentLoopConfig

准备参数与 Schema 校验发生在 hook 和 handler 之前,查看 prepareToolCall。这给自定义宿主一个清楚的拦截点。

Pi Coding Agent 有意保持较小的默认核心。官方说明中列出的“不内建”项目包括逐工具 permission popup、plan mode、sub-agent 与 MCP,查看设计原则。这些能力可以通过 Extension 或外部运行环境加入。

Project Trust 也不能替代权限策略。它控制项目设置、Extension 和 Skill 是否被加载;项目一旦受信,后续工具仍继承 Pi 进程拥有的系统权限。查看 Pi 的安全说明

my-pi-agentCapabilityPolicy 返回三种结果:

allow
deny
ask

如果结果为 ask,AgentCore 保存当前消息、turn 计数和待执行 tool call,然后返回 needs_approval。批准以后,它先执行原来的 tool call,再进入下一轮模型请求。它不会要求模型重新生成一次写入动作。

运行实验:

Terminal window
cd agent-harness-lab
npm run lab -- 04

预期观察:

{
"firstTerminal": "needs_approval",
"writesBeforeApproval": 0,
"secondTerminal": "completed",
"writesAfterApproval": 1,
"content": "new\n"
}

第一段最重要的是 writesBeforeApproval: 0。它来自工作区计数器,不来自模型的自我声明。第二段表明批准后只执行了一次原调用。

这个教学 approval 很简陋。真实系统还要把批准绑定到操作者、工具名、参数摘要、目标资源和有效期;路径要规范化,命令、网络、凭据与写入也要分开控制。它没有提供操作系统沙箱。

接下来先处理另一个更常见的问题。工具跑得越多,消息历史越长;每次模型请求究竟应该看见哪些内容,需要从 Session 中显式投影出来。