Pi 编码代理教程 · 第四部分:安全治理与性能优化(新目录整理版)
本文件按重新整理版目录,完整覆盖第四部分全部两章:第14章"行为治理与访问控制"、第15章"审计、成本与性能优化",共 7 节。内容严格核实自 pi.dev 官方文档 与 earendil-works/pi 开源仓库,重点澄清网传版本里几个最容易误导人的"内置能力"描述。
第14章 行为治理与访问控制
14.1 真实立场:没有 Policy-as-Code 引擎,靠 Extension 事件拼装
📌 重要校订 :Pi 没有内置的 "Policy-as-Code" 系统 ------不存在一个可以声明式书写"策略文件"、由内核统一加载执行的官方机制。官方立场很直接:"Pi does not include a built-in permission system for restricting filesystem, process, network, or credential access. By default, it runs with the permissions of the user and process that launched it."
真实能达到"代码级行为约束"效果的手段是自己写 Extension,订阅第三部分第11章讲过的生命周期事件来拦截/改写 Agent 的行为,这是应用层拼出来的能力,不是内核自带的策略引擎:
| 想要的约束效果 | 真实实现事件 |
|---|---|
| 拦截/阻断某个工具调用 | tool_call 事件,返回 { block: true, reason: '...' } |
| 改写工具调用参数 | tool_call 事件里直接修改 event.input(可变对象,修改后不会被重新校验) |
| 拦截/改写用户输入 | input 事件,可在请求真正进入 Agent 循环前做预处理或直接拒绝 |
| 改写发给模型的系统提示词 | before_agent_start 事件 |
| 改写即将发给模型的完整消息上下文 | context 事件 |
一个更接近"策略即代码"效果的社区实践:在 input 事件里,先用一个便宜的快速模型对照一份 permission.md 策略文件做分类判断,决定是否放行这条用户消息------被拒绝的请求根本不会到达主模型:
ts
pi.on('input', async (event, ctx) => {
const verdict = await classifyAgainstPolicy(event.message);
if (verdict === 'denied') {
ctx.ui.notify('该请求被项目安全策略拦截', 'warning');
event.cancel?.();
}
});
这确实能实现"代码化策略约束"的效果,但这终究是你自己组合 Extension + 模型调用写出来的应用逻辑,不是 Pi 提供的声明式 Policy-as-Code 框架。
14.2 白名单(--tools)+ Extension 精确拦截(订正:没有黑名单声明方式)
真实可用的三档手段,从粗到细:
| 手段 | 粒度 | 真实机制 |
|---|---|---|
| 工具白名单 | 会话级 | pi --tools read,grep,find,ls,只能按工具名整体圈定,没有"黑名单"这种反向声明方式,只能用白名单正向枚举允许的工具 |
| Extension 精确拦截 | 单次调用级 | 订阅 tool_call 事件,正则/规则匹配命令内容后 { block: true } 阻断,或 ctx.ui.confirm() 二次确认 |
| 容器化隔离 | 进程/系统级 | Gondolin 扩展 / Plain Docker / OpenShell(详见第二部分第8章),从执行环境层面兜底 |
ts
pi.on('tool_call', async (event, ctx) => {
const dangerousPatterns = [/rm\s+-rf/i, /drop\s+table/i, /:\(\)\{.*\};:/]; // rm -rf、SQL DROP、fork炸弹
if (event.toolName === 'bash' && dangerousPatterns.some((p) => p.test(event.input.command ?? ''))) {
return { block: true, reason: '命中高危命令规则,已自动拦截' };
}
});
📌 校订:网传版本描述的"任务白名单/黑名单"作为一个内置声明式配置项(比如写在
settings.json里的一份规则表)不存在 。真实的"白名单"只体现在--tools这一层工具粒度的限定上,更细的行为级黑白名单需要在 Extension 代码里自己维护规则列表。
14.3 思维层级与权限相互独立,无官方联动
📌 重要校订 :
thinkingLevel(详见第二部分第6章)和"行为权限/工具访问范围"之间没有任何官方文档化的联动关系。二者是完全独立的两套配置:
| 配置 | 管辖范围 |
|---|---|
thinkingLevel(off/minimal/low/medium/high/xhigh) |
只影响模型的推理深度与 token 消耗 |
--tools / Extension 拦截规则 |
只影响工具能否被调用、调用是否被放行 |
如果希望实现"低思考档位=低权限、高档位=高权限"这种联动效果,需要自己在 Extension 里读取当前思考等级、动态调整工具白名单或拦截规则------这是自定义业务逻辑,不是 Pi 内置能力:
ts
pi.on('session_start', (_event, ctx) => {
// 示例思路:会话启动时根据当前配置的思考等级动态收紧/放宽工具访问范围
// 具体如何读取当前生效的 thinkingLevel、以及如何动态改写工具白名单
// 需要结合 pi-agent-core / pi-coding-agent 的具体版本 API 自行实现
});