ARTICLE · 1161570
AI 编程助手总不顺手?Pi 把 LLM API、Agent 循环和终端 UI 全拆开给你改
用过 AI 编程助手的开发者,多多少少都碰过这种别扭:工具本身挺能干,但干活的流程是它定好的。
你想插一个自定义的代码检查钩子,想把团队积累的 prompt 模板固化进去,想在 CI 里拿同一个 agent 跑批量任务,往往都得先等官方排期。
面对这类需求,多数项目的选择是继续堆功能。Pi 选了另一条路:能拆的都拆开,让你自己拼。
它对自己的描述只有一句话——一个最小、可扩展的 agent harness,你把它变成你自己的。
它到底是什么
Pi 是一套 TypeScript 写的 AI agent 工具集,主体是一个叫 Pi 的命令行 coding agent,背后撑着一整个 monorepo 的库。
统一的多厂商 LLM API、带工具调用和状态管理的 agent 运行时、带差分渲染的终端 UI 库、管持久化会话和任务的运行时,还有服务和插件相关的组合运行时,都在里面。
它想解决的不是「再做一个更强的 AI 编程助手」,而是「AI 编程助手的工作流凭什么是它说了算」。
默认配置做得足够用,但故意不带 sub-agents 和 plan mode 这类功能——需要就自己写,或者装一个别人写好的包。
适合两类人:想把 agent 嵌进自家工程流程的团队,以及想拿现成积木搭 agent 应用的开发者。
四个定制入口,随你改
Pi 留了四个定制入口:extensions(扩展)、skills(技能)、prompt templates(提示词模板)、themes(主题)。
四者可以单独用,也能打包成 Pi packages,通过 npm 或 git 分发出去。
场景上很直接:团队里每个人写 prompt 的习惯都不一样,把规范过的模板打成包发到内部 npm,新人装完就是统一姿势,不用靠口头传经验。
换模型不用改业务代码
monorepo 里的 @earendil-works/pi-ai 提供统一的多厂商 LLM API,OpenAI、Anthropic、Google 这些都在覆盖范围内。
这意味着换模型不用动实现层:今天用 A 家跑,明天想评估 B 家的效果,改的是配置。
配套的 pi-agent-core 负责工具调用和状态管理,pi-durable 管持久的会话、任务和文档。
想在终端里做一个自己的 agent 界面,pi-tui 是现成的、带差分渲染的 UI 库,不用从零撸渲染逻辑。
同一套能力,四种用法
交互式用、在 print 或 JSON 模式下做自动化、通过 RPC 从外部控制、或者直接用 Pi TypeScript SDK 写应用——四种接入方式,底层是同一个 agent。
白天在终端里交互着改代码,晚上丢进流水线用 JSON 模式跑批处理,用的是同一个东西。
README 里提到的 OpenClaw,就是一个真实世界的集成案例。
权限边界和依赖,都摆在明面上
Pi 不自带权限系统,默认就以启动它的用户和进程权限运行。
这个设计把话说清楚了:需要更硬的边界,得自己上容器或沙箱。官方给了三种模式。
Gondolin 扩展把 pi 和厂商鉴权留在宿主机,只把内置工具和 ! 命令送进本地 Linux micro-VM;普通 Docker 是整进程进本地容器;OpenShell 则是整进程进策略可控的沙箱。
依赖这边也做了硬化:直接外部依赖锁精确版本,.npmrc 里设了 save-exact=true 和 min-release-age=2,避开当天发布的依赖。
package-lock.json 是唯一的依赖事实来源,install-lock 用来钉死传递依赖。
装上就能跑
安装一行命令,脚本会把所有依赖版本钉死,之后用 pi update 更新。
curl -fsSL https://pi.dev/install.sh | sh
Windows 走 PowerShell:
powershell -c "irm https://pi.dev/install.ps1 | iex"
也可以直接用 npm 装,代价是不锁传递依赖:
npm install -g --ignore-scripts @earendil-works/pi-coding-agent
Pi 要求 Node.js 22.19 或更新版本,macOS、Linux、Windows 的安装器在需要时会顺手把 Node 装上。
正常 npm 安装不需要 dependency lifecycle scripts。
然后进到你想让它干活的目录:
cd /path/to/project
pi
进 Pi 之后跑一次 /login,接上订阅或 API key,就能给它派任务了。
用 Nix 的话:
nix run github:earendil-works/pi/stable
stable 指向最新 release,装完用 nix profile upgrade pi 升级。
想钉版本就换成具体的 release tag,比如 github:earendil-works/pi/v1.0.0;写 github:earendil-works/pi 则跟着 main 上的未发布改动走。
Nix 是从源码构建 Pi,Linux 和 macOS 上支持 ARM64 和 x86-64,自己的 checkout 用 nix build . 或 nix run .。
Nix 构建离线进行,内置模型数据来自 nix/model-catalog.json 里钉住的一份 pi.dev 目录版本,运行时 Pi 依然会从 pi.dev 拉更新的目录数据覆盖上去。
需要手动刷新这个 pin:
npm run update:model-catalog-pin
想动 Pi 本身的代码,开发流程是这样:
npm install --ignore-scripts # Install all dependencies without running lifecycle scripts
npm run build # Refresh model data, then build all packages
npm run build:offline # Rebuild using existing model data without network access
npm run check # Lint, format, and type check
./test.sh # Run tests (skips LLM-dependent tests without API keys)
./pi-test.sh # Run pi from sources (can be run from any directory)
要从 release 源码构建独立的二进制,GitHub release 里带了版本化的源码归档,跑的是和官方二进制同一个构建脚本:
VERSION=""
tar -xzf "pi-${VERSION}-source.tar.gz"
cd "pi-${VERSION}"
./scripts/build-binaries.sh --offline-model-data --platform linux-x64 --out "$PWD/out"
归档里已经包含 release 模型数据和原生预构建产物,--offline-model-data 表示直接用这份数据、不去刷新厂商目录。
它的取舍比功能更有意思
Pi 值得收藏的原因不是它功能最多,恰恰相反——它先把取舍写清楚了:哪些默认给、哪些不默认给、哪些交给你自己决定。
对「工具必须顺着我的流程走」的开发者来说,这种姿态比多几个功能更有吸引力。
想试的话,从一行安装命令开始,跑完 /login 丢个任务进去,再去翻 extensions、skills、prompt templates 和 packages 的文档,基本就知道该把它改成什么形状了。
项目以 MIT 协议开源。