同一个 Claude 或 GPT,交给不同的 coding agent,往往会呈现出完全不同的工作方式。有的会先写计划、拆子任务、弹出权限框;有的直接读文件、跑测试、修改代码;有的在模型切换后还能续上会话。差异并不主要来自模型本身,而来自模型外部那一层软件:谁组织上下文,谁定义工具,谁执行工具,谁保存状态,又是谁决定哪些动作需要人确认。
Pi 的有趣之处正在这里。它不试图把所有这类决定做成一个预设的产品流程,而是把 Agent Harness 收缩为一个可读、可替换、可组合的内核。模型、工具、UI、计划、权限、子 Agent 和长期任务的组织方式都可以换;相应地,安全、编排和团队标准化也不能再默认交给产品。
本文讨论截至 2026-08-02 的 earendil-works/pi,不比较模型基准。先给出结论:如果你需要开箱即用、默认工作流完整的 coding agent,Pi 未必是首选;如果你希望把 Agent 的行为、上下文与边界变成自己的工程资产,Pi 是一个辨识度很强的底座。
先分清模型、Harness 与执行环境
Pi 是一个开源的 minimal terminal coding harness。它既提供可直接使用的终端编码 Agent pi-coding-agent,也拆出可以嵌入其他应用的组件:pi-ai 处理多 Provider 的消息、流式输出与工具调用;pi-agent-core 管理 Agent loop、状态与事件;pi-tui 提供终端 UI;coding-agent 则把会话、项目上下文、内置工具和交互界面组装成成品。1
把 Pi 当成“另一个 Claude Code”,只看到了它的 CLI 外观;把它当成“一个模型 SDK”,又低估了其会话、工具、事件与终端交互能力。更准确的说法是:Pi 同时是一套成品 coding agent 和一组可编程的 Harness 零件。
所谓 Harness,是让文本生成模型真正参与工作所需的运行时。模型只能依据当前上下文生成下一段内容;Harness 则要决定哪些项目指令进入上下文、暴露哪些工具、如何校验参数和执行命令、怎样把结果回填给模型、何时保存会话,以及如何把中间过程交给人或上层程序。模型能力相同,这些选择不同,结果就可能明显不同。
Pi 的立场是:尽量少把工作流固化到 Harness 这一层。官方把它描述为小核心,通过 TypeScript extensions、skills、prompt templates、themes 和 packages 扩展。1 这使它特别适合两类人:一类是不满足于“工具替我决定了什么”的重度使用者;另一类是希望把 coding loop 嵌进内部产品、自动化或自定义 UI 的开发者。
最小 Agent Loop:Pi 有意不替你决定工作流
Pi 的最小闭环并不神秘:用户给出目标,Harness 组织上下文并调用模型;模型要么直接回答,要么请求调用工具;Harness 校验并执行工具,再把结果写回上下文;直到模型不再请求工具。pi-agent-core 将这个循环、工具执行、事件流和消息队列作为基础能力提供出来。2
2025 年作者复盘 Pi 的起点时,给出的默认 coding agent 极其克制:短系统提示,read、write、edit、bash 四个基础工具,以及从全局到项目逐层加载的 AGENTS.md。作者的判断是,现代前沿模型已经理解编码 Agent 的基本范式;比起把大量隐式规则和工具说明塞进上下文,更值得控制的是上下文中到底出现了什么。3
这不是“工具越少越强”。四个工具覆盖的是最小动作面:观察文件、精确改动、整体写入、调用已有 CLI。它让模型和人都容易理解边界,也让 Shell 得以复用成熟的搜索、构建、测试和版本控制工具;但可发现性、命令约定、错误处理与安全策略也随之交还给用户和环境。
Pi 对渐进披露的偏好来自同一个取舍。它不主张在启动时将所有外部服务的工具 schema 都放进模型上下文;更倾向于先给一个 Skill 的简短描述,需要时再读完整说明或调用已有 CLI。这样可以减少常驻上下文和无关工具干扰,但前提是 Skill 文档、命令帮助和资源发现已经足够好。
因此,Pi 有意不把 MCP、子 Agent、计划模式、Todo、权限弹窗和后台 Bash 写死在 core 中。这里的“不内置”不等于“不能做”:MCP 可以由 Extension 接入或由 CLI 包装,多 Agent 可以由 tmux、多进程或 SDK 子会话组织,计划可以是受版本控制的 PLAN.md,权限确认可以由 Extension 实现,真正的隔离则应由容器或 VM 提供。Pi 的 coding-agent README 将这些替代方案视为产品哲学的一部分。4
Pi 并不反对 MCP、计划或子 Agent;它拒绝的是把某一种实现永久写死在 core 中。对个人黑客和平台团队,这常常是优势。对需要统一策略、低配置成本和可预测协作体验的团队,它也可能是额外负担。
内核很小,工作台并不小
若只用“Pi 只有四个工具”描述今天的项目,会错过它最重要的演进。它没有放弃最小内核,却在内核周围补齐了多模型、会话、可观察性、扩展和分发能力。更有用的理解方式不是数 Release 增加了多少功能,而是看每项能力解决了初始版本的哪一种摩擦,并把哪一种责任转移给了使用者。
| 演进主题 | 当前补齐 | 解决的摩擦 | 仍需承担的代价 |
|---|---|---|---|
| 模型接入 | pi-ai 统一消息、流式与工具调用,支持订阅、API、本地及自定义模型 | 可以在同一 Harness 中试验模型并续接会话 | Provider 对 reasoning、签名、缓存、token 与计费的语义并不一致 |
| 工具与上下文 | 内置 read、bash、edit、write、grep、find、ls,可用 allowlist 限制 | 只读分析与常见检索更直接 | 更丰富的工具面需要更严格的提示注入与权限治理 |
| 会话连续性 | 保存、恢复、分叉、树导航、压缩、导出与消息队列 | 长任务可以回放、纠错和切分分支 | 压缩会丢失细节,分支也需要人维护意图 |
| 可编程性 | 生命周期事件、工具拦截/替换、动态工具、自定义 UI、SDK、RPC、JSON mode | 工作流可以从临时提示沉淀为程序 | Extension 以本机权限执行,接口需要版本治理 |
| 团队分发 | Skill、Prompt Template、Theme 和 Pi Package | 团队可以复用经过验证的流程 | 包、代码和指令同时构成供应链风险 |
多 Provider 是最容易被误读为“统一后没有差异”的能力。Pi 作者明确将它称为会泄漏的抽象:不同服务对 tool call、reasoning trace、缓存和 token 的报告方式不同;跨 Provider 切换上下文只能尽力保留信息,不能保证语义无损;token 与费用统计也不应直接拿去做严谨的多租户计费。3 多模型不是一次配置就消失的复杂度,而是将复杂度集中到一个可检查的位置。
会话能力则让 Pi 从一次性命令转向可持续协作。当前 CLI 支持 --continue、--resume、--fork、会话目录、HTML 导出,以及 Print、JSON、RPC 等非交互入口;工具也能通过 allowlist 收紧为只读集合。4 同一套核心因此能服务终端中的人在回路任务、CI 中的结构化输出、跨语言进程集成,甚至自定义应用 UI。
真正将 Pi 变成工作台的是 Extension 与 Package。Extension 可以监听生命周期事件、注册或覆盖工具、拦截危险调用、添加命令和 TUI 组件、保存 session 状态;Package 则把 Extension、Skill、Prompt 和 Theme 作为 npm、git 或本地资源分发。6 7 这解释了“核心不内置计划模式”并不等于用户永远只能手写计划,而是计划工作流可以成为团队可审查、可固定版本、也可随时移除的外围组件。
最需要反复强调的边界没有变:Project Trust 决定是否加载项目内的 settings、resources、packages 和 extensions;它不是命令 sandbox。Pi 文档明确指出,extensions 会以完整系统权限运行,不可信仓库的文件、命令输出和项目指令也可能成为提示注入载体。8
与 Codex、Claude Code 的差别,是默认决策权
把 Pi、Codex 和 Claude Code 放在一起时,最没有价值的问题是“哪个更强”。任务结果会受模型、提示、仓库、上下文、权限策略和人为 steering 的共同影响。更有用的问题是:哪些决策由产品提前做好,哪些由你配置,哪些必须由你自己造?
| 维度 | Pi | Codex | Claude Code |
|---|---|---|---|
| 核心定位 | 可组合、供应商中立的 coding harness | 与 OpenAI 模型及本地、IDE、桌面和云产品协同的 coding agent | 与 Claude 生态深度协同的终端 coding agent |
| 默认工作流 | 尽量少规定,依赖文件、CLI、Extension 和 Package | sandbox、approval 与任务执行是显式产品能力 | 权限、Skills、plugins、MCP、subagents 等是一等工作流能力 |
| 扩展路径 | TypeScript Extension、Skill、Prompt、Package、SDK/RPC | 配置、MCP、CLI/SDK 与 App Server | Skills、plugins、MCP、hooks、subagents |
| 模型策略 | 多 Provider 和本地模型 | OpenAI/Codex 优先 | Claude 优先 |
| 安全基线 | 不内置 sandbox,需外部隔离 | 可选择 sandbox policy 与 approval policy | 权限模式与用户确认流属于产品体验 |
Codex CLI 的官方仓库将本地 Agent、IDE、桌面和云端 Codex 放在同一产品谱系中;其 Rust CLI 提供 read-only、workspace-write、danger-full-access 等 sandbox 策略,并支持针对命令的审批流。9 Claude Code 则将权限、插件、Skills、hooks 与 subagent 作为产品面的一部分持续演进。10 它们的价值不只在于“内置更多功能”,还在于为团队提供了一套默认约定。
Pi 的不同之处是把这些约定留空。对于 MCP,它更偏向已有 CLI、文档和按需 Skill 的接口观;对于子 Agent,它建议用 tmux 或自己构建;对于权限确认,它宁愿让你使用容器,或在 Extension 中贴合具体环境地实现。这样做能减少不可见的系统提示和固定流程,却要求使用者有更高的工作流表达与维护能力。
选型可以很朴素:需要快速落地、统一默认体验和单一生态协同时,先评估 Codex 或 Claude Code;需要多模型、深入观测 tool loop、将团队工作流发布为代码包,或把 Harness 嵌入自有产品时,Pi 更合适。Pi 的自由度不是无条件收益。如果团队不能维护 Package、策略、隔离与评估,它会变成不必要的可变性。
适合 Pi 的任务,先要有可验证的闭环
Pi 最适合的是目标清楚、验证闭环存在、权限边界可表达的场景。最典型的仍然是人在回路的编码任务:给出一个失败测试,Agent 搜索相关实现、运行测试、做最小编辑、重新验证,再由人审查 diff。任务之所以适合,不是因为模型一定会修好,而是输入、停止条件、工具权限和可回滚产物都明确。
第二类是只读的代码理解、架构调研和审查。Pi 可以仅开放 read,grep,find,ls,让 Agent 不拥有写入和任意 Bash 能力。4 这种模式适合让模型快速建立假设、列出证据和提出后续验证命令;它不能替代人工 code review,更不应被包装成自动安全审计。
第三类是自动化与嵌入。pi -p 适合一次性任务,JSON mode 适合消费结构化事件,RPC 适合非 Node.js 进程,SDK 则适合将 session、UI、领域工具和存储放进自己的应用。1 5 进入无人值守场景后,Pi 反而要求更多工程:固定输入输出 schema、超时、日志、临时凭据、独立工作区、失败处理,以及对写入和网络的隔离。没有这些,所谓自动化只是把一次终端误操作扩大为持续风险。
长期对话与多 Agent 也是 Pi 扩展性最有说服力、最容易踩坑的应用。长期 Agent 要解决记忆范围、会话恢复、密钥、网络、停止与审计;多 Agent 要解决任务拆分、进程隔离、冲突解决与成果合并。二者都不是“多开几个模型”就能得到的能力。
| 场景 | 推荐入口 | 最小控制 |
|---|---|---|
| 局部修复、重构、测试闭环 | Interactive CLI | 审查 diff,保留测试和回滚路径 |
| 只读理解与 Review | CLI / Print | 只读工具 allowlist,记录证据 |
| CI 报告、批处理 | Print + JSON | 受控 runner、超时、临时凭据、结构化输出 |
| 自建产品功能 | SDK / RPC | 领域工具、审计、session 与权限层 |
| 聊天或长期 Agent | Extension + 隔离执行单元 | 独立工作区、记忆作用域、密钥代理、停止开关 |
| 多 Agent | 多 Pi 进程或 SDK 子会话 | 任务契约、隔离目录、验证与合并责任人 |
反过来看,三个信号说明此时不应直接使用高权限 Pi:任务只是“帮我把系统变好”而没有验收条件;任务需要生产凭据或部署权限;任务试图以共享聊天记录替代任务拆分与验证。工具调用能力无法消除这些管理问题。
自由度必须被工程边界接住
Pi 将大量能力留在 core 外,真正的挑战也就从“怎样调用模型”转为“怎样把边界做成可执行机制”。安全、团队分发、长期运行和多 Agent 都不应靠更长的 system prompt 兜底。
把安全放在工具边界
官方 Extension 示例提供了危险 Bash 确认、保护 .env、.git、node_modules、脏工作区保护、工具覆盖,以及将内置工具路由到 sandbox 或 Gondolin micro-VM 的做法。11 这些实践比在 system prompt 中写“不要删除文件”可靠得多,因为它们在工具调用边界执行,可以测试、记录和拒绝。
正确顺序应当是先列出文件、网络、凭据和部署等资产,再设计 deny-first 规则、人工确认与审计。仍要注意,Extension 本身是高权限代码;安装未知 Extension 来“增强安全”,可能恰好扩大供应链风险。
把团队工作流交付为可审查的资源
Pi 的 Skill、Prompt Template、Extension 与 Package 可以形成一条分层路径:Skill 放按需读取的流程、领域说明和验证脚本;Prompt Template 放低成本快捷入口;Extension 承担状态、hook、工具或 UI;Package 将它们固定版本、声明依赖并分发给团队。6 7
这比复制一段不断膨胀的团队提示词更可维护。一个好的 Skill 应处理边界明确的任务,有可执行验证,并说明何时停止;一个好的 Package 应最小化自动加载资源、锁定版本,先用 -e 临时试运行,再进入项目设置。流程应当是软件交付物,而不只是聊天技巧。
把长期运行拆成隔离、记忆与密钥边界
pi-chat 是一个很好的反例教材:它不是简单地将 Pi 接到 Discord 或 Telegram,而是让每个连接在独立 Gondolin micro-VM 中运行、拥有持久工作区;同时区分账户级与频道级记忆,按需发现 Skill,并通过受限的密钥交换避免把真实 secret 直接暴露给 Agent。多频道 worker 则由 tmux 管理。12
它相对初始 CLI 的变化不在“多了一个聊天入口”,而在于明确回答了长期运行的四个问题:执行单元怎样隔离,记忆归谁,秘密怎样使用,用户怎样 stop、查询状态和审计。任何把 Agent 放进 IM、工单或 Slack 的系统,都应先回答这四个问题。
多 Agent 首先是进程编排
Pi 不给出唯一的子 Agent 框架,官方建议使用 tmux 启动独立实例,或通过 Extension 与 SDK 自定义。4 这使你可以按任务选择隔离、模型和工具,但绕不开协调成本。更稳妥的模式是:先把工作拆成可独立验收的单元,为每个单元分配工作目录与权限,通信只传递产物、证据和状态,再由明确的责任人合并结果。
若没有这些契约,增加 Agent 数量通常只会增加冲突、上下文噪声和不可复现性。
先让单 Agent 可控,再扩大自主性
Pi 最容易被误用的方式,是刚安装就接上所有权限、长期任务和多个 worker。更合理的采用路径是渐进扩大自主性,而不是渐进增加提示词。
第一步选择低风险、可恢复的仓库,用同一个小任务分别跑 Pi 和现有工具。记录 Agent 读取了什么、调用了什么、何时失败、会话能否恢复、最终 diff 与测试是什么。目标不是做一个没有控制变量的 benchmark,而是识别自己的上下文、工具和验证缺口。
第二步只固化一个高频流程,例如只读 Review、失败测试分析或受限重构。将输入、允许工具、验证命令、输出物和人工检查点写成项目指令、Skill 或很小的 Extension。此时,稳定拒绝越权行为与成功生成代码同样重要。
第三步才进入团队分发和高风险自动化:固定 Package 版本,审查其中的 TypeScript 与提示内容;在容器、Gondolin 或受控 runner 中运行高风险工具;设置超时、日志、回滚和人工审批。Pi 的容器化文档特别提醒,若只把内置工具路由到宿主 Pi 外的环境,其他自定义 Extension 工具仍可能在宿主机执行,因此隔离范围必须逐个工具核查。13
最后才考虑长期会话与多 Agent。进入这一步之前,单 Agent 必须已具备可恢复 session、停止机制、状态观察、任务验收和明确的权限模型。否则,多 Agent 只是把尚未解决的单 Agent 问题并行放大。
Pi 的价值不在于声称它替你找到了唯一正确的 Agent 工作流,而在于它将工作流本身变成可以阅读、替换、版本化和验证的对象。对于愿意承担这部分工程责任的团队,这是少见的自由;对于只想尽快使用成熟 coding agent 的团队,选择 Codex 或 Claude Code 也完全合理。
让模型负责当下的推理,让 Harness 组织模型与工具,让安全、流程和验收落在可以审查的工程边界上。控制不应消失,它应该回到能够被替换、测试和证明的位置。
参考资料
Mario Zechner, What I learned building an opinionated and minimal coding agent, 2025-11-30。 ↩ ↩