README
Pi Code Agent 深度剖析
一套从 0 开始写的 Pi 学习文档:先说清「是什么、怎么用」,再拆「为什么能这样做」,最后落到「怎么接进自己的东西」。
写作用源:npm 包
@earendil-works/pi-coding-agent@1.0.0的docs/(41 篇官方文档)与examples/,加上包内package.json、dist/的实际结构。每篇正文末尾都有「溯源」列出实际读过的官方文件,可逐条回核。
项目地图
01-入门/ 装上、会用、接上一个模型
02-核心机制/ 代理循环、会话树、压缩、工具与安全
03-扩展体系/ 写扩展、技能/模板/主题/包、MCP 与 CodeMode
04-集成/ 把 Pi 嵌进别的程序
05-配置与自定义/ 所有开关、环境变量、快捷键、自建供应商
06-源码与设计/ 分层、数据流、为什么这么设计
| # | 文档 | 一句话 | 什么时候读 |
|---|---|---|---|
| 01 | 安装与首次运行 | 安装方式、认证、工作目录、第一次任务、常用 CLI 选项 | 刚装上 Pi |
| 02 | 交互模式与日常操作 | 输入语法(@file、!、!!)、斜杠命令、会话管理、导出与分享 | 每天在用 |
| 03 | 模型与供应商 | 订阅还是 API key、供应商清单、切模型与思考级别、额度与成本 | 接不上模型、想降成本 |
| 04 | 代理循环与上下文工程 | 一个 turn 的生命周期、上下文文件、技能按需加载、steering 与 follow-up | 想搞懂它到底怎么工作 |
| 05 | 会话文件格式与分支树 | JSONL 条目、父引用、活动分支、/tree 导航、fork 与 clone | 要写会话处理工具 |
| 06 | 上下文压缩与分支摘要 | 阈值触发、摘要当锚点、/compact、与 prompt cache 的关系 | 长任务总被截断 |
| 07 | 工具系统与安全边界 | 内置工具表、启用与排除、权限、路径保护、三种隔离档 | 担心它把机器弄坏 |
| 08 | 扩展开发与事件系统 | 扩展怎么加载、完整事件表、注册工具/命令/快捷键、自定义 UI | 想给它加能力 |
| 09 | 技能、提示模板、主题与包 | 四种资源的格式与放置位置、Pi 包的安装与分发 | 想沉淀自己的用法 |
| 10 | MCP 与 CodeMode | MCP 的本地/远程接入与工具命名、CodeMode 用脚本代替逐个工具调用 | 要接外部工具、要省上下文 |
| 11 | 集成方式:SDK、CLI、JSON 与 RPC | 四种模式对比、JSONL 严格帧规则、RPC 命令表、SDK 会话、消息类型 | 要写客户端 / IDE 插件 |
| 12 | 配置体系与自定义供应商 | 全部 settings、环境变量、快捷键、models.json、provider 与虚拟模型扩展 | 要调参、要接自建端点 |
| 13 | 源码结构与设计思想 | 包分层、核心对象、请求数据流、六条设计原则、构建与调试入口 | 要读源码、做二次开发 |
三条阅读路径
只想用好它(约 1 小时):01 → 02 → 03 → 07 →(需要时)09。 把工具与权限规则看清楚,比多背命令有用。
要给它写扩展(照 examples/extensions/ 写):01 → 04 → 08 → 09 → 10 → 12 → 13。
先懂事件与上下文怎么装配,再决定把逻辑放在扩展层还是配置层。
要把它接进自己的程序(客户端 / IDE / 自动化):04 → 05 → 06 → 11 → 13。 不先读懂会话树与压缩,写出来的客户端一定会丢上下文。
十条最值得先记住的结论
- 上下文是推导出来的,不是维护的:模型看到的历史由会话树的活动分支重建;压缩只是插入一条摘要条目,历史条目仍在会话文件里。
agent_end不是终点:自动重试、溢出恢复、压缩重试、排队消息都可能继续,要等agent_settled。- JSON / RPC 的流只能按 LF 切:不要用 Node
readline(它会把U+2028/U+2029当换行),并且必须持续读 stdout,否则会在管道缓冲满时堵住 Pi。 prompt成功只代表命令被处理:data.disposition === "handled"时根本没起运行,别去等 settle;发 prompt 前先订阅事件。- RPC 的
bash输出在下一个prompt才进模型上下文,不是立即生效;除非显式设了excludeFromContext。 defaultTools是「纯名字替换、+/-增减」:["read","bash"]只留这两个,["+codemode"]是在默认之上加;--tools则不认+/-。- 权限不靠模型自觉:项目信任只控制加载哪些项目资源,工具与扩展始终用 Pi 进程自身的系统权限;真要隔离就得降权限、整包进容器,或只用受限的内置工具集。
- 上下文省不下就换手段:技能只在被调用时展开全文,MCP 可以按需折叠,工具太多时用 CodeMode 改成「写代码调工具」。
- 配置分两层:用户层在
~/.pi/agent(可用PI_CODING_AGENT_DIR改),项目层在.pi/且靠信任解锁;项目设置能覆盖用户设置,但资源列表是合并。 - 想改它的行为,先问自己落在哪一层:偏好/开关 →
settings.json;可复用知识 → 技能或提示模板;新工具/拦截/UI → 扩展;新模型端点 →models.json或 provider 扩展;只有要改运行时语义才碰源码。
三条容易踩的坑
- 别把 stderr 当协议数据解析:RPC 的 stdout 才是协议,诊断信息在 stderr;子进程意外退出、启动失败、超时都得客户端自己处理。
- 仓库改动与文档同步:这一系列文档写的是 Pi v1.0.0 的行为;升级后先看官方
CHANGELOG.md与对应核准页,再改本文。 - 别求「一次问答就完事」的接口:Pi 的一次提交可能包含多轮模型请求与多次工具调用;客户端要按事件流做状态机,而不是等一个返回值。
本项目的写作惯例
- 只用中文叙述,保留 API / 字段 / 命令 / 路径 / 配置键的英文原文。
- 每篇先给一段「读这一篇的价值」,再说事实,最后给「溯源」。
- 不将推测写成结论:官方文档没写的部分会明确标为判断(例如第 13 篇的分层解读)。
- 新增/修改章节时同步更新本页索引,保证从
README.md能走到每一篇。
文章版本
- 对象版本:
@earendil-works/pi-coding-agent@1.0.0(engines.node >= 22.19.0)。 - 文档篇数:13 篇(01–13),分 6 个目录。
- 覆盖官方文档:
quickstart、cli、usage、providers、models、how-pi-works、session-format、sessions、compaction、security、extensions、tui、skills、prompt-templates、themes、packages、mcp、codemode、sdk、json、rpc、rpc-commands、rpc-extension-ui、message-types、cli-integration、settings、configuration、environment-variables、keybindings、custom-provider、virtual-models、containerization等。