Skip to main content

Pi 为什么只给模型四个工具?

· 7 min read

只给四个工具不是减配,是把所有会因团队而异的东西都从内核里拿出去。

  • 默认工具只有 个:read / bash / edit / write
  • MCP、sub-agent、待办事项、权限弹窗一律不进核心
  • 理由:每个团队的权限规则都不一样,内置任何一套都是错的
  • 循环内核极简:模型决定动工具,工具返回结果,再交回模型
  • 内核之外开了三十多个插口,从会话启动到归档通知
  • 提示词只能写原则,tool_call 前的 Hook 代码才是停止键
  • 极简不等于省事,扩展继承运行账号的全部权限

四个工具足够把一件事做完

先别把 Pi 当成一个配好的数字员工,它更像一块可改造的运行底座。默认交给模型的就四件工具:

  • read 读资料
  • bash 调用现成程序
  • edit 改文件里的片段
  • write 创建新文件,或者整个覆盖掉

editwrite 在中文里容易混成同一个「写」字,记一句话就行:新建或重写用 write,改一段用 edit

看上去朴素,但足够把一件事做下去。读得到资料、跑得动命令、改得了文件,一个任务需要的动作类型基本就这些。

(版本注脚:v0.84.2 里另外还实现了 grep / find / ls,打包成一组只读工具定义备用;默认给模型的那组仍然是上面四个。)

没进内核的东西比进了的更说明问题

MCP、sub-agent、待办事项、权限弹窗——这些能力 Pi 一个都没往核心里塞。

不是因为它们不重要,而是每个团队的做法都不一样

团队想要的规则
安全可能只允许读取
研发需要改代码
客服只能访问指定知识库
财务每一步都要审批留痕

模型、上下文、工具清单、审批规则,四条全都不一样。内置任何一套默认方案,对其余三方都是错的。

Pi 的选择是把协作方式留给团队自己定义。组织上的代价是前期要多设计一层,回报是不用在之后的两年里,围着框架的默认方案反复改自己的业务。

循环内核:工具送出动作,结果带回下一步

Agent 能连续工作,靠的不是模型自己会想很久。程序只是反复做同一件事:

模型看见新结果,才知道下一步该继续查、继续改,还是停下来交给人。四件工具负责把动作做出去,结果负责把下一步带回来——这就是 agent 的循环内核。

这里有个关键性质:所有对外的副作用,都必须从工具调用这一个出口过。发邮件要过 bash,落盘要过 write。记住这一点,下面停止键该装在哪就是显然的。

内核之外全是插口

Pi 有意思的地方不是循环本身,而是它在运行过程里留了大量插口:

时机能做什么
会话刚开始加载项目规则
模型看资料前删掉无权访问的内容
工具真的执行前改参数,或者直接拦住
结果回来后脱敏、补证据、写日志
任务结束归档和通知

提示词、权限、审计,都不用写死在核心里。它们可以是一段段能替换的扩展代码。这类扩展点一共开了三十多个,完整的生命周期清单在这里

这才是「只给四个工具」的另一半:内核做薄,是因为外面接得住

Extension 在动作发生前守底线

回到一个具体场景。团队做合同审查,agent 的提示词里写着「未经确认不要外发」——这条规则大概率会失效。

因为真到外发那一步,模型不会先回头读一遍纪律条款,它只会调用工具。提示词是长上下文里的一段文字,可能被淹没,也可能被模型排错优先级。如果一条规则的生效依赖模型「想起来」,那它就不是规则,是建议

可靠的做法是在工具调用前放一道 Hook 代码。tool_call 事件在工具真正执行之前触发,handler 返回 { block: true } 就能拦停:

import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';
import { isToolCallEventType } from '@earendil-works/pi-coding-agent';

const OUTBOUND = /\b(curl|scp|rsync|sendmail|mail)\b/;

export default function (pi: ExtensionAPI) {
pi.on('tool_call', async (event) => {
if (!isToolCallEventType('bash', event)) return;
if (!OUTBOUND.test(event.input.command)) return;
if (await hasApproval(event.input.command)) return;

return { block: true, reason: '外发动作未经审批,已拦截' };
});
}

没有审批,外发动作就过不去。等工具结果回来,再在 tool_result 里把身份证号、手机号这些信息脱掉,最后把谁做了什么写进日志。

脱敏放在这一层的价值在于它不可逆:模型从头到尾看到的都是脱敏版本,之后无论怎么转述、怎么总结,都不可能把原始号码带出去。而「读完之后请不要复述敏感信息」这种提示词,是把已经泄露的东西寄希望于模型自觉不说。

一句话:提示词写原则,扩展在动作发生前守底线

极简不等于省事

扩展有完整系统权限

第三方扩展可以执行任意代码,并且继承运行账号的全部权限。版本怎么锁、环境怎么隔离、哪些工具能动哪些数据、出问题怎么回放——这几件事 Pi 一件都不会替团队做完,它自己也明确说了没有沙箱

所以别被「极简」两个字带跑偏。只想尽快上线一套标准流程的团队,成熟平台更省心;Pi 适合的是愿意把控制权和工程责任一起接回来的团队。这两样是一个包,不能只拿前一半。这套取舍在企业落地场景下的完整算账是另一篇的话题。

第一步不是装十个扩展

挑一个真实风险不高的任务,先把三件事画清楚:

  1. 它在哪里读数据
  2. 它在哪里改数据
  3. 哪一步必须人来审批

然后只写一个权限扩展,把一类高风险调用拦下来。验收标准也是三条:拦得稳定、日志查得到原因、过程能回放。这三条过了,再去加 MCP、sub-agent 和更多能力。

References

  1. Pi Agent为什么只给模型四个工具?极简Agent机制讲透 —— 产品总监看AI, 哔哩哔哩, 2026-07-26
  2. pi 官方 GitHub 仓库 —— earendil-works, GitHub, 2026-08-19
  3. @earendil-works/pi-coding-agent v0.84.2 —— earendil-works, npm, 2026-08-14