Pi Harness:架构与扩展边界
Pi 里能带到别的工具上的,是两条判断。第一条是按层放定制:稳定规则写进项目上下文,可复用的开场提示写成模板,按需的方法写成技能,只有真要新工具、事件钩子或界面时才写扩展。第二条是扩展以启动它的账户权限运行任意代码,所以包只是分发单位,不是安全边界;Claude Code 的 hooks 也一样,它们在沙箱外、以你的全部权限运行(沙箱文档)。
Pi 把 Harness 的核心做得很小,其余能力由使用者一层层加上。核心因此更容易读懂和修改,但安全策略和工作流质量不会自动出现;复杂度没有消失,而是推迟到了搭建工作流的人手里。下文按 Pi 1.4.0(2026 年 10 月 21 日发布)核对,核对日期 2026-10-29。
Pi:可编程的最小 Harness
Pi 自称是一个最小终端编程 Harness。它将模型调用、Agent 循环、工具执行、可分支会话及终端界面保留在核心中,而将特定工作流行为留给可组合的资源。按命令行文档,默认启用的工具只有 read、bash、edit 和 write 四个,设置里的 defaultTools 可以改。--tools 写普通工具名时会替换整个选择;1.1.0 起也能写 +name / -name,在默认四个之上增减,例如 pi --tools +codemode,-write。grep、find 和 ls 也是内置工具,要显式选上才会出现。1.3.0 起,恢复的会话会保留它原来启用的工具。
除了交互式 TUI,Pi 还支持单次 -p 输出、JSON 事件流、stdin/stdout RPC 以及用于把 Agent 嵌入 Node.js 应用的 SDK。提供商可切换。会话存储为可分支的 JSONL 树;/tree、/fork、/clone 和 /compact 涵盖文件内探索、独立会话及上下文压缩。
各定制层级的所有权
全局资源通常位于 ~/.pi/agent/;项目资源位于 .pi/ 或 .agents/skills/。提示模板只是把 /review 这样的命令展开成一段写好的文字。技能平时只露出名字和描述,按需才加载正文。扩展直接更改 Harness 行为。当缺失的是方法时优先选择技能,当是复用输入时选择提示,仅在确实需要新工具、事件钩子或 UI 时才使用扩展。
Pi 的 Agent Loop 怎样运转
对照 agent-loop.ts 和 AgentSession,一次运行有三层:会话先准备请求,底层循环负责模型与工具,外层会话再处理持久化、压缩和重试。
一、模型调用之前已经发生了很多事
用户输入不会直接交给模型。按扩展文档里的生命周期,扩展命令先运行,input 事件可以拦截或改写输入,然后显式调用的 Skill 和提示模板才展开。
如果 Agent 正在运行,新消息不会插进当前工具调用中间,而是进入两种队列之一。Steering 队列里的消息在下一次调用模型之前插进去,用来中途纠偏;Follow-up 队列里的消息等当前任务本来要结束时再取出,让 Agent 接着干。
随后会检查模型和鉴权,并判断旧上下文是否需要先压缩。before_agent_start 事件还可以追加自定义消息或修改本轮系统提示。直到这些步骤完成,用户消息才进入底层 Agent Loop。
二、底层其实有内外两个循环
内层循环负责一轮轮模型调用。每轮开始前,Pi 可以刷新系统提示、工具、模型和思考级别,也会在安全的回合边界插入 Steering 消息。上下文随后经过转换,变成当前模型供应商接受的消息格式,再开始流式生成 Assistant Message。
如果响应包含工具调用,Pi 会执行工具,把每个结果变成 toolResult 消息,再进入下一轮模型调用。如果没有工具调用,也没有等待中的 Steering,内层循环才会停下。外层循环处理 Follow-up:它只在当前工具链和 Steering 都已经耗尽后取出新消息,然后重新进入内层循环。
按 1.4.0 的键位说明,运行中 Enter 提交的消息进 Steering,Alt+Enter 放入 Follow-up(Windows 和 WSL 用 Ctrl+Q);Alt+Up 把排队消息取回编辑器(Windows 和 WSL 用 Alt+Q),Escape 中止运行。
三、工具调用要先过校验和钩子
Pi 会先确认工具是否存在,再准备并校验参数;未知工具或参数不合法的调用根本不会执行。扩展的 tool_call 事件可以阻止调用或修改输入,执行后的 tool_result 事件可以改写结果。工具可以并行执行,但标记为 Sequential 的工具,或全局顺序模式,会强制串行。模型的输出如果被长度上限截断,其中的工具调用一律标为失败,让模型重新提交。
四、agent_end 之后还可能接着跑
底层 Loop 没有更多工具调用和排队消息,或者出错、被取消时,发出 agent_end。这还不是空闲:重试、溢出后的压缩重试或排队的消息都可能再启动一轮,扩展也能在 agent_before_settle 里请求最后一次继续。只有 agent_settled 才表示 Pi 不会再自动继续。测试、Schema、页面断言或人工验收仍然在 Loop 外面,接在这之后。
五、压缩和重试属于会话层
按压缩文档,Pi 在三个时点检查上下文:新 Prompt 之前,工具结果写入之后、下一次模型响应之前,以及底层运行结束之后。超过阈值时,旧消息被总结,近期消息继续保留;遇到供应商报告的上下文溢出,Pi 会压缩后重试一次。1.4.0 起,摘要不再有固定的输出上限,而是用模型自己的输出上限。
消息同时写入树状 JSONL 会话。按会话格式,这棵树保存的是消息、工具结果和压缩记录,没有文件系统快照,所以切换会话分支不会撤销已经写入磁盘的修改。
扩展:Pi 的插件层
扩展是由 Pi 直接加载的 TypeScript 模块。它可以:
- 注册模型可调用的工具和用户斜杠命令;
- 挂钩模型回合、工具调用及结果、模型变更和会话生命周期事件;
- 阻止或重写危险调用,并添加受保护路径或审批 UI;
- 自定义压缩、会话状态、终端组件和渲染;
- 注册提供商,或实现 MCP、子 Agent、计划模式和沙箱集成。
子 Agent、计划模式和沙箱集成仍由示例或第三方包实现,不是核心默认值;MCP 自 0.99.0 起改为内置扩展(见下一节)。较小的核心允许竞争设计,同时让安装者负责其策略、维护和恢复行为。
自动发现的扩展位于 ~/.pi/agent/extensions/ 或受信任项目的 .pi/extensions/;更改后运行 /reload。使用 pi -e ./extension.ts 进行临时实验而无需安装。扩展以当前用户的权限执行任意代码,技能可能指示模型运行捆绑脚本。因此安装前阅读源代码和依赖项,固定版本,并仅启用工作流所需的资源。
0.99 到 1.4:MCP 和 codemode 成为内置扩展
变化最大的是 9 月 29 日的 0.99.0:codemode、工具搜索和 MCP 从这一版起成为内置扩展,都可以在 pi config 里关掉。codemode 让模型写一段 JavaScript,在 QuickJS 沙箱里并行调用 Pi 的工具,只有脚本的输出会交回模型。工具搜索则在需要时找出还没告诉模型的工具,让下一次调用能用上。这两项各对应一个工具,codemode 和 tool_search,默认都关闭;接入的 MCP 服务器需要时,MCP 扩展会自动打开它们。同一版还加入了分类模型,见 Jev 与 Laya。
Model Context Protocol (MCP) 服务器可以走 stdio 或 Streamable HTTP,支持 OAuth,用 mcp.json、/mcp 和 pi mcp add|remove|list|login|logout 管理。之后几版又补了这些:
- 1.0.0:校验授权响应里的
iss,按服务器分别保存凭据;全屏界面成为默认。 - 1.0.1:项目里的
.pi/mcp.json可以为本项目开关或调整用户级的服务器;支持用 Client ID Metadata Document 注册。 - 1.0.4:
--no-mcp在一次运行里关掉 MCP;--tools支持mcp__<服务器>__*这样的模式。
日常使用
普通项目第一天只需要 AGENTS.md 写规则和验收命令;.pi/prompts/、.agents/skills/ 和 .pi/extensions/ 等到真有重复内容再加。常用命令:
pi --name "parser repair" # 交互式会话
pi -c # 继续最新会话
pi -r # 打开会话列表
pi --no-session -p "Summarize this repository" # 临时单次调用
pi --no-session --tools read,grep,find,ls -p "Review the change" # 只给只读工具
pi --no-extensions -e ./.pi/extensions/policy.ts # 只加载待测扩展
交互中常用 /model 切换模型,/tree、/fork、/clone 管理分支,/compact 手动压缩,/reload 重新加载扩展、技能和上下文文件。
安全:只记两个 Pi 专有的开关
Pi 不在工具调用前请求批准,也没有内置沙箱;它的基线和其他工具的对照见 Agent 安全。Pi 自己要记的只有两点:
- 项目信任只决定是否加载项目里的
.pi设置、MCP 配置和扩展,不限制工具能碰什么。打印、JSON 和 RPC 模式弹不出信任提示,自动化运行要显式写--approve或--no-approve(安全文档)。 - 审查类任务用
--tools read,grep,find,ls,只在需要写入时扩大工具集。