浅尝Pi Coding Agent
我其实是 OpenCode 的用户。
没用 Claude Code 或 Codex,一是原生模型绑定不便,加上 CC 对中国大陆的严苛让人心里有芥蒂;二是 OpenCode 开源、多模型支持、Agent/Subagent/Skill 也够用。这些让我很长时间都是 OpenCode 的用户,现在也是。
但从今年开始,总在 B 站刷到一个新工具:Pi。之前只知道它开源、精简、自定义强。但它有种魔力——就像爱旅行的人得知了一片新大陆,可以按捺住暂时不去,但终有一天会上岸看看。
最近终于作为初学者体验了一把。这篇文章,就是我的分享。
一、一个"啥都不带"的家伙
先看几个数字。
系统提示词不到 1,500 个 token。 Claude Code 约 15,000,Codex 约 12,000。你跟 CC 说句"在吗",它大脑里已塞满了代码索引、测试指令、Git 规范。
开箱只有 7 个工具。 read、write、edit、bash、grep、find、ls。没了。
核心源码 5 个文件,约 1,500 行 TypeScript。
这不是穷酸,是刻意为之。Pi 的设计哲学:做一个极简、稳健的核心,扩展的决定权还给用户。 它有意不内置 MCP、子 Agent、权限弹窗、计划模式——不是"做不到",是"不做"。全部可通过 Extension 或 Skill 自己加。
如果说 Claude Code 是预制菜——开包装即食——那 Pi 就是自己搭火锅。给你锅底和炉子,涮什么你决定。代价是自己动手,收益是做同样的事 Token 消耗只有 CC 的 30-35% 。这也是为什么 OpenRouter 消耗榜上,这个"啥都不带"的工具排第六——前面是 Anthropic、OpenAI 这种巨头,后面才是 Claude Code。
二、装好就能用
安装就一条命令(需 Node.js):
npm install -g --ignore-scripts @earendil-works/pi-coding-agent
进项目目录,pi 启动,/login 登录。已有 API Key 直接设环境变量——Pi 支持 15+ 个 LLM 提供商。
进来第一反应:"我在跟谁说话?" Pi 跟 CC 有个根本区别——没有独立的"Agent"实体。对话对象就是你当前选的模型。Pi 只是中间人:拼上下文 + 工具定义 → 发给模型 → 执行工具调用。
切换模型很方便:/model 面板、Ctrl+L 快捷键、Ctrl+P 循环收藏。切换后对话不中断。我的常用策略:粗活用 DeepSeek,精调切 Claude,一个对话里来回切。
⚠️ 一个坑:树形回退不回退文件。 /tree 管的是对话上下文树,磁盘上改过的代码依然在。关键操作前先 commit。
三、它脑子里到底装了啥——最值得懂的东西
3.1 四层架构
你装的 pi-coding-agent 其实由 4 个独立 npm 包拼成:
图:Pi 的四层架构与依赖关系
pi-ai(模型通信层) :统一 LLM API,封装 15+ 提供商。换模型只动这层,核心无感。pi-agent-core(Agent 运行时) :核心循环引擎,7 个工具在这里注册执行。独立于 UI,可被 SDK/RPC/脚本调用。pi-coding-agent(用户交互层) :敲pi启动的那个,把核心包装成 CLI。pi-tui(终端 UI 层) :纯差异渲染框架,不含业务逻辑,可复用。
3.2 上下文组装:模型每轮看到了什么
每次调模型前,Pi 会组装一个完整上下文,由 6 个来源分层叠加:
图:Pi 每次调模型前从 6 个来源组装上下文
实际运行中形成 5 层叠加,从通用到具体:
第 1 层:Base agent behavior ← Pi 核心,所有项目通用
第 2 层:Global user instructions ← ~/.pi/agent/ 下的全局设定
第 3 层:Project instructions ← 当前项目的 AGENTS.md
第 4 层:Skill/workflow instructions ← 当前激活的 Skill 注入
第 5 层:Current user request ← 你本轮说的这句话
上层不覆盖下层,而是叠加。 这就是 Pi 能"保持通用,同时在不同代码库里行为得当"的机制。对比 Claude Code:CC 把大量行为硬编码进系统提示词,Pi 把同样的行为下放到 AGENTS.md 和 Skill——由你决定注入什么。同一个 Pi,在 A 项目用 uv 跑 Python,在 B 项目走完全不同发布流程——核心代码零修改。
3.3 Session:会话是怎么存的
Pi 的全部会话存在 ~/.pi/agent/sessions/ 下,每个会话一个 JSONL 文件——每行一个 JSON 对象。关键字段:
type:消息类型(用户消息、模型回复、工具调用等)id:唯一标识parentId:父消息 ID
就是 id 和 parentId 两个属性,在一个平铺文件里构建出了一棵会话树。
图:JSONL 文件中 id 和 parentId 构建出的会话树
/tree 命令可随时查看这棵树,在分叉点间跳转。分叉后两个分支独立发展。
⚠️ 重申:/tree 回退的只是对话上下文,不回退文件系统。配合 git 才是完整的回退方案。
长会话由 Compaction 处理:逼近上下文上限时自动压缩——保留目标、决策点、改动文件;压缩掉中间探索和冗长输出。模型拿摘要,但关键信息不丢。
四、让它自己给自己写功能,当场就能用
这一章讲 Pi 最让我上头的东西:它能在运行中修改自己。
我想要一个 /diff 命令,列出工作区修改过的文件。在别的工具里得翻文档、写脚本、配环境。在 Pi 里,就说了一句话:
"帮我写一个 /diff 扩展,通过 git diff 列出修改过的文件。"
然后:
我说需求
↓
Pi 自己读 node_modules 里的扩展文档
↓
创建扩展文件
↓
我敲 /reload → /diff 生效
全程没退出终端,不到一分钟。
Pi 自己写的代码长这样(核心部分):
图:Pi 自己写的 /diff 扩展——自动定位目录、两遍查、边界处理
它知道用 ctx.cwd 定位项目目录,做了工作区/暂存区两遍查。这是一个 Pi 自己写的、考虑了边界情况的扩展。
这种感受很奇妙。OpenCode 给 Agent 配命令像"装工具栏按钮"——功能预定义。Pi 的 Extension 是给它装新器官——而且这个器官是 Agent 自己长出来的。你描述需求,它读文档、写代码,/reload 生效。无限可能,自由搭配。 这在 OpenCode 里是没有的。
五、装点插件吧,但别太多(我还在探索)
Extension 给 Agent 新器官,Skill 给 Agent 操作手册。
Skill 核心创新是渐进式披露:启动时只写名称和描述进系统提示词(极省 Token),完整指令任务匹配时才加载。加载分两层——原生层(~/.pi/agent/skills/,自动发现)和桥接层(settings.json 显式挂载,可复用 OpenCode 的 Skill)。
社区有 4000+ 包。以下是网上看到的推荐,我自己还没用太多,仅供参考:
图:社区推荐扩展包(仅供参考,还在持续探索中)
⚠️ Pi 的扩展以完整系统权限运行,可以执行任意代码。安装第三方包前最好先看一眼源码。社区的经验法则是:装得越少越好,只保留真正用得上的。
六、不是更好,是不一样
写了这么多,不是要说服你换工具。Pi 和 Claude Code / Codex 不是替代关系。
图:不是 Pi 更好,是 Pi 不一样
简单说:写代码选 Claude Code / Codex,做事情选 Pi。 Pi 的真正差异在于——为你的工作流量身定制,而不是你去适应工具预设的工作流。
收尾:没想清楚,但很愿意继续用下去
写到这里,我想诚实地说一件事:我还没有想清楚要不要从 OpenCode 切换到 Pi。
Pi 给我的感受是更极客的、更有无限可能的、更能实现想象力的。那种"说一句话,它就自己长出功能"的体验,那种 id 和 parentId 两根线就织出会话树的优雅,都让我很兴奋。
但 OpenCode 已经能比较好地满足我的需求了。我还有必要切换过来吗?这是我自己的困惑,可能也是很多人的困惑。
但我确定一件事:使用 Pi 让我找回了第一次用 Trae、第一次用 OpenCode 时的那种兴奋。 你发现了一片新大陆,还没想清楚要不要移民,但已经迫不及待想多走几步。
Pi 不问我"你学我怎么用",它问"你要什么,我长出来"。
这篇文章不是答案。只是一个 OpenCode 用户在 Pi 的新大陆上走了几步之后,匆匆写下的旅行笔记。至于要不要搬家——我再走走看。
最后推荐一篇博客:Alejandro AO 写的 How Pi Works: Agent Architecture, Tools, TUI, and Skills。如果你读完这篇还想深入了解 Pi 的架构细节,这篇博客是目前我见过的最清晰的解读,本文中关于上下文组装和 Session 机制的很多理解都来自它。
参考:Pi 官网 pi.dev / Pi 源码 github.com/earendil-works/pi / 社区包目录 pi.dev/packages
每次一推广,欢迎关注我的公众号“我AI了”