Pi Agent Harness:把 AI 编码代理拆成可组装、可重跑的工程工具链
Pi Agent Harness:把 AI 编码代理拆成可组装、可重跑的工程工具链
AI 编码工具正在从「帮我补一段程式」走向「替我完成一个可验证的工程任务」。但功能越多,工作流也越容易被单一产品绑死:模型、工具、上下文、工作阶段、权限与自订指令全部揉在同一个介面里,换一个模型或部署方式就得重新适应。Pi Agent Harness 提供了另一种方向:保留一个最小的终端代理核心,再用 TypeScript extensions、skills、prompt templates、themes 与 packages 组合出自己的工作方式。
我认为 Pi 值得研究的地方,不只是它是一个 coding agent CLI,而是它把「代理产品」拆成几个可以被替换、测试与重复执行的工程层。这种拆分让同一套 agent runtime 可以透过互动模式使用,也可以进入 print、JSON、RPC 或 SDK 流程;团队可以先用 CLI 验证工作流,之后再把相同能力嵌入自己的服务。
先讲结论:Pi 解决的是工作流锁定,而不是模型能力不足
Pi 的官方定位是 minimal terminal coding harness。它预设提供 read、write、edit、bash 等工具,让模型能读取专案、修改档案并执行命令;同时不把 sub agents、plan mode、MCP 或复杂的权限提示视为核心必备功能,而是留给 extensions、skills、外部套件或你自己的工程流程处理。
这个选择有两个直接结果。第一,核心相对容易理解,使用者不需要先学一整套企业级控制台才能跑第一个任务。第二,团队不必接受工具作者预设的协作抽象,可以自行决定要不要加入子代理、检查清单、MCP、审批流程或沙箱。换句话说,Pi 把代理的「最小执行回圈」固定下来,把代理的「产品形状」交还给使用者。
这不代表 Pi 适合所有人。如果你期待开箱即用的多代理编排、完整的计划模式、细致的权限 UI 或内建 MCP 生态,Pi 的刻意克制反而会变成额外工作。但对想把 AI agent 放进既有工程流程的人来说,这种取舍很有价值。
架构拆解:从统一模型介面到可嵌入的 Agent runtime
Pi 专案不是只有一个 CLI。官方 monorepo 将能力拆成几个彼此相关但用途不同的套件:
@earendil-works/pi-coding-agent:互动式 coding agent CLI,负责终端介面、命令列模式、工作阶段与资源载入。@earendil-works/pi-agent-core:具有工具呼叫、状态管理与事件串流的 agent runtime。@earendil-works/pi-ai:统一多供应商 LLM API,让上层程式不必把每个 provider 的请求格式写死。@earendil-works/pi-tui:终端 UI 元件与差异渲染能力。
这种拆分让使用者可以依照需求选择抽象层。如果只是想在终端里完成程式码修改,直接安装 coding agent 即可。如果要做自己的 agent service,可以直接使用 agent-core;如果只需要多模型串接,则可研究 pi-ai 的 provider 与 model 介面。
agent-core 的基本模型是「状态加事件」。Agent 会保存 system prompt、目前模型、工具与讯息,呼叫 prompt 后依序产生 agent start、turn start、讯息更新、工具执行与 agent end 等事件。这里的重要性在于,UI 不必轮询一个最后才出现的完整答案,而是可以在事件流中更新画面、记录工具执行、建立自己的审计轨迹或在特定事件后中止流程。
官方文件也明确区分 AgentMessage 与模型真正理解的 LLM message。前者可以包含 UI 或应用程式自订的讯息型别;在送给模型前,再透过 transformContext 与 convertToLlm 修剪、注入或转换上下文。这使得上下文治理不必硬编码在每个 provider 里,而能成为 runtime 的可插拔步骤。
工具执行同样不是黑盒。Agent 支援平行或循序模式,也提供 beforeToolCall、afterToolCall 与 shouldStopAfterTurn 等钩子。团队可以在工具真正执行前做参数检查,在结果回传前补上审计资讯,或在完成一个回合后判断是否应该先压缩上下文,而不是继续呼叫模型。
四种执行模式,让同一个代理从终端走向服务
Pi coding agent 支援四种主要模式:互动模式、print 或 JSON 模式、RPC 模式,以及 SDK 嵌入模式。
互动模式适合人与代理一起工作。你可以在终端输入问题,让模型读取档案、修改程式与执行测试,并用 /model、/session、/tree、/compact 等命令管理模型与上下文。
Print 或 JSON 模式适合脚本与 CI。当一个任务可以由固定输入触发,例如「检查这次变更是否有遗漏测试」,就不必启动完整 TUI,而是把 prompt、档案参照与结果接到既有管线。
RPC 模式适合由其他程序控制 agent。外部服务可以把 Pi 当成一个可通讯的工作程序,自己负责伫列、权限、观察性与使用者介面。
SDK 模式则适合把 agent runtime 放进应用程式。官方的 createAgentSession 范例展示了如何建立记忆体内工作阶段、送出 prompt,并以程式方式取得执行结果。这条路径的价值是:你可以先用同一个 coding agent 验证提示与工具,再逐步把它收敛成产品内的受控能力。
实际上手:先用 CLI 完成第一个可验证任务
1. 安装 coding agent
官方快速开始使用 npm 全域安装,并建议以 --ignore-scripts 避免安装阶段执行相依套件的 lifecycle scripts:
npm install -g --ignore-scripts @earendil-works/pi-coding-agent
也可以使用官方安装器:
curl -fsSL https://pi.dev/install.sh | sh
这里的 curl 安装方式应只在你已经检查脚本来源、执行环境与供应链风险后使用;若团队需要可重现建置,优先采用已锁定版本的 npm 安装与内部套件快取。
2. 登入模型供应商
可以透过环境变数提供 API key,也可以进入 Pi 后使用 /login 选择现有订阅或供应商。以下示例只展示变数名称,不把任何凭证写进脚本:
export ANTHROPIC_API_KEY="在本机安全地设定"
pi
如果使用订阅登入:
/login
接着选择 provider 与 model。Pi 会维护可使用工具的模型目录;需要立即刷新模型资料时,可执行:
pi update --models
3. 让代理完成一个小任务
先不要从大型重构开始。进入一个有测试的专案,要求 Pi 完成可观察、可回退的小任务:
cd /path/to/project
pi "找出最近变更中缺少测试的函式,先列出档案与理由,不要修改任何档案"
第一个任务的验收标准应该是:它读了哪些档案、提出哪些风险、是否能指出下一步,而不是回答看起来是否流畅。确认只读检查符合预期后,再执行一个明确允许修改的任务:
pi -p "请为目前缺少测试的函式补上最小测试,执行相关测试,最后列出修改档案与测试结果"
若要限制工具,可以只允许读取与搜寻:
pi --tools read,grep,find,ls -p "检查这个专案的设定与测试覆盖缺口"
也可以用 --exclude-tools 或 --no-tools 逐步收紧能力。这种由命令列明确指定工具集合的方式,比只在 prompt 里写「不要修改档案」更容易被脚本、审查与 CI 重现。
扩充模型:skills、extensions、prompt templates 与 packages
Pi 的可组装性主要来自四种资源。
Skills 适合描述可重复的知识与工作流程,例如如何执行资料库迁移、如何检查某种框架的安全设定,或如何按照团队规范产生测试。它们可以放在全域或专案目录,并透过 /skill:name 使用。
Prompt templates 适合把高频任务整理成具名入口,例如 /review、/release-check 或 /debug-api。这比把一大段提示复制到聊天视窗更容易版本控制。
Extensions 是 TypeScript 模组,可以注册自订工具、命令、键盘快捷键、事件处理器与 UI。若你要接入公司内部部署系统、建立审批对话框、拦截工具呼叫或注册自订 provider,extension 通常比修改 Pi 核心更合适。
Pi Packages 则是分享与部署这些资源的单位,可以从 npm 或 git 安装:
pi install npm:@foo/pi-tools
pi install npm:@foo/[email protected]
pi install git:github.com/user/repo@v1
pi list
pi config
专案级安装可使用 -l,把资源放进 .pi 目录;全域资源则放在 ~/.pi/agent。这让同一套工作流可以先在单一专案试用,再打包给团队。
但扩充能力也带来一个不能省略的安全边界:官方文件指出 Pi packages 与 extensions 具有完整系统存取权,skills 也可能指示模型执行任意动作。安装第三方套件前,应检查原始码、锁定版本、限制网路与档案权限,并把敏感凭证放在代理不需要读取的位置。不要把「可扩充」误解成「可信任」。
工作阶段与上下文:把可重跑性放在第一线
Pi 的 sessions 以 JSONL 档案保存,内部使用树状结构,每个项目都有 id 与 parentId。这使得 /tree 可以在同一个工作阶段里切换分支,而不是复制一堆互相失去关联的聊天记录。
常用命令包括:
/session
/resume
/tree
/fork
/clone
/compact
/export
我特别推荐把 session 管理纳入工程流程。每次 agent 任务开始时,先用固定名称建立工作阶段;任务结束时输出摘要、修改档案、测试结果与未完成项目。若结果不理想,可以从树状历史回到修改前的节点,而不是重新猜测当时的上下文。
上下文压缩也应被视为一种工程行为,而不是单纯的聊天功能。Pi 支援手动或自动 compact,但压缩是有损的;完整历史仍留在 JSONL,必要时可以透过 /tree 回看。对长时间执行的 agent,最好在压缩前先写入一份短而结构化的工作状态,例如目前目标、已验证事实、失败尝试与下一步,降低摘要遗漏关键决策的风险。
权限与沙箱:预设能力很强,边界必须由你建立
Pi 预设以启动它的使用者权限执行,没有内建的档案、程序、网路或凭证限制。这对本机个人开发很直接,但对 CI、共享工作站或处理敏感程式库的代理来说,不能只依赖 prompt 约束。
官方 containerization 文件提供三种思路。第一种是 Gondolin extension:Pi 留在主机上,但把内建工具与 ! 命令路由到本机 Linux micro VM。第二种是 Plain Docker:把整个 Pi 程序放入容器,以简单的档案挂载共享工作目录。第三种是 OpenShell:把整个 Pi 放进具有档案、程序、网路、凭证与推理控制的 policy-controlled sandbox。
Docker 的最小示例可以是:
FROM node:24-bookworm-slim
RUN apt-get update \\
&& apt-get install -y --no-install-recommends bash ca-certificates git ripgrep \\
&& rm -rf /var/lib/apt/lists/*
RUN npm install -g --ignore-scripts @earendil-works/pi-coding-agent
WORKDIR /workspace
ENTRYPOINT ["pi"]
执行时把程式码目录挂载到 /workspace,再用独立 volume 保存代理设定与 sessions。不要直接挂载主机的 ~/.pi/agent,除非你确定要让容器读取主机的登入状态与历史工作阶段。
这里的核心原则是分离「模型认为自己应该做什么」与「程序实际被允许做什么」。前者由 system prompt、skills 与 extensions 处理,后者则应由容器、micro VM、档案系统、网路政策与凭证注入机制处理。
Pi 与常见 agent 抽象的差异
Pi、子代理、skills、代理团队与工作流程不是同一层。
Pi 是执行回圈与工作阶段的 harness。它处理模型、讯息、工具、事件与 session,但不替你决定完整产品流程。
Skill 是可载入的知识与操作规范,通常描述「如何做一种任务」。它不一定会建立新的代理程序。
子代理是另一个代理执行个体,适合把任务切成互相隔离的探索或实作工作。Pi 不把子代理列为内建功能,使用者可以透过 tmux、extension 或第三方 package 自行建立。
代理团队是更高层的协作模型,包含角色分工、共享状态、汇整与冲突处理。它需要比单一 agent 更多治理与观察性。
工作流程则是把整个协调逻辑写成可重跑的程式码:输入是什么、何时启动哪个代理、怎么验证输出、失败如何回退,都应该有明确规则。Pi 的价值在于提供一个足够小、可以被这些上层抽象包住的执行核心。
什么团队适合先试 Pi
我会优先推荐以下几种团队试用:
1. 已经有成熟 CLI、测试与 code review 流程,想把 agent 接进现有工程,而不是另建一个封闭平台。
2. 需要在不同模型供应商之间切换,希望模型介面与 coding workflow 不要一起绑死。
3. 想把 skills、prompt templates 与 extensions 放入版本控制,建立团队共用的 agent 套件。
4. 需要把同一个代理从互动终端逐步嵌入 CI、RPC 服务或内部工具。
5. 愿意自己处理权限、沙箱、供应链与观察性,而不是期待工具替你做完所有治理。
相反地,如果你的首要需求是立即使用一个完整的多代理工作台,或团队没有能力审查第三方 extension 与套件,Pi 的最小核心可能会让导入成本变高。它不是「零决策」产品,而是把决策权交给工程团队。
我的导入建议:先限制范围,再逐步组装
第一阶段只做唯读任务:列出变更、搜寻漏洞模式、整理测试缺口。使用 --tools read,grep,find,ls,把输出写入 session 与 CI artifact。
第二阶段开放写入,但要求代理先提出计划、只修改指定目录,并在结束时执行固定测试。用 extension 或 wrapper 记录工具呼叫与修改档案。
第三阶段才加入自订 skills、packages 与模型路由。每个套件都锁定版本,建立最小权限执行环境,并为失败任务准备人工接管路径。
第四阶段把稳定流程搬到 RPC 或 SDK。这时才值得投资伫列、重试、成本统计、事件储存与多租户隔离。不要一开始就把互动 demo 直接包成无人值守的自动部署系统。
结语:最小核心,反而让代理更像工程系统
Pi Agent Harness 的重点不是再提供一个会写程式的聊天介面,而是示范一种更可控的 agent 工程分层:pi-ai 负责模型供应商,pi-agent-core 负责状态与事件,coding agent 负责 CLI 与工作阶段,extensions、skills 与 packages 负责工作流差异,容器或 micro VM 负责真正的安全边界。
当这些责任被拆开,团队才有机会针对每一层做测试、替换与审查。你可以先用终端完成一个小任务,再把相同 runtime 放到 RPC 或 SDK;可以先用唯读工具观察模型,再逐步开放修改权;也可以在不 fork 核心的前提下,加入自己的 provider、工具与治理逻辑。
如果你正在寻找的是一个功能最多的 AI coding 平台,Pi 未必是最短路径。但如果你想把 agent 变成既有工程系统的一部分,而不是再增加一个孤立的聊天视窗,那么它的最小主义值得实际跑起来研究。
参考资料