2025 年可以说是 Coding Agent 集中爆发的一年。4 月 OpenAI 将 Codex CLI 开源之后,Claude Code、Cursor、OpenCode 这些终端 Agent 陆续成为不少开发者日常工作里的“副驾驶”。
说实话,我已经受够了 Claude Code。不是因为它做得不好——我很喜欢它,它定义了 Coding Agent 这个品类,背后团队也足够出色。但它的输出总是出问题。
我说的还不是 Bug。真正打断工作流的是 Harness 本身在变化,模型行为也跟着变。
作为工程师,我需要更可靠的工具。在 2026 年这么说多少有点讽刺,毕竟 LLM 本身就不稳定。但我至少可以让其中一部分变得更确定:工具、系统提示词,以及被塞进上下文的所有东西,都应该可控。
如果你认真观察 Claude Code 或 OpenAI Codex,会发现它们在 UI 背后偷偷把大量内容灌进上下文。这些注入内容会以非常隐蔽的方式干扰你。
它们可能一天发布一次,甚至一天发布多次。你可能上午 9 点开始工作时一切正常,10 点就突然失效,到了下午 3 点行为又不一样了——模型没变,变的是 Harness。这样的环境让我没法稳定工作。
Claude Code、OpenCode 和 Codex 几乎每个月都会增加新功能:MCP、Subagents、Plan Mode、后台执行。能力越来越多,但要弄清幕后到底发生了什么也越来越难。
pi 偏偏反着来。它在 GitHub 上已经拿到超过 99,000 颗星,作者 Mario Zechner 是一位因 Java 游戏框架而闻名的工程师。他对现有的 Coding Agent 不满,于是干脆从零给自己写了一个。
它的设计原则也很直接:“如果我不需要它,就不会构建它。”现有工具会在幕后注入上下文,用户根本看不到发生了什么。这正是 pi 要解决的问题。
开始之前:Pi 的极简设计从哪来?
在 Mario 写 Pi 之前,他翻过 Terminal Bench 排行榜,发现一个叫 Terminus 的 Harness 表现很出色。它只给 LLM 一个工具:与 tmux 会话交互。
LLM 必须发送单个按键,再读取 tmux 返回的 ANSI 序列才能完成任务。仅靠这一个工具,它就几乎总能进入前三,还常常拿下第一。
这里有一个关键直觉:模型已经通过强化学习被大量训练过,它们天然知道 Coding Harness 是什么,不需要我们在上面堆太多东西。Pi 正是这个理念的落地:一个极简但可扩展的 Harness。
Pi Agent 的独特之处
Pi 设计上最引人注目的,是它有意省略掉其他 Coding Agent 常见的功能。

不是能力不够,而是作者决定不添加。
Zechner 在博客里质疑过 MCP。问题并不在协议本身,而在 Token 成本。Playwright MCP 会带 21 个工具、13,700 个 Token,占用上下文窗口的 7–9%;Chrome DevTools MCP 则是 26 个工具、18,000 个 Token。
如果你连上 MCP Server,所有工具定义会在每个会话里都被灌进上下文。CLI 工具有 README,你只需要在必要时阅读并运行它们,没有理由持续消耗上下文。
Subagents 也一样。Claude Code 会在内部启动 Subagents,只返回摘要结果,内部发生了什么从外面根本看不到。pi 用 tmux 把多个实例并排展示,所有交互都能被人类直接读取。
现有 Harness 还有另一个问题:系统提示词和工具定义经常变动,用户无法控制哪些上下文被注入。pi 把系统提示词限制在 1,000 个 Token 以下,并完整公开内容。
它一以贯之的原则是:Harness 不应该规定工作流。如果缺某项功能,用户应该自己创建。
OpenCode 和 Claude Code 里没有的功能
pi 采用减法设计,但也有一些 Claude Code 没有的能力。
会话期间切换模型
pi 中的 Context 会以与 Provider 无关的格式序列化。即使你用 Anthropic 开始,中途切到 OpenAI,上下文也仍然保留。使用 /model 或 Ctrl+L 就能立即切换。
思考方式也被统一处理。Claude 的 Extended Thinking、OpenAI 的 Reasoning Effort、Gemini 的 Thinking Budget,都会以 minimal 到 xhigh 的五级尺度呈现。
JSONL Tree Session
会话历史以 JSONL 格式存储,每条记录都有 id 和 parentId,从而形成树结构。/tree 命令允许你回到过去的任意节点,从那里扩展出新分支。
它有点类似 Git Branch,但历史都保存在单个文件里。当你想回到之前尝试过的方案时,不必重新开始会话。
PiPops
Extensions、Skills、Prompt Templates 和 Themes 可以通过 npm 或 git 一起分发。
pi install npm:@foo/pi-tools
pi install git:github.com/user/repo
pi config # Enable or disable
工具本身内置了社区创建和分享 Extensions 的机制。
扩展机制
Pi 即使功能有限也能保持可用,靠的是三种扩展能力。
Extensions 提供最大的灵活性。你可以用 TypeScript 编写它们,添加自定义工具、命令、快捷键和事件处理器。你可以在工具调用前后插入 Hooks,例如,可以像下面这样编写一个阻止危险命令的 Extension。
import { ExtensionAPI } from "@mariozechner/pi-coding-agent";
export default function (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" };
}
});
}
我们并没有移除 Claude Code 的权限确认弹窗,只是让用户可以根据自己的标准创建代码。
Skills 是符合 Agent Skills 标准,并遵循与 Claude Code 中 Skills 相同规范的 SKILL.md 文件。
Prompt Templates 是可复用的 Markdown 文件,可以用 /templatename 展开,也支持 Mustache 变量({{variable}})。
1. 基本安装
安装只需要一条命令:
npm install -g --ignore-scripts @earendil-works/pi-coding-agent
另一种方式是使用安装脚本:
curl -fsSL https://pi.dev/install.sh | sh
有两种身份验证方式:
# Use an API key
export ANTHROPIC_API_KEY=sk-ant-...
pi
# Use an existing subscription
pi
/login # Select a provider
/login 可以直接使用现有订阅,例如 Anthropic Claude Pro/Max、OpenAI ChatGPT Plus/Pro (Codex) 和 GitHub Copilot。
这段视频的重点是学习曲线很低。只需要安装并与它交互,它就会开始工作。
2. 模型设置
这是视频里耗时最长的部分,大约 9 分钟。Pi 支持超过 15 个不同的 LLM Provider,主要包括:
- Anthropic
- OpenAI
- Google Gemini / Vertex
- DeepSeek
- xAI
- OpenRouter
- Amazon Bedrock
- Azure OpenAI
- Groq / Cerebras / Mistral 等
在会话中途切换模型也完全正常:
/model # Model selection screen
Ctrl+L # Same as above
Shift+Tab # Switch thinking level (off–max)
你还可以在 ~/.pi/agent/models.json 中添加自定义 Provider。只要它们使用 OpenAI/Anthropic/Google 兼容的 API,做好配置就能用。也可以连接到像 llama.cpp 这样的 Router Server,使用本地模型。如果你暂时没有多家官方 Key,RouteFast.ai 这类模型 API 中转服务也可以作为统一接入和测试的选择。
Pi 反复强调的优势之一,就是“不会锁定到某个 Provider”。
3. 会话管理
Pi 会话会保存为树结构的 JSONL 文件。保存位置在 ~/.pi/agent/sessions/,每条消息都有单独的 id 和 parentId。
得益于这种结构,下面这些操作都可以在单个文件中完成:
pi -c # Continue the most recent session
pi -r # Select from previous sessions
以下是会话期间的主要命令:

/tree 尤其有意思。你可以回到对话中的“任意位置”,从那里分支继续写。完整历史都保存在一个文件里,所以你能立刻意识到:“哦,我想按 30 分钟前的方式继续。”
/compact 会总结旧消息并压缩上下文。默认情况下也会启用自动压缩;如果发生上下文溢出,它会自动恢复并重试。
4. Plugin Extensions
真正的 Pi 就在这里,视频里大约花了 10 分钟介绍这部分。Pi 的自定义由四个层次组成:
- Extensions (TypeScript) → Tools, commands, UI, and event handling
- Skills → Procedures/instructions written in Markdown
- Prompt Templates → Reusable prompts
- Themes → Display themes
pi install npm:@foo/pi-tools
pi install git:github.com/user/repo
pi list
pi update --all
使用 Extensions,你可以完成下面这些事:
- 添加自定义工具(包括替换内置工具)。
- 自定义创建 Sub-agents 和 Plan Mode。
- 权限门控和路径保护。
- 添加 Status Line、Header 和 Footer 等 UI 元素。
- Git Checkpoint / 自动提交。
- MCP Server 集成。
- (甚至可以在等待时运行 Doom。)
这段视频的重点是:其他 Agent 内置在产品里的功能,比如 Sub-agent、Plan Mode、权限弹窗,都可以用 Extensions 创建。所以 Pi 的核心逻辑是保持基础功能足够精简。
5. Skills
Skills 是以 Markdown 文件编写的“能力包”。它遵循 Agent Skills 标准,包含 SKILL.md 文件的文件夹就构成一个 Skill:
<!-- ~/.pi/agent/skills/my-skill/SKILL.md -->
# My Skill
Use this skill when a user asks about X.
## Steps
1. Perform this action.
2. Then perform that action.
除了通过 /skill:name 显式调用之外,如果任务匹配,Agent 也会自动加载它。
这里的重点是:Skills 被设计成仅在需要时进入上下文。它们不会被全部塞进系统提示词,而只会在使用时展开。这正是维持 1,000 Token 系统提示词的方式。
6. Pi Web(浏览器 UI)
视频还介绍了浏览器 UI“Pi Web”:
npx @agegr/pi-web@latest
主要功能包括:
- 会话工作区:按项目列出、恢复、重命名和删除过去的对话。
- 两种分支路径:从某条消息创建新会话,或在当前会话中创建分支。
- 查看项目文件,显示 Git Diff。
- 切换 Git Worktree。
- 通过 Web 配置 Provider 登录、模型、Package 和 Skill。
~/.pi/agent 与终端版 pi 共享相同的设置和会话文件,所以你可以在浏览器和终端之间随时切换,很方便。
7. 记忆系统
Pi 对“记忆”的处理同样很简单。作者认为,Pi 不需要独立的长期记忆数据库:
- The session itself is memory
整个历史保存为 JSONL,随时可以恢复。
- AGENTS.md / CLAUDE.md
把项目规范、指令和命令写在这些文件里。它们会在启动时从全局设置和目录层级中加载。
- Compaction
长会话通过总结较旧部分来压缩。完整历史仍保留在 JSONL 中,所以你可以用 /tree 返回。
换句话说,职责划分很清楚:“我们已经做过什么”由会话负责,“我们希望你记住什么”由 AGENTS.md 负责。通过 Extension 添加记忆功能也是一种常见衍生用法。
8. 安全使用
Pi 没有内置 Sandbox。Read/Write/Edit/Bash 操作会以启动 Pi 的用户权限运行,Extensions 也一样。
这是刻意的设计选择。一个不完善的进程内 Sandbox 只能提供“看似安全的边界”,所以官方立场是把真正的隔离交给 OS、Container/VM 层。
视频强调,处理不受信任的 Repository 和无人值守执行时,必须始终放在隔离环境中:
# 1. Put the entire pi environment in Docker (simplest)
# 2. Run pi on the host and route only tool execution
# to a local micro-VM (Gondolin)
pi -e ~/.pi/agent/extensions/gondolin
还有一种机制叫 Project Trust。它是一种“输入读取防护”,用来阻止 Repository 随意覆盖 pi 的设置或 Extensions;默认情况下,未经验证的项目会要求确认。
不过要知道,它并不能完全阻止 Prompt Injection。处理未指定的代码或文档时,这一点仍然需要牢记。
9. 创建自己的 Plugins
视频最后大约 5 分钟是实现部分:编写自己的 Extension。
最小的 Extension 只需要一个 TypeScript 文件:
export default function (pi: ExtensionAPI) {
pi.registerTool({
name: "deploy",
// Tool definition (input schema, execution logic)
});
}
pi.registerCommand("stats", {
// Custom command definition
});
pi.on("tool_call", async (event, ctx) => {
// Intercept tool calls and process them
});
把这个文件放到 ~/.pi/agent/extensions/(针对整个用户)或项目下的 .pi/extensions/,Pi 启动时就会自动加载。如果只是临时测试,可以用 pi -e ./my-ext.ts。
官方 Repository 里有不少示例,包括自动提交、Git Checkpoint、MCP 集成和自定义压缩。在 Pi 看来,“所需功能没有内置”是常态;自行添加或安装 Package 才是标准做法。
我的看法
从 Pi 身上至少能学到三点。
添加的功能越多,用户看不见的处理就越多。Subagents、后台执行、自动压缩都很方便,但它们也在增加黑盒。pi 优先让人类能直接观察所有交互。
如果你站在构建自己 Agent 的角度,pi 的设计决策就是一个很好的参照。不要一上来就搞一个包罗万象的 Package,而是从四个工具和一个 1,000 Token 系统提示词开始,只添加真正需要的内容。设计的起点不是“还要加什么”,而是“还能删掉什么”。