PI 是 Mario Zechner(libGDX 作者)做的极简终端编码 harness,仓库 https://github.com/earendil-works/pi,MIT 协议,TypeScript 实现,当前 93.5k stars,最新版本 v0.84.2。它的设计哲学就一句话:我不需要的就不构建。核心只有 read/write/edit/bash 四个工具,系统提示词约 1000 token,没有内置权限弹窗、没有子代理、没有内置 MCP——这些全部通过扩展系统按需补齐。OpenClaw 的底层就是它。官方文档在 https://pi.dev/docs/latest。
Pi 是 BYO-Model 工具:软件本身免费,模型用你自己的订阅或 API key。它同时支持订阅登录(Claude Pro/Max、ChatGPT Plus/Pro、GitHub Copilot、Grok 订阅、OpenRouter)和 30+ 家的 API key。
安装
Pi 以 npm 包分发,全局安装即可:
bash npm install -g --ignore-scripts @earendil-works/pi-coding-agent
--ignore-scripts 用于禁用依赖生命周期脚本,普通安装不需要它。
进入项目目录启动:
bash cd /path/to/project
pi
Pi 在当前工作目录运行,可以读写该目录下的文件。想随时回滚的话,配合 git 或其他检查点工作流使用。
升级 Pi 本身用 pi update --self,需要重装时加 --force。
卸载:
bash # curl 安装器与 npm 安装都用 npm 卸载
npm uninstall -g @earendil-works/pi-coding-agent
# 其他包管理器
pnpm remove -g @earendil-works/pi-coding-agent
yarn global remove @earendil-works/pi-coding-agent
bun uninstall -g @earendil-works/pi-coding-agent
卸载后 ~/.pi/agent/(设置、凭证、会话、已装包)原样保留。
平台说明:Windows 支持原生终端和 Git Bash,Android 上有 Termux 版本,tmux 有专门的使用说明,详见官方文档的 Platform Setup 章节。
模型配置
订阅登录
启动 pi 后运行 /login,选择订阅提供商:
/login xai | |
/login openrouter | |
凭证存 ~/.pi/agent/auth.json,过期自动刷新。/logout 清除。远程无头机器上浏览器够不到 loopback 回调时,把最终跳转 URL 贴回登录提示即可。
API key
启动前导出环境变量,或 /login 里选 API-key 提供商写入 auth.json:
bash export ANTHROPIC_API_KEY=sk-ant-...
pi
支持的提供商与对应环境变量(节选):
auth.json 的 key 字段支持三种取值:字面量、环境变量插值($ENV_VAR)、shell 命令执行(!command,进程生命周期内缓存)。从系统钥匙串或 1Password 取 key 很顺手:
json {"type":"api_key","key":"!security find-generic-password -ws 'anthropic'"}
{"type":"api_key","key":"!op read 'op://vault/item/credential'"}
auth.json 创建时权限为 0600,auth.json 里的凭证优先于环境变量。
云端提供商(Azure OpenAI、Amazon Bedrock、Cloudflare AI Gateway、Google Vertex AI)和本地 llama.cpp 都有官方支持;自定义提供商用 models.json 声明 baseUrl 和模型列表。
模型选择
/model | |
CLI 里用 --model provider/id:thinking 语法,例如 pi -p --model anthropic/claude-opus-4-5:high "..."。
认证解析优先级:SDK 运行时覆盖 > auth.json 存储凭证 > 环境变量 > 自定义 provider 的 fallback 解析器。
基础使用
界面分四块:启动头部(快捷键、已加载上下文/技能/扩展)、消息区、输入编辑器(边框颜色表示当前 thinking 等级)、底部状态栏(工作目录、会话名、token/缓存、花费、上下文占用、当前模型)。
编辑技巧
@ | |
!command | |
!!command | |
"externalEditor": "code --wait") |
消息队列
agent 干活时你可以继续输入:Enter 排队一条 steering 消息(当前 turn 的工具调用执行完后送达),Alt+Enter 排队 follow-up 消息(全部工作完成后送达)。Escape 中止并退回排队消息,Alt+Up 取回。
上下文文件
Pi 启动时加载:
~/.pi/agent/AGENTS.md:全局指令 从当前目录向上逐级找 AGENTS.md或CLAUDE.md某目录存在 AGENTS.override.md时,它整体替换该目录的 AGENTS.md/CLAUDE.md
上下文文件放项目约定、常用命令、安全规则和偏好。改完用 /reload 生效,或 --no-context-files 全局禁用。
替换系统提示词:.pi/SYSTEM.md(项目)或 ~/.pi/agent/SYSTEM.md(全局);APPEND_SYSTEM.md 只追加不替换。
常用命令
/login/logout | |
/model/settings | |
/resume/new | |
/tree/fork/clone | |
/compact [prompt] | |
/export [file]/share | |
/import <file> | |
/reload | |
/hotkeys | |
/session |
非交互模式
bash pi -p "Summarize this codebase"# 单轮,输出后退出
cat README.md | pi -p "Summarize this"# 管道输入合并进提示词
pi -p @screenshot.png "What's in this image?"
pi --mode json "List files"# JSONL 事件流
pi --mode rpc # stdin/stdout 双向协议
包管理命令:pi install <source> [-l](-l 装到项目 .pi/settings.json 共享给团队)、pi list、pi config(开关包内资源)、pi update --all/--models/--self。
会话管理
会话自动保存到 ~/.pi/agent/sessions/,按工作目录组织,每个会话是一个 JSONL 文件,内部是树结构(每条记录有 id 和 parentId)。
启动参数:
pi -c | |
pi -r | |
pi --no-session | |
pi --name "任务名" | |
pi --session <path\|id> | |
pi --fork <path\|id> |
/resume 的选择器支持搜索、Ctrl+P 切路径显示、Ctrl+N 只看命名会话、Ctrl+R 重命名、Ctrl+D 删除(优先走系统 trash)。
压缩
上下文超限时自动触发:contextTokens > contextWindow - reserveTokens,reserveTokens 默认 16384,给模型响应留空间。往回数 keepRecentTokens(默认 20000)作为保留区,更早的消息交给模型生成结构化摘要。
手动触发 /compact [instructions],可以带自定义指示聚焦摘要。摘要格式是固定的:
markdown ## Goal
## Constraints & Preferences
## Progress (Done / In Progress / Blocked)
## Key Decisions
## Next Steps
## Critical Context
<read-files>...</read-files>
<modified-files>...</modified-files>
摘要会累积文件操作记录(读/改哪些文件),跨多次压缩持续累计。单轮消息超大时支持 split turn:把一个超长 turn 从中间切开,分别生成历史摘要和 turn 前缀摘要再合并。工具结果序列化时截断到 2000 字符,防摘要请求 token 爆炸。
扩展可以拦截 session_before_compact 事件取消压缩或塞自定义摘要。
会话树与分支
/tree 在会话文件内导航,跳到任意历史点继续,不新建文件:
text ├─ user: "Hello, can you help..."
│ └─ assistant: "Of course! I can..."
│ ├─ user: "Let's try approach A..."
│ │ └─ assistant: "For approach A..."
│ │ └─ user: "That worked..." ← 当前活动叶
│ └─ user: "Actually, approach B..."
│ └─ assistant: "For approach B..."
选中一条 user 消息:叶子移到它的父节点,消息文本放回编辑器,改完重发就是新分支。选中 assistant/工具消息:直接从那一点继续。
三种分支方式:
/tree | ||
/fork | ||
/clone |
/tree 切走分支时,Pi 会问要不要总结被放弃的分支,把摘要作为 branch_summary 条目挂到新位置——离开的路径不重放,但关键上下文不丢。
/export 导出 HTML,/share 上传私有 gist 拿到可分享链接。开源项目想发布会话做研究,官方有 badlogic/pi-share-hf 发布到 Hugging Face 数据集。
插件扩展
扩展是 TypeScript 模块,Pi 用 jiti 直接加载,不用编译。放对位置就能被自动发现,/reload 热重载:
~/.pi/agent/extensions/*.ts | |
.pi/extensions/*.ts | |
pi -e ./path.ts |
扩展能做的事:
pi.registerTool():注册模型可调用的自定义工具 pi.on():订阅生命周期事件,拦截或修改工具调用、注入上下文、自定义压缩 pi.registerCommand():注册 /mycommand斜杠命令pi.registerShortcut()/ pi.registerFlag():自定义快捷键和 CLI flagpi.appendEntry():往会话写自定义条目,状态跨重启持久 ctx.ui:用户交互(notify/confirm/select/input,甚至自定义 TUI 组件)
核心事件链:session_start → input(可拦截/改写)→ before_agent_start(可注入消息、改系统提示词)→ turn_start → context(改发给模型的 messages)→ tool_call(可 block,可原地改参数)→ tool_result(可改结果)→ turn_end → agent_settled。压缩、分支导航、模型切换、会话切换都有对应事件。
典型用例:rm -rf / sudo 权限门、每 turn git 检查点、.env 等路径写保护、自定义压缩逻辑、todo 列表工具、文件监听/webhook 外部集成。官方仓库 examples/extensions/ 有 50+ 可直接抄的示例。
SKILLS
Pi 完整实现 Agent Skills 标准(SKILL.md 目录结构),这就是 Claude Code / Codex 那套技能规范。一个技能是带 SKILL.md 的目录,其余自由:
text my-skill/
├── SKILL.md # frontmatter + 指令
├── scripts/ # 辅助脚本
├── references/ # 按需加载的详细文档
└── assets/
SKILL.md frontmatter 字段:name(必填,小写字母数字连字符,1-64 字符)、description(必填,≤1024 字符,决定模型何时加载它)、license、compatibility、metadata、allowed-tools(预批准工具,实验性)、disable-model-invocation(设为 true 时技能不进系统提示词,只能手动调用)。
加载位置:全局 ~/.pi/agent/skills/ 和 ~/.agents/skills/;项目 .pi/skills/、.agents/skills/(信任后才加载);包的 skills/ 目录;settings 的 skills 数组;CLI --skill <path>。--no-skills 关闭自动发现。
Claude Code 和 Codex 的技能目录直接复用:
json {"skills":["~/.claude/skills","~/.codex/skills"]}
工作方式是渐进式披露:启动时只把所有技能的 name+description 放进系统提示词(XML 格式),模型判定任务匹配后自己 read 完整的 SKILL.md。描述写得好不好直接决定技能会不会被触发——“Extracts text and tables from PDF files…” 这种具体描述远比 “Helps with PDFs” 有效。
/skill:name 强制加载某个技能,后面可带参数,参数会以 User: <args> 追加到技能内容后。/settings 里可以开关技能命令。Pi 对标准的校验很宽容,多数违规只警告不阻止,也允许技能名和目录名不一致(共享技能目录场景更实用)。
WEBUI
Pi 官方包目录里有一个 pi-web-ui(MIT,作者 xingshuyin):Web 聊天界面,agent 通过 pi SDK 在进程内跑,事件经 WebSocket 推给浏览器。要求 Node.js ≥ 22.19。
功能清单:
流式聊天:思考块、工具调用卡片、bash 输出的实时状态(running → finished) steer 补充:agent 回复中插入指令,排队到当前 turn 工具调用结束后送达 斜杠命令面板:内置 /new /model /compact /cwd /thinking /resume 等 每项目多会话:切走后 agent 继续后台跑,Running conversations 列表可切回 编辑重问:把历史问题 fork 成新分支重新提问,原会话不动 附件三种模式:inline(≤12 KB)、reference(仅路径)、lines(选中行),超限自动降级 Vision bridge:当前模型不支持图片时,自动调一个视觉模型把图转写成文本证据 内置终端(xterm.js + node-pty)和 Git 面板(status/diff/commit/分支切换) 模型管理:UI 里直接改 models.json、配各 provider key(凭证不出服务器) Goal 模式:设定目标 + 审查模型 + 轮次上限,每轮结束后独立审查会话对照目标与 git diff 检查,不过就注入 steer 重试 后台任务面板:按端口快照发现 agent 拉起的服务器,可停止;工具调用超 20 分钟自动中止 安全:默认只监听 loopback, PI_WEB_HOST=0.0.0.0才开 LAN;跨源请求 403;provider 头信息不下发浏览器
社区还有 https://github.com/agegr/pi-web(4.8k stars,本地浏览器 UI,复用同一份本地配置)和 @firstpick/pi-package-webui 等选择。
记忆系统
Pi 内核刻意不带记忆——会话结束即忘,这是极简设计的一部分。记忆靠扩展补齐,生态里最常用的是 pi-memory:pi install npm:pi-memory 装上就有六个核心工具(memory_write / memory_forget / memory_restore / memory_read / scratchpad / memory_status),装完即用。
一切存在 ~/.pi/agent/memory/ 的纯 Markdown 里,可直接 cat、可 diff、可提交 git:
markdown <!-- 2026-06-07 10:12:03 [a1b2c3d4] -->
#preference [[package-manager]] Always use pnpm in this repo, never npm.
跨会话召回是它的卖点:第一会话说"这个仓库永远用 pnpm",几天后的新会话让它装依赖,它自己就记得用 pnpm。可选的 qmd 集成支持关键字/语义/混合搜索(memory_search 和选择性注入需要它),向量嵌入在会话启动和写入后后台自动维护。
其他选择:pi-agent-memory(claude-mem 的 fork 适配,带语义搜索)、tickernelz/pi-memory(持久身份 + 用户画像 + 每日日志)、db0 的持久记忆集成、Mem0 官方 Pi 插件。用法建议:长期偏好和决策写 MEMORY.md,日常进展写按日期组织的 daily log,待办放 scratchpad。
安全约束
Pi 的立场很明确:不内置沙箱,工具以启动它的用户权限运行,这是有意设计。可信边界靠两层:
项目信任
目录里存在 .pi/settings.json、.pi/extensions|skills|prompts|themes、.pi/SYSTEM.md、.agents/skills 时,Pi 判定该项目有需要信任的资源,交互式启动会询问是否信任。决定存 ~/.pi/agent/trust.json,defaultProjectTrust 默认 ask,可改 always/never。--approve/--no-approve 单次覆盖。/trust 手动保存决定。
信任只是加载门:阻止仓库在你批准前偷偷改你的设置或扩展。它不把不受信任的代码、提示词、模型输出变安全——仓库文件里的提示注入是本地 agent 的固有风险,Pi 不承诺防。
容器化
官方给了三种隔离模式:
Gondolin 会把宿主机 cwd 挂载为容器内 /workspace 并写穿透,Docker 的 -v "$PWD:/workspace" 同理;要更强的写保护就用只读挂载。远程沙箱注意:API key 不要随进程带进去,走网关注入。
补充:auth.json 文件权限 0600;API key 支持从系统钥匙串/1Password 拉取,不用明文落盘。
自己编写插件
最简扩展就是一个导出默认函数的 TypeScript 文件,放进 ~/.pi/agent/extensions/:
typescript importtype { ExtensionAPI } from"@earendil-works/pi-coding-agent";
import { Type } from"typebox";
exportdefaultfunction (pi: ExtensionAPI) {
// 拦截危险命令
pi.on("tool_call", async (event, ctx) => {
if (event.toolName === "bash" && event.input.command?.includes("rm -rf")) {
const ok = await ctx.ui.confirm("Dangerous!", "Allow rm -rf?");
if (!ok) return { block: true, reason: "Blocked by user" };
}
});
// 注册自定义工具
pi.registerTool({
name: "greet",
label: "Greet",
description: "Greet someone by name",
parameters: Type.Object({
name: Type.String({ description: "Name to greet" }),
}),
asyncexecute(toolCallId, params, signal, onUpdate, ctx) {
return {
content: [{ type: "text", text: `Hello, ${params.name}!` }],
details: {},
};
},
});
// 注册斜杠命令
pi.registerCommand("hello", {
description: "Say hello",
handler: async (args, ctx) => {
ctx.ui.notify(`Hello ${args || "world"}!`, "info");
},
});
}
用 pi -e ./my-extension.ts 快速试跑。注意:不要在工厂函数里启动后台资源(进程/监听器/定时器)——工厂可能在没有会话时执行,把资源启动推迟到 session_start 事件里,并在 session_shutdown 里清理。
三种组织风格:单文件(小扩展)、目录 + index.ts(多文件)、目录 + package.json(要 npm 依赖时)。依赖直接 npm install 到扩展目录,import 自动解析。
做成可分发的 Pi 包:package.json 里加 pi manifest,声明资源路径:
json {
"name":"my-package",
"keywords":["pi-package"],
"pi":{
"extensions":["./extensions"],
"skills":["./skills"],
"prompts":["./prompts"],
"themes":["./themes"]
}
}
带 pi-package 关键字会被包目录收录。发布到 npm 或 git 仓库后:
bash pi install npm:my-package
pi install git:github.com/user/repo@v1
核心包(@earendil-works/pi-ai、pi-agent-core、pi-coding-agent、pi-tui、typebox)放 peerDependencies 声明 "*",不要打进包里,Pi 会统一带。
架构与 SDK
Pi 是 monorepo(pi-mono),四个核心包:
架构特点:极简核心 + 事件总线。系统提示词约 1000 token,核心不内置任何高级功能,全部通过扩展系统的生命周期事件钩子外挂——这是它和其他 agent 最大的区别,也是 token 优势的来源。
SDK 与 CLI 是同一套代码,三种集成方式:
--mode rpc | |
--mode json | pi --mode json "..." \| jq 一条命令接管道 |
SDK 最小用例:
typescript import { createAgentSession, ModelRuntime, SessionManager } from"@earendil-works/pi-coding-agent";
const modelRuntime = awaitModelRuntime.create();
const { session } = awaitcreateAgentSession({
sessionManager: SessionManager.inMemory(),
modelRuntime,
});
session.subscribe((event) => {
if (event.type === "message_update" && event.assistantMessageEvent.type === "text_delta") {
process.stdout.write(event.assistantMessageEvent.delta);
}
});
await session.prompt("What files are in the current directory?");
核心对象:createAgentSession() 创建会话,AgentSession 管理生命周期(prompt/steer/followUp/subscribe/compact/navigateTree/abort);ModelRuntime 管模型目录与认证(可注入自定义 CredentialStore);SessionManager 管会话树(inMemory/create/continueRecent/open/list,树遍历 branch/branchWithSummary/createBranchedSession);SettingsManager 管配置合并(全局 + 项目);DefaultResourceLoader 管扩展/技能/提示词模板/主题/上下文文件发现。
典型用途:自建 Web/桌面/移动端 UI(pi-web-ui 就是这么做的)、把 agent 能力嵌进现有应用、自动化流水线、自定义工具里再开子 agent、程序化测试 agent 行为。RPC 模式还支持扩展 UI 协议——扩展在 TUI 外的请求走 stdout,响应回 stdin,无头场景也能做交互式工具。
想 fork 一个自己的发行版:package.json 的 piConfig 里改 name、configDir(比如换成 .omp)、bin,命令行 banner、配置路径、环境变量名全部跟着变。Can Bölük 的 Oh My Pi 就是这么来的。
参考来源
Pi 官方文档: https://pi.dev/docs/latest earendil-works/pi 仓库: https://github.com/earendil-works/pi pi-web-ui 包: https://pi.dev/packages/pi-web-ui pi-memory 包: https://pi.dev/packages/pi-memory agegr/pi-web 仓库: https://github.com/agegr/pi-web Mario Zechner:What I learned building an opinionated and minimal coding agent: https://mariozechner.at/posts/2025-11-30-pi-coding-agent Pragmatic Engineer:Building Pi, and what makes self-modifying software so hard: https://newsletter.pragmaticengineer.com/p/building-pi-and-what-makes-self-modifying silenceper:Pi: A Coding Agent Harness You Can Reshape Around Your Workflow: https://silenceper.com/en/article/2026-05-27-pi-coding-agent-harness bradAGI/awesome-cli-coding-agents: https://github.com/bradagi/awesome-cli-coding-agents pradeep.md:pi-mem: surprisingly useful plain-md memory for the pi coding agent: https://pradeep.md/2026/02/11/pi-mem.html db0.ai:Persistent memory for Pi coding agent: https://db0.ai/integrations/pi Mem0:Introducing the Mem0 Plugin for Pi: https://mem0.ai/blog/introducing-the-mem0-plugin-for-pi-code

夜雨聆风