本文是「Pi-Agent 项目原理详解」的开篇。不涉及源码细节,而是回答一个更根本的问题:Pi 是什么?它为什么值得你花时间?读完这篇,你会对 Pi 的三个身份——编码工具、学习教材、开发 SDK——有一个清晰的全局认知。
你可能因为三种不同的原因点开了这个系列:
这三个问题,恰好对应 Pi 的三个身份。而这三个身份指向同一个项目,这本身就值得好奇。
在深入源码之前,我们先站远一点,看看 Pi 的全貌。
Pi 是一款极简、可扩展的终端编码 Agent 外壳(coding agent harness),由 libGDX 作者 Mario Zechner 创建,全部用 TypeScript 编写,MIT 协议开源。
拆开来看:
| 指标 | 数值 | 含义 |
|---|---|---|
| GitHub Stars | 64,000+ | 十个月的增长,社区验证了需求 |
| 内置工具数 | 4 核心 + 3 辅助 | 核心:read / write / edit / bash;辅助:grep / find / ls |
| 系统提示词 | 静态模板 ~90 词(英文 word,运行时 200-400 词) | 对比 Claude Code 的数万字 |
| TUI 代码量 | ~12000 行 | 核心 tui.ts 单文件约 1700 行;Mario 的游戏引擎背景带来的"克制" |
| 支持供应商 | 30+ 家 | 源码 KnownProvider 枚举实际 35 个(含区域变体),独立品牌约 27 个;Anthropic、OpenAI、Google、Groq、Ollama 等 |
| 核心包数量 | 4 个 | pi-ai / pi-agent-core / pi-tui / pi-coding-agent |
| 运行模式 | 4 种 | 交互 / print-JSON / RPC / SDK |
关于数字的说明:Pi 官网早期营销材料常说"4 个内置工具"、"15+ 家供应商"、"约 600 行 TUI"——前两者分别指核心 4 个工具(不含 grep/find/ls 辅助工具)和早期版本列举的知名厂商;"600 行 TUI"是早期版本的数字,v0.80.2 实际已增长到约 12000 行。本表按 v0.80.2 源码实际数字呈现,避免读者对照源码时困惑。
这四层里,pi-ai / pi-agent-core / pi-coding-agent 构成一条三层堆栈(每层可独立使用),pi-tui 是一个正交的 UI 库,与 Agent 体系完全解耦——你可以只用 pi-ai 调模型,也可以用 pi-agent-core 在你自己的应用里跑 Agent Loop,完全不需要碰 CLI。这是 Pi 作为 SDK 的核心价值,我们在第五节细讲。

配图说明:四个核心包的分层依赖图。coding-agent 在顶层(产品+SDK),agent-core 在中层(引擎),pi-ai 在底层(模型抽象),pi-tui 是平行的 UI 层不依赖任何 AI 包。底部展示四种运行模式。
外围还有一个实验性的 pi-orchestrator(v0.80.x 新增),负责多 Agent 编排,不在核心学习主线内。
先聊最实际的:把它当工具用,体验怎么样?
这是 Pi 最硬核的差异化。Pi 的系统提示词 + 工具定义加起来不到 1,000 个 token。对比 Claude Code 的数万 token,差距不是一点半点。
为什么这件事重要? 上下文窗口是 Agent 最稀缺的资源。固定指令占得越少,留给你的代码、你的项目上下文的空间就越多。而且 Pi 不会在你背后偷偷注入任何东西——所有 prompt 源码公开可见,你甚至可以用 SYSTEM.md 文件把整个系统提示词替换掉。
技能(Skills)采用渐进式披露:只在被调用时才加载,不会预加载进每一个会话。你可以拥有一座丰富的能力库,而不必为用不上它们的会话付上下文开销。
Pi 对 Agent 操作的可见度不做任何妥协。你能看到模型收到的每一条消息、模型做每一个工具调用的完整输入输出、跨会话的完整成本追踪、以及会话的 HTML/JSON 导出。
"这有什么了不起的?"如果你用过其他编码 Agent,你可能经历过:Agent 做了一个奇怪的决定,你想知道它为什么这样做,但你看不到它"看到"了什么。在 Pi 里,没有这种黑箱。
Pi 支持 30+ 家 LLM 供应商(v0.80.2 源码 KnownProvider 枚举实际有 35 个,含区域变体如小米 4 个、Moonshot 2 个;去重后独立品牌约 27 个):Anthropic、OpenAI、Google、Azure、Bedrock、Mistral、Groq、Cerebras、xAI、Hugging Face、Kimi、MiniMax、OpenRouter、Ollama、DeepSeek、智谱、小米、Together、Fireworks 等等。
更重要的是,你可以在会话中途切换模型——用 /model 或 Ctrl+L。比如用 Claude 做复杂推理,然后切到 MiniMax 做简单文本处理省钱。pi-ai 库在底层处理了跨供应商的上下文交接(思考轨迹转换、供应商特定签名 blob 的回放等),虽然本质上有损,但比大多数工具"切换等于重新开始"的做法要好得多。
Pi 把会话存成树结构(DAG,有向无环图),而不是线性日志。用 /tree 跳到任意历史消息,从那里分叉出一个新分支继续探索。所有分支活在同一个文件里,不用开十个终端窗口。
这在调试时尤其有用——你可以在同一个起点尝试三种不同的修复方案,而不必担心"回不去了"。
Pi 默认运行在"YOLO 模式"——Agent 不经审批弹窗就直接执行动作。
这听起来危险,但 Mario 的论点是:基于审批的安全措施会让用户疲劳("弹窗疲劳"),最终要么被整体禁用、要么沦为看都不看就机械点同意的"安全表演(security theater)"。他建议以容器化作为恰当的安全边界。如果你确实需要审批流程,可以用大约 50 行扩展代码自己实现——框架提供了所有必要的钩子。
然后在任意项目目录里运行 pi。设一个 ANTHROPIC_API_KEY 环境变量,或者用 /login 完成认证,就可以开始了。
官方教程里默认让你设 ANTHROPIC_API_KEY,但实际项目里你大概率想用的是国内的智谱、DeepSeek、Kimi、Qwen 之类。这些不可能靠一个环境变量搞定——你需要告诉 Pi:base URL 在哪、用哪种 API 协议、模型 ID 叫什么、上下文窗口多大。
Pi 的解法是一个本地 JSON 配置文件:~/.pi/agent/models.json(Windows 下是 C:\Users\<你>\.pi\agent\models.json)。文件由 ModelRegistry.create()(repo/packages/coding-agent/src/core/model-registry.ts#L367) 在启动时自动读取,不需要任何命令行参数。
一个真实例子:
拆开看几个关键字段:
配置完之后怎么用? 三种方式:
models.json 还支持两种进阶用法(本教程不展开):用 modelOverrides 给内置 provider 的某个具体模型打补丁(比如改 baseUrl 指向自部署网关);用 compat 字段处理非标准接口的兼容性问题(比如某些网关需要特殊的 max_tokens 字段名)。schema 的完整定义在 model-registry.ts:158-218(repo/packages/coding-agent/src/core/model-registry.ts#L158-L218)。
第二个身份:Pi 是学习"怎么构建一个生产级 Agent"的绝佳教材。
很多 Agent 框架动辄几万行代码,光是搞清楚启动流程就要读几十个文件。Pi 的核心循环只有几百行,但它的设计质量一点都不"简陋"——它在 TerminalBench 基准测试中排名第二(使用 Claude Opus 4.5),仅次于 Terminus,尽管它缺少 MCP、子 Agent、计划模式等功能。
这意味着你可以在有限的时间内真正"读完"一个高质量 Agent 的全部核心代码。 这种事对 Claude Code 来说是不可能的,对 LangChain 也是不可能的。
本教程(插图版)目前已发布 10 章,前 6 章建立核心理解,后 4 章进入进阶工程议题:
| 章节 | 主题 | 核心问题 | 难度 |
|---|---|---|---|
| 第 1 章 | 开篇总览 | Pi 是什么?为什么值得学? | 入门 |
| 第 2 章 | 项目结构与分层架构 | 四个包怎么分工?为什么这样分层? | 入门 |
| 第 3 章 | Agent Loop | 怎么让 LLM 反复思考和行动? | ★ 核心 |
| 第 4 章 | 模型调用 | 怎么用一套代码调 30+ 家模型? | ★ 核心 |
| 第 5 章 | 工具系统 | 工具怎么定义、验证、执行? | ★ 核心 |
| 第 6 章 | 消息系统 | 对话历史怎么表示和传递? | ★ 核心 |
| 第 7 章 | 事件驱动架构 | 为什么需要事件? | 进阶 |
| 第 8 章 | 上下文工程 | 怎么让有限窗口装下无限对话? | 进阶 |
| 第 9 章 | 上下文压缩 | 对话太长怎么办? | 进阶 |
| 第 10 章 | 会话管理 | 会话怎么存、怎么恢复、怎么分叉? | 进阶 |
阅读建议:前 6 章建议按顺序通读,它们是理解 Pi-Agent 运行机制的基础。第 7 章起可按需跳读,每章相对独立。
每一个章节都会回答三个层次的问题:是什么(概念)、怎么做(源码分析)、为什么这样做(设计取舍)。
看一个"什么都做了"的框架,你只能学到"他们做了什么"。看一个刻意什么都不做的框架,你才能学到"做 Agent 到底需要什么"。
Pi 官网的 "What we didn't build" 章节是一份倒过来的宣言。竞争对手在罗列功能,Pi 在罗列舍弃。每一次舍弃背后,都有清晰的工程理由:
| Pi 不做的 | 为什么不做 | 替代方案 |
|---|---|---|
| MCP 支持 | MCP 服务器(如 Playwright MCP)会在会话开始灌入 13,700+ token 的工具描述 | 带 README 的 CLI 工具,Agent 按需读取 |
| 子 Agent | 增加复杂度,降低可观察性 | tmux 多实例,或专用扩展 |
| 权限弹窗 | 导致"弹窗疲劳",沦为安全表演 | 容器化隔离,或用扩展搭审批流程 |
| 计划模式 | 计划写到 markdown 文件里更持久、可复用 | 写 plan.md 文件 |
| 后台 bash | tmux 已经解决了这个问题 | 用 tmux |
| 内置待办 | TODO.md 文件更灵活 | 用 markdown 文件或自建扩展 |
这些取舍是理解 Pi 设计哲学的关键,也是学习 Agent 设计时最有价值的思考素材。
第三个身份:Pi 是一套可以独立复用的 SDK,让你在它的基础上构建自己的 Agent 应用。
回看第二节那张四层架构图,你会发现 pi-tui 是和 pi-agent-core 并排画的——它不在堆栈链上,而是 coding-agent 在交互模式下才用到的"侧依赖"。所以从 SDK 复用角度,Pi 实际是一条三层堆栈(pi-ai → pi-agent-core → pi-coding-agent),加上一个正交的终端 UI 库(pi-tui)。堆栈三层每层都可独立使用,UI 库也可独立使用——但它解决的是与 Agent 无关的另一类问题。
Layer 1: pi-ai — 只管调模型
pi-ai 不依赖任何 Agent 概念。你可以在任何需要调 LLM 的项目里用它——聊天机器人、文档分析、代码审查工具、甚至和 Agent 完全无关的应用。它支持 30+ 供应商、流式输出、跨供应商上下文交接、token 成本追踪、以及浏览器端运行。
Layer 2: pi-agent-core — 只管跑循环
pi-agent-core 依赖 pi-ai,但不依赖 pi-coding-agent 或 pi-tui。你可以用它构建任意类型的 Agent——不限于编码场景。数据分析 Agent、客服 Agent、自动化测试 Agent——只要是需要"模型思考 → 调工具 → 看结果 → 再思考"循环的场景,都可以用。
Layer 3: pi-coding-agent — 完整的 CLI + SDK
这是堆栈的最顶层,把下面两层组装成一个完整的编码 Agent 产品。同时也暴露出 SDK 接口,让你以"无头"(headless)模式在自己的应用中嵌入 Agent:
侧库: pi-tui — 一个与 Agent 无关的终端 UI 库
把 pi-tui 单独拿出来说,是因为它有个特别的属性:完全独立于 Pi 的 Agent 体系。它的 package.json(repo/packages/tui/package.json) 只依赖 get-east-asian-width和 marked(markdown 解析)两个包,源码里零处 import 来自 @earendil-works/pi-* 的兄弟包。反倒是 coding-agent 单向依赖它(比如 list-models.ts:6(repo/packages/coding-agent/src/cli/list-models.ts#L6) 从 pi-tui 引入 fuzzyFilter)。
pi-tui 是 Mario 的老本行(libGDX 游戏引擎作者)的作品,约 12000 行代码实现了:
它有什么用? 跟 Agent 没关系——任何需要终端交互界面的 Node.js 程序都能用:CLI 工具、交互式 dashboard、TUI 游戏、自定义 REPL。如果你曾经觉得 blessed/ink 要么太重要么太抽象,pi-tui 是一个值得读源码的极简替代品。
为什么会出现在 Pi 里? 因为 Pi 选择"终端外壳"形态(见第二节),就必须自己解决终端渲染问题。Mario 没用任何现成 TUI 库,而是按游戏引擎的思路重写了一个。这个"副产物"反而成了 Pi 最容易脱离 Pi 单独复用的部分——它根本不在乎你是在调 LLM 还是在做别的事。
Pi 的扩展系统具备热重载能力——当 Agent 修改了一个扩展文件,改动立即生效,无需重启会话。这催生了一种强大的模式:可以让编码 Agent 来修改和增强自己的能力。
扩展可以实现:
这五种定制杠杆(扩展、技能、提示词模板、主题、Pi Package),本质上提供了从"用 Pi"到"改造 Pi"的平滑升级路径。
| 模式 | 用途 | 示例 |
|---|---|---|
| 交互模式 | 日常编程的经典 TUI | pi |
| print/JSON 模式 | 脚本和 CI/CD 流水线 | pi -p "explain this code" |
| RPC 模式 | 通过 stdin/stdout 交换 JSON | 集成进非 Node.js 程序 |
| SDK 模式 | 嵌入自己的应用 | createAgentSession() |
这种多模式设计意味着 Pi 可以从"开发者手边的工具"无缝演进为"生产系统中 Agent 能力的提供者"——你不需要在项目成长后换一套框架。
OpenClaw 等项目已经在生产环境中使用 Pi 的 SDK,把每一个 Agent 实例跑在 Pi 上。Pi Package 可以通过 npm 或 git 分发,生态正在形成。
理解 Pi 最好的方式,是看它的对立面。
Claude Code 代表"全包"路线:内置计划模式、子 Agent、MCP、权限弹窗、待办追踪——一艘功能齐全的"飞船"。系统提示词数万字,功能持续膨胀,用户被推送着适应工具。
Everything Claude Code(214K+ Stars)则把这种哲学推向极致:数百条现成命令和 Agent 打包在一起,用户从"满"开始,慢慢删。
Pi 代表相反的轨迹:从"空"开始,让你来填。 核心极简,扩展随心。工具适应你的工作流,而不是强迫你适应工具的设计。
这两种哲学没有绝对的对错。但如果你是一个"想知道 Agent 到底在干什么"的人,Pi 大概率更适合你。
Pi 是一个"三位一体"的项目:
但最重要的是,Pi 证明了做减法是一种有竞争力的产品立场。在一个正朝着"全包"狂奔的赛道里,"我不需要的,就不会被构建"这句话本身,就是一项真正的功能。
版本说明
本文档系列基于 Pi v0.80.2 编写。代码分析以 repo/packages/ 中的实际源码为准。官方仓库已从 badlogic/pi-mono 迁移至 earendil-works/pi。