工具 —— 戴着手铐的双手
30 秒版本: 模型的"手"就是工具——它能请求执行的小函数。Pi 只带 4 个(
read、write、edit、bash),每次调用都要过一道验证和钩子组成的流水线,所有失败都被翻译成模型能消化的消息。永远不炸。
工具到底是个什么东西?
去掉所有仪式感,一个工具就三样东西:
- 名字和描述——给模型看的那部分("read:读取文件……")
- 参数 schema——接受什么参数,机器可检查
- 一个
execute函数——真正干活的部分
整个接口就这些。模型从不直接碰你的文件系统;它只能用 JSON 请求一次工具调用,然后让外壳去执行。这个"请求/执行"的分离,就是所有安全性的藏身之处——在"开口"和"动手"之间,Pi 有机会检查、拒绝或改造任何东西。
四个(外加三个)
Pi 的默认工具箱故意做得很小:
| 工具 | 干什么 |
|---|---|
read |
读文件(大文件支持 offset/limit) |
write |
新建或覆盖文件 |
edit |
打补丁——精确匹配旧文本 → 换成新文本 |
bash |
跑 shell 命令(带超时) |
另有三个只读工具——grep、find、ls——可以通过工具选项打开。这就是全部内置工具了。没有浏览器,没有数据库客户端,没有部署按钮。
先别急着嘲笑:别忘了有 bash。一个有 shell 的模型,已经能做开发者能做的几乎一切——包括读 README 自学它没有的工具。Pi 的赌注是:一只灵活的通用手,胜过十七件专用 gadgets 的抽屉。(不同意也没关系,扩展机制允许你自己加工具——后面细说。)
"开口"到"动手"之间的五道关卡
模型请求一次工具调用时,Pi 不是直接放行。请求要走一条短短的流水线——就当是过安检,五个岗:
1. 重新打包(prepareArguments)。 模型有些怪癖:有的把数组序列化成字符串,有的该传字符串时传数字。这一岗悄悄把这些已知的毛病捋顺,别人根本看不到原始乱象。
2. 安检机(schema 校验)。 参数在运行时对照参数 schema 检查。类型不对?调用到此为止,一条错误消息退回给模型。工具永远收不到垃圾数据。
3. 保安(beforeToolCall)。 扩展在这里拥有否决权。返回 { block: true, reason: "..." },调用根本不会执行——模型只会收到原因,然后自己重新想办法。想给 Pi 加权限弹窗、白名单、或者"永远禁止 rm -rf"的规矩,就是在这里实现的。
4. 真正干活(execute)。 直到这一步函数才执行。它会收到一个 AbortSignal(你的 Ctrl+C 能传导到这里)和一个 onUpdate 回调用于流式汇报进度——bash 工具输出能一行一行显示而不是静默三十秒,靠的就是它。
5. 最后看一眼(afterToolCall)。 对结果做后处理的钩子:脱敏、写审计日志,或者设置 terminate: true("到这儿就行了,停吧")。
每一岗都可能失败,但没有任何一岗能把异常扔出大楼。
黄金法则:错误是消息,不是崩溃
这个思想值得单独打一束追光,因为它是 Agent 工程里最好的点子之一。
工具失败时——文件找不到、命令退出码 1、编辑目标没匹配上——Pi 会接住它,把失败转成一条普普通通的、标着 isError: true 的工具结果。模型像收到其他结果一样收到它,然后决定怎么办:换个正确的路径重试、试试别的方案、或者告诉你出了什么事。
对比一下朴素版本:异常直接掀翻整个运行,你只能重启重来。在 Pi 里,失败只是输入。一个看得见自己错误的模型就能修正错误——你会实时看着它自我纠偏,那种感觉惊人地靠谱。
顺带一个来自 Pi 自家工具的进阶提示:错误消息写得越具体,模型的恢复能力越强。"File not found" 还行;"File src/auth.ts not found — directory contains auth.old.ts and authz.ts" 才是给模型真正能用的线索。
坦诚的部分:Pi 没有权限系统
大多数 Agent 会不停地弹"允许吗?允许吗?"。Pi 的维护者审视了这种模式,结论是它主要制造弹窗疲劳——用户看都不看就点允许,这是安全表演,不是安全。
所以 Pi 的官方立场(README 原话的意思):它以你的用户权限运行,内置限制为零。 想要真正的边界?在外面修墙:
- 普通 Docker——把整个
pi进程关进容器 - Gondolin——一个 Pi 扩展:认证留在宿主机,工具执行路由进 Linux 微型虚拟机
- OpenShell——策略管控的沙箱
再配上 git(宇宙通用的后悔药),这就是完整的安全故事:隔离进程、版本控制损失、眼睛盯着事件流。 有人觉得这很吓人,粉丝觉得这很痛快。无论如何,它坦诚得 refreshing——你永远不会疑惑 Pi 在保护你什么、没保护你什么,因为它白纸黑字写着。
能带走什么?
就算你永远不碰 Pi 的代码,这里也有三个值得偷进任何 Agent 项目的点子:
- 在边界上做校验。 模型产出的是"大概对的 JSON",每次调用都当不可信输入处理。
- 把失败变成反馈。 模型读得懂的错误,问题就已经解决了一半。
- 把权力讲清楚。 一个没有魔法、也没有假装在保护你的工具集,反而比处处设卡的更容易信任。
资料来源: Security · Containerization · Extensions