开源编程 Agent pi 上手实录:从 npm 安装到跑通第一个任务

2026-07-29

本文基于 pi v0.82.1(仓库 commit 027a584,2026-07-28)梳理,该项目仍在快速迭代,具体行为以官方文档 https://pi.dev/docs/latest 与仓库最新代码为准。

pi 的安装环节只有一条命令,真正会把你卡住的是第二步——凭据从哪来,以及它在你机器上落到哪个文件里。 把这两件事想明白,剩下的第一次对话、会话续接、Windows 适配都是顺水推舟;想不明白,你会在 /login 的选单前反复试错,或者装完发现它连一次请求都发不出去。

这个项目的主仓库在 https://github.com/earendil-works/pi-mono ,MIT 许可证,截至 2026 年 7 月 GitHub 上约 8 万 star。它把自己描述成一个极简的终端编程 harness:核心保持小,工作流层面的能力靠 TypeScript 扩展、skills、prompt templates、themes 和 pi packages 往外长。

站内的 Claude Code 使用教程Claude Code 在 Windows 怎么装?原生 vs WSL 报错排查 讲的是这类命令行 Agent 的通用装法和 Windows 上的共性坑,那是方法论。本篇不重复方法论,只盯着 pi 这一个能被你当场 clone 下来核对的仓库,看它的文档里到底把哪些东西写死了。

一、装:一条命令,以及那个 —ignore-scripts

pi 以 npm 包的形式分发。仓库文档给出的安装命令是:

npm install -g --ignore-scripts @earendil-works/pi-coding-agent

包名要记准:@earendil-works/pi-coding-agentpi 只是它装出来的可执行命令名(package.jsonbin 字段里就是这么映射的),不是包名,照着命令名去 npm i -g pi 装不到这个项目。

--ignore-scripts 这个参数值得单独说一句。它的作用是在安装期间禁用依赖的生命周期脚本,文档给的理由很直白:正常的 npm 安装场景下,pi 本身不需要安装脚本。对于一个会读写你整个源码树、还会调 shell 的工具,安装阶段少跑一批第三方脚本是纯赚。这条思路和仓库 README 里写的供应链策略是一致的——直接外部依赖锁到精确版本,.npmrc 里设了 save-exact=truemin-release-age=2,避免在依赖解析时拉到当天刚发布的版本。

仓库还给了一个 shell 安装脚本作为替代:

curl -fsSL https://pi.dev/install.sh | sh

这个 installer 底层走的还是全局 npm,所以卸载时用 npm 卸就行;用 pnpm、Yarn、Bun 装的则各用各的全局 remove 命令。有一点要提前知道:卸载 pi 不会清掉 ~/.pi/agent/ 下的设置、凭据、会话和已装的 pi packages,重装之后这些还在。

环境上唯一的硬门槛写在包的 engines 字段里,它对 Node 声明了一个最低版本下限。这个下限不是随便写的:低于它的运行时可能装得上却跑不起来。装之前先 node -v 看一眼,再去 packages/coding-agent/package.json 里对一眼 engines.node,比装完了在启动阶段报一堆语法错误再回头查要省事。

装完 cd 到你要它干活的项目目录,敲 pi 就进交互界面了。它跑在当前工作目录里,也就地修改那里的文件。

二、凭据:四条来源,一个优先级顺序

这是最容易翻车的一环。pi 认四条凭据来源,而且优先级是文档里明确写死的:

  1. 命令行 --api-key 参数
  2. ~/.pi/agent/auth.json 里的条目(API key 或 OAuth token)
  3. 环境变量
  4. models.json 里的自定义 provider key

注意第 2 条压第 3 条——auth.json 里的凭据优先于环境变量。这个顺序解释了一类典型故障:你在 shell 里 export 了新 key,重启 pi 还是在用旧的,因为 auth.json 里有一条老记录一直在兜底。真遇到这种情况,去看 auth.json,别在环境变量上打转。

订阅登录/login,在交互界面里敲,然后选 provider。文档列出的内置订阅登录包括 ChatGPT Plus/Pro(Codex)、Claude Pro/Max、GitHub Copilot、xAI、OpenRouter 和 Radius。token 存在 ~/.pi/agent/auth.json,过期自动刷新;OpenRouter 走的是 PKCE 授权流程,铸出来的是一把用户自己可控、不会自动过期的 API key。/logout 清凭据。

这里要诚实说一句:上面几家海外模型服务商,官方对中国大陆都存在区域限制、不支持直连,订阅本身能不能开通、开通后能不能用,是你得先解决的前置问题。市面上确实存在第三方中转,但那不在官方支持范围内,具体渠道本文不做任何背书和推荐。各家的规则不同且会调整,以官方最新说明为准。

API key 有两种给法。最省事的是启动前设环境变量:

export ANTHROPIC_API_KEY=sk-ant-...
pi

也可以跑 /login 选一个 API-key 类型的 provider,让它把 key 写进 ~/.pi/agent/auth.json。这个文件创建时权限是 0600,只有你本人可读写。

auth.json 里的 key 字段还支持几种写法,对团队场景挺有用:以 ! 开头的值会被当成 shell 命令执行、取 stdout 作为 key(进程生命周期内缓存),所以你可以把 key 放在系统钥匙串或密码管理器里,让 pi 现取现用:

{ "type": "api_key", "key": "!op read 'op://vault/item/credential'" }

$ENV_VAR${ENV_VAR} 形式做环境变量插值,$$$! 分别转义字面量的 $!。而像 MY_API_KEY 这样不带 $ 的纯大写串会被当成字面量而不是变量名——这是个容易写错的点。密钥落盘这件事本身的风险控制,可以配合站内 API Key 怎么管才不泄漏 一起看。

三、第一次对话该怎么开口

进去之后直接打字回车就行。文档给的第一句示范是让它先自我介绍这个仓库:

Summarize this repository and tell me how to run its checks.

这个开口方式不是随便举的例子。默认情况下 pi 给模型四把工具:read 读文件、write 创建或覆盖文件、edit 打补丁、bash 跑 shell 命令。另外还有三把只读的内置工具 grepfindls,通过工具选项开启。第一句让它读仓库、找出检查命令,等于用最低风险的动作把它的认知拉到和你同一水平线上,同时你也能观察它调工具的方式对不对。

比这更值回票价的是给它一份项目说明。pi 启动时会加载上下文文件,你在项目里放一个 AGENTS.md

# Project Instructions

- Run `npm run check` after code changes.
- Do not run production migrations locally.
- Keep responses concise.

加载路径是:~/.pi/agent/AGENTS.md 作为全局指令,再加上从当前工作目录往上走的各级父目录和当前目录里的 AGENTS.mdCLAUDE.md。改完这些文件要重启 pi 或者跑 /reload 才生效。不想加载可以用 --no-context-files(简写 -nc)。

几个第一天就该用上的输入技巧:编辑器里打 @ 会模糊搜索项目文件,也可以在命令行直接传:

pi @README.md "Summarize this"
pi @src/app.ts @src/app.test.ts "Review these together"

!command 会跑一条 shell 命令并把输出送给模型,!!command 则跑了但不把输出塞进上下文——后者在你只想自己看一眼结果、不想污染上下文时很好用。/model 或 Ctrl+L 换模型,Shift+Tab 循环 thinking level。

会话是自动保存的,存在 ~/.pi/agent/sessions/,按工作目录组织。pi -c 接最近一次,pi -r 浏览历史,pi --no-session 走一次性不落盘的模式。交互里还有 /tree 跳到会话中任意一点接着往下走、/fork 从某条用户消息分叉出新会话、/clone 把当前活动分支复制成一个新会话文件。

一次性任务用 -p

pi -p "Summarize this codebase"
cat README.md | pi -p "Summarize this text"

要接进自己的流水线,--mode json 输出 JSON 事件行,--mode rpc 走 stdin/stdout 的进程集成。

下面这张表是我读文档时整理的方位图,仓库路径都是实际打开过的文件:

组成部分它负责什么对应仓库位置你什么时候会碰到它
安装与首次会话流程装、认证、跑通第一句话packages/coding-agent/docs/quickstart.md第一天
Provider 与凭据订阅登录、API key、云厂商、解析顺序packages/coding-agent/docs/providers.md认证卡住、换服务商时
CLI 与交互参考斜杠命令、会话选项、工具开关、模型参数packages/coding-agent/docs/usage.md想知道某个开关叫什么时
环境变量进程配置变量、bash 工具注入的会话变量packages/coding-agent/docs/environment-variables.md做离线、代理、脚本集成时
Windows 平台说明bash 查找顺序、自定义 shell 路径packages/coding-agent/docs/windows.md在 Windows 上第一次启动
终端按键适配Kitty 键盘协议、各终端的按键映射packages/coding-agent/docs/terminal-setup.md发现某个快捷键没反应时
设置项清单全局与项目两级 JSON 设置packages/coding-agent/docs/settings.md想固定默认模型、主题、shell 时
安全边界说明项目信任、无内置沙箱的理由packages/coding-agent/docs/security.md决定要不要容器化时
Node 版本门槛engines 字段packages/coding-agent/package.json安装报错时

还有一组环境变量是 pi 反过来注入给 bash 工具的,调试时很有用:PI_SESSION_IDPI_SESSION_FILEPI_PROVIDERPI_MODELPI_REASONING_LEVEL。文档里明确写了,问它现在跑的是哪个模型时,应该让它去读这些变量,而不是从系统提示词里推断:

printf '%s/%s\n' "$PI_PROVIDER" "$PI_MODEL"

值在每条命令启动时解析,所以你中途换了模型或改了 reasoning level,下一条 bash 命令就能看到新值,不用重启。另外这些变量只注入 LLM 可调用的 bash 工具,你自己敲的 !!! 命令里没有。

四、Windows 上要额外做的三件事

pi 在 Windows 上要求有一个 bash shell。它按这个顺序找:

  1. ~/.pi/agent/settings.json 里的自定义路径
  2. Git Bash,即 C:\Program Files\Git\bin\bash.exe
  3. PATH 上的 bash.exe(Cygwin、MSYS2、WSL)

多数人装个 Git for Windows 就够了。如果你的 bash 在别处,写死到设置里:

{
  "shellPath": "C:\\cygwin64\\bin\\bash.exe"
}

shellPath 支持开头用 ~ 表示 home 目录。

第二件事是终端按键。pi 用 Kitty 键盘协议来可靠识别修饰键,Windows Terminal 需要手动转发几个组合键,否则你会遇到”Shift+Enter 换不了行""Alt+Enter 直接全屏了”这类现象。文档给的配置是往 Windows Terminal 的 settings.json 里加:

{
  "actions": [
    {
      "command": { "action": "sendInput", "input": "\u001b[13;2u" },
      "keys": "shift+enter"
    },
    {
      "command": { "action": "sendInput", "input": "\u001b[13;3u" },
      "keys": "alt+enter"
    }
  ]
}

Alt+Enter 在 Windows Terminal 里默认绑的是全屏,而 pi 用它来排队 follow-up 消息(Enter 排的是 steering 消息,在当前这一轮的工具调用执行完后送达;Alt+Enter 排的是等它把活全干完再送达)。改成 sendInput 之后真实按键才会传给 pi。如果改完全屏行为还在,把 Windows Terminal 彻底关掉重开。

第三件是几个平台差异:粘贴图片在 Windows 上是 Alt+V 而不是 Ctrl+V;多行输入除了 Shift+Enter,Windows Terminal 上还可以用 Ctrl+Enter;Ctrl+G 调外部编辑器时,如果没配 externalEditor、也没有 $VISUAL / $EDITOR,Windows 上回落到记事本。用 VS Code 集成终端的话,较新的版本已经在集成终端里默认开启 Kitty 键盘协议,Shift+Enter 开箱可用;更老的版本要自己往 %APPDATA%\Code\User\keybindings.json 里加一条 Shift+Enter 的 workbench.action.terminal.sendSequence 绑定(terminal-setup.md 里给了从哪个版本开始默认生效,以及三个平台的 keybindings.json 路径)。

五、边界与代价:它明确不管的那些事

一个工具的取舍比它的功能列表更能说明它适合谁。pi 的文档在这点上相当坦白。

核心里不内置的东西,文档原话列了这么几样:MCP、sub-agents、权限弹窗、plan mode、to-dos、后台 bash。它的说法是这些都可以做成扩展或 package,或者用容器、tmux 这类外部工具解决。这意味着你从别的工具迁过来时,那套围绕权限确认弹窗建立的操作习惯是不成立的——你得换一套边界机制。相关的思路可以参考站内 主流 AI Agent 框架对比

没有内置沙箱,而且这是刻意的。文档给的理由是:内置工具能读文件、写文件、改文件、跑 shell 命令,权限就是 pi 进程的权限;扩展是 TypeScript 模块,同样跑在这个权限里。一个不完整的进程内沙箱容易被误当成安全边界,可它实际上还是依赖宿主的 shell、文件系统、包管理器、凭据和扩展代码。真正的隔离得来自操作系统或者虚拟化/容器边界。

项目信任不是沙箱。pi 在交互式启动时,如果发现当前目录有 .pi/settings.json.pi/extensions.pi/skills.pi/SYSTEM.md 这类项目级资源,而 ~/.pi/agent/trust.json 里对这个目录或其父目录没有已保存的决定,它会问你信不信任。但文档说得很清楚:这只是一道输入加载的闸门,防的是一个仓库在你点头之前偷偷改掉 pi 的设置或扩展;它不能让不可信的代码、不可信的提示词、不可信的模型输出变安全。来自仓库文件、注释、文档、构建输出的提示词注入,是本地 Agent 的预期风险,pi 不承诺能可靠拦住。

还有一点要提前知道:AGENTS.mdCLAUDE.md 这类上下文文件是不受项目信任约束的,只要没禁用上下文加载就会被读进去。也就是说,你 clone 一个陌生仓库进去开 pi,即使拒绝信任,它的 AGENTS.md 照样进了上下文。非交互模式(-p--mode json--mode rpc)根本不弹信任提示,走的是全局设置里的 defaultProjectTrust,默认值 asknever 都会忽略那些项目资源,只有 always 才信任。

所以边界得你自己划。对不可信仓库、你不打算盯着看的生成代码、无人值守的自动化,官方的建议是把 pi 放进容器、VM、micro-VM 或策略沙箱里跑,只挂载任务需要的文件和凭据。工作区隔离这件事的通用做法,站内 多个 agent 同时改文件老是打架,什么时候该给它开独立工作区 有更展开的讨论。

六、上手清单:为什么会踩,以及怎么避

包名装错。 会踩是因为命令名是 pi,很多人凭直觉去 npm i -g pi。避法是复制文档里的完整包名 @earendil-works/pi-coding-agent,装完用 pi -v 确认版本号能出来。

Node 版本不够。 会踩是因为全局装 npm 包这件事太熟了,没人会先查 engines。而 pi 在 engines.node 里写了明确的下限,低于这个下限可能装得上却跑不起来,报的错还未必指向版本。避法:装之前 node -v,拿结果去比包里声明的下限。

环境变量改了不生效。 会踩是因为凭据解析顺序里 auth.json 压环境变量,而 /login 又会悄悄往 auth.json 写东西。你以为自己只用环境变量,其实早就有一条持久化记录了。避法:改 key 之前先确认 ~/.pi/agent/auth.json 里那个 provider 有没有条目,有就直接改它,或者 /logout 清掉。

auth.json 里的 key 被当成字面量。 会踩是因为大写下划线的字符串看起来就像变量名。pi 的规则是不带 $ 的纯大写串按字面量处理,写 MY_API_KEY 它就真的把这一串字符原样当 key 发出去了。避法:引用环境变量一律写 $MY_API_KEY;变量名后面还要接字面量文本时用 ${FOO}_BAR 的形式,因为 $FOO_BAR 会被整体当成一个变量名。

Windows 上没装 bash 就开跑。 会踩是因为在 Windows 上不会预期一个 npm 包要依赖 bash。pi 的 bash 工具需要真实的 bash 可执行文件,找不到就废掉一大半能力。避法:先装 Git for Windows,或者把 shellPath 写进全局设置。

Alt+Enter 一按就全屏。 会踩是因为这是 Windows Terminal 的默认绑定,跟 pi 的 follow-up 排队撞了。避法:按前面那段 sendInput 配置改掉,改完彻底重启终端。

改了 AGENTS.md 但模型没看到。 会踩是因为上下文文件只在启动时加载。避法:改完跑 /reload,或者干脆重启。同理,/trust 写完 trust.json 之后当前会话也不会重新加载,得重启才生效。

卸载了以为清干净了。 会踩是因为 npm 卸载只删包。设置、凭据、会话、已装 packages 都还留在 ~/.pi/agent/。避法:如果你是在换机器或者交还设备,手动确认这个目录的处置——里面可能有明文 API key。

在陌生仓库里直接跑。 会踩是因为项目信任的提示很容易被当成一个普通确认框顺手点过去。避法:把”这个仓库我信不信”当成一次真实的判断,不信任就先只读地看(用 --tools read,grep,find,ls 起一个只读会话),或者放进容器。

收尾

跑通第一个任务之后,值得按这个顺序自检一遍:pi -v 能出版本号;/session 能看到会话文件和 ID;让它跑一条 bash 打印 $PI_PROVIDER$PI_MODEL,确认你以为在用的模型就是它实际在用的;项目根目录有一份写了实话的 AGENTS.md~/.pi/agent/auth.json 里没有你已经不用的旧凭据。

接下来该读哪个文件,取决于你卡在哪:想固定默认模型、主题、shell,去 docs/settings.md;想知道某个快捷键叫什么、能不能改,去 docs/keybindings.md;准备把它接进自动化流水线,去 docs/json.mddocs/rpc.md;决定要不要容器化,去 docs/security.mddocs/containerization.md。这个项目迭代很快,遇到与本文描述不一致的地方,以仓库里的文档和代码为准。

本篇属于一个把开源编程 Agent 项目 pi 逐层拆开讲的系列,整体地图见开源编程 Agent pi 是什么;沿着这条线往下,还可以看 开源编程 Agent pi 接入国产模型开源编程 Agent pi 没有内置权限系统

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。