Pi 1.3.0:介绍与整体架构
本文件回答三个问题:Pi 是什么?内部怎么分层?关键设计取舍是什么? 基于学习区版本 v1.3.0(
71023aec,2026-10-15 发布)。路径均相对$PI_SRC。 用法:配合学习路线开头的「七块」总表阅读;每个学习阶段深入其中一块。
一、Pi 是什么
跳转到“一、Pi 是什么”README 的原话:“Pi is a minimal, extensible agent harness that you can make your own.”
逐词拆解这句话:
- agent harness(代理挽具):Pi 不是模型,也不是编辑器。它负责把「模型、工具、上下文、会话」编排成一个能自动干活的系统——模型是发动机,Pi 是传动系统和底盘。
- minimal(极简核心):核心保持小而稳。连 MCP、工具搜索、codemode 这类别家当核心功能做的东西,Pi 都尽量以扩展形态内置(见
packages/coding-agent/src/extensions/下的 codemode、mcp、tool-search、llama)。 - extensible(可扩展):扩展是进程内 TypeScript 模块;技能、提示模板、主题按需加载;可打包为 Pi packages 经 npm / git 分发。
- make your own:官方明确跳过 sub-agents、plan mode 这类功能——不是做不了,而是这类能力更适合由你或社区按自己的方式长出来(“Adapt Pi to your workflows, not the other way around.”)。
五种使用形态(同一个引擎、同一套会话机制,详见阶段 7):
| 形态 | 入口 | 适合 |
|---|---|---|
| 交互模式 | 终端直接运行 pi |
人机结对:流式输出、工具块、斜杠命令 |
pi -p "任务" |
一次性执行拿结果、脚本化 | |
| JSON | pi --mode json |
stdout 输出完整事件流,供程序解析 |
| RPC | pi --mode rpc |
stdin/stdout JSONL 协议,外部进程双向控制 |
| SDK | TypeScript 库(@earendil-works/pi-coding-agent) | 进程内嵌:建会话、发任务、收事件 |
二、部件全景:任何 agent 都是七块
跳转到“二、部件全景:任何 agent 都是七块”学习清单的总表在这里补上「在 Pi 里的位置」一列:
| 部件 | 要回答的问题 | Pi 中的对应 | 阶段 |
|---|---|---|---|
| 循环 | 一轮怎么推进?何时调模型、执行工具、停? | packages/agent + coding-agent 会话编排 |
2 |
| 上下文 | 每次发给模型什么?怎么存、压、找回来? | 会话树 JSONL、压缩、系统提示词 | 3 |
| 工具 | 模型能做哪些动作?怎么执行、校验、展示? | packages/coding-agent/src/core/tools |
4 |
| 模型接入 | 怎么把多家厂商统一成一套接口?凭据怎么管? | packages/ai + 模型目录 |
5 |
| 扩展 | 能力怎么长出来?核心与生态怎么分工? | 扩展 / 技能 / MCP / codemode | 6 |
| 界面 | 同一个引擎怎么同时服务人、脚本、程序? | TUI / print / JSON / RPC / SDK | 7 |
| 工程 | 怎么让改动可靠、可持续演进? | 测试(faux provider)/ check 流水线 / 发布流程 | 8 |
三、分层架构:每一层到底在做什么
跳转到“三、分层架构:每一层到底在做什么”先记住一个总原则:Pi 把「和人交互、安排任务、循环调用模型与工具、连接模型厂商」拆成了不同的层。 换界面、换模型或增加工具时,只需改动对应的一层,不必推倒重来。
3.1 先看简化图:任务向下,事件向上
跳转到“3.1 先看简化图:任务向下,事件向上”┌──────────────────────────────────────────────────────────────┐│ 入口层:交互 TUI / print / JSON / RPC / SDK ││ 负责接收输入、显示结果;不负责决定模型该做什么 │└───────────────────────────┬──────────────────────────────────┘ │ ① 输入:文字、图片、命令┌───────────────────────────▼──────────────────────────────────┐│ 应用层:coding-agent(产品本体) ││ ││ AgentSession 一次任务的「总调度」 ││ 整理输入、检查认证、排队、压缩、启动与收尾 ││ ││ SessionManager 会话「账本」 ││ 读写 JSONL 会话树,按活动分支重建上下文 ││ ││ 工具 / 扩展 / 技能与提示模板 / 模型选择与凭据 │└───────────────────────────┬──────────────────────────────────┘ │ ② 历史消息 + 系统提示词 + 工具声明┌───────────────────────────▼──────────────────────────────────┐│ 引擎层 ││ agent:循环执行「请求模型 → 执行工具 → 再请求模型」 ││ ai:把不同厂商的请求格式和流式回复统一成一套内部格式 │└───────────────────────────┬──────────────────────────────────┘ │ ③ 统一格式的请求┌───────────────────────────▼──────────────────────────────────┐│ 模型供应商:Anthropic / OpenAI / Google / … ││ 真正生成回答的地方 │└──────────────────────────────────────────────────────────────┘
事件沿反方向返回:模型回复片段、工具开始/结束、消息落盘……最终由入口层决定怎么显示,或交给外部程序处理。看这张图,只需抓住三件事:
- 向下:一次任务被逐层整理成模型能处理的请求。
- 向上:执行过程中的状态变化以「事件」返回,界面和程序都消费它。
- 旁边:会话账本持续记录发生了什么,并在下一次请求前提供历史。
3.2 四层各自负责什么
跳转到“3.2 四层各自负责什么”| 层 | 你可以把它想成 | 负责 | 不负责 |
|---|---|---|---|
| 入口层 | 前台 | 收输入、显示流式输出和工具进度 | 决定如何循环、如何压缩历史 |
| 应用层 | 项目经理 | 把一次任务安排妥当:会话、工具、扩展、资源、认证 | 具体调用哪家模型、模型内部怎么运行 |
| 引擎层 | 执行队 + 翻译 | 推进循环、执行工具、统一模型接口 | 终端长什么样、用户按了哪个快捷键 |
| 供应商 | 外聘专家 | 根据请求生成文本或工具调用 | 记住上一次请求;保存 Pi 的会话历史 |
表格里的「不负责」很重要。分层清不清楚,主要看边界,而不是看名词多不多。
3.3 应用层:两个最容易混淆的对象
跳转到“3.3 应用层:两个最容易混淆的对象”同属应用层,AgentSession 和 SessionManager 经常被混为一谈。可以这样区分:
| 对象 | 像什么 | 具体管什么 |
|---|---|---|
AgentSession |
一次任务的调度员 | 判断扩展命令、处理输入、展开技能/模板、流式时排队、检查认证、压缩检查、触发扩展事件、启动和收尾一次运行(run) |
SessionManager |
档案馆管理员 | 把消息和状态追加到 JSONL;维护 id/parentId 树;确定活动分支;生成投影;读写标签、模型切换等记录 |
一句话:AgentSession 管「这次任务怎么跑」,SessionManager 管「发生过的事情怎么存、怎么取」。
真正的「问模型—跑工具—再问模型」循环不在这两个对象里,而在引擎包的 agent 中。
3.4 引擎层:循环与翻译
跳转到“3.4 引擎层:循环与翻译”agent:循环引擎。 它只关心消息、回合(turn)、工具调用、事件,不知道外面是终端、脚本还是另一个程序。也正因如此,同一个引擎才能同时服务五种使用形态。ai:模型适配层。 Anthropic、OpenAI、Google 的鉴权方式、请求字段、流式事件格式各不相同;ai把这些差异收在自己的 provider 适配器里,向上只交出统一格式的文本增量、思考增量、工具调用增量、结束和错误事件。- 模型目录也由
ai提供:上下文窗口、价格、能力标记等。它让「有哪些模型、各自能做什么」不必硬编码进循环。
如果不熟悉 provider:在这里可以把它理解成「某一家模型厂商的接入插件」。Pi 的业务代码只面对统一接口,不直接写满 if Anthropic ... else if OpenAI ...。
3.5 入口层:五张门,同一个内核
跳转到“3.5 入口层:五张门,同一个内核”交互 TUI、print、JSON、RPC、SDK 看起来差别很大,但做的事都只有两件:
- 把输入交给同一个会话系统;
- 消费同一套事件流,并决定怎样显示或转发。
因此,你在终端里看到的行为,和脚本通过 JSON/RPC/SDK 得到的行为,来自同一套引擎与会话机制。print 只保留最终答案,JSON 输出完整事件,RPC 允许外部进程双向控制,SDK 则把会话嵌入 TypeScript 程序。这部分到阶段 7 再展开。
3.6 图外的辅助部件
跳转到“3.6 图外的辅助部件”| 部件 | 作用 | 需要时再记 |
|---|---|---|
tui |
终端差分渲染 | 交互模式使用 |
mcp |
连接外部 MCP 工具服务器 | 外部工具生态 |
codemode |
在沙箱里运行 JS,通过注入的工具完成复杂操作 | 工具编排 |
tool-search |
在工具较多时寻找合适的工具 | 扩展形态内置 |
chord → durable → env |
插件宿主、持久化运行时、SSH 远程执行 | 平台化运行时,独立演进 |
telemetry / evals |
遥测数据格式、评测框架 | 工程与测试 |
这些部件不是理解主链路的入口。初读时只要知道它们「按需接入」,不要被包名打断主线。
3.7 两条贯穿全系统的规则
跳转到“3.7 两条贯穿全系统的规则”- 会话是账本。 文件在
~/.pi/agent/sessions/--<工作目录>--/*.jsonl;里面是一棵可追加的树。当前所在的末端叫 leaf,从 leaf 回溯到根就是「活动分支」,下一次请求的历史从这条分支推导。 - 权限沿操作系统走。 Pi 不实现一个自制的细粒度沙箱;工具和扩展默认拥有 Pi 进程本身的系统权限。打开项目前先做信任决定;需要强隔离时,把整个 Pi 放进容器,而不是只给某个工具加一层假权限。
这两条规则会在第四、五章反复出现,先各记一句即可。
四、一条请求的完整旅程
跳转到“四、一条请求的完整旅程”这一章把第三章的图真正走一遍。代码名可以先跳过,只要每一步都能说出「谁把什么交给了谁」。
4.1 六个词,先弄清楚
跳转到“4.1 六个词,先弄清楚”| 术语 | 一句话解释 | 最容易误解的地方 |
|---|---|---|
| Prompt | 你交给 Pi 的任务文本(可能还带图片、文件引用) | 它只是新输入,不是模型这次看到的全部内容 |
| Run | 从提交这次输入,到 Pi 确认「不会再有自动工作」为止的一整段执行 | 一个 run 里通常有多个 turn |
| Turn | 一次「模型回复 + Pi 执行它要求的工具」的完整回合 | 模型只说话、没有调用工具时,也算一个 turn |
| Context | 本次请求真正发给模型的全部内容:历史、系统提示、工具说明、当前输入等 | 它不等于会话文件;文件里有很多不进上下文的东西 |
| Projection | 从当前活动分支按规则整理出的「模型可见的对话历史」 | 它不是改写原文件,而是每次临时算出来的视图;完整上下文还要再加上系统提示词、工具声明和当前输入 |
| Event | 执行过程中发出的状态通知,如回复片段、工具开始/结束、消息落盘 | 不是日志附赠品;界面和外部程序就是靠它工作的 |
优先记住 run、turn、context、projection 这四个词,后面会反复出现。
4.2 从回车到答案:分阶段看
跳转到“4.2 从回车到答案:分阶段看”阶段 A:入口层收下输入
跳转到“阶段 A:入口层收下输入”你在输入框敲回车。交互界面只做一件事:把文本(以及可能的图片)交给 AgentSession.prompt()。它不自己猜模型,也不自己执行工具。
阶段 B:AgentSession 做「发送前检查」
跳转到“阶段 B:AgentSession 做「发送前检查」”prompt() 像总调度,依次处理:
- 扩展命令:输入以
/开头且命中扩展命令,就直接执行,不调用模型。 - 输入处理器:扩展可以拦截、改写甚至取消这条输入。
- 技能与提示模板:把
/skill:...或模板展开成真正的提示词。 - 流式排队:如果上一条回复还在流式输出,这次输入不会硬插进去,而是按类型放进 steer 或 follow-up 队列。
- 认证检查:确认已经选了模型,并且该 provider 有可用凭据;否则报错并提示登录。
这些检查都过了,才进入 _startRun() / _prepareRun(),准备真正启动一次 run。
阶段 C:准备本次 run
跳转到“阶段 C:准备本次 run”这一阶段做三件事:
- 压缩检查:如果历史已经接近模型上限,先用摘要压缩旧历史。
- 触发
before_agent_start:扩展可以在这里补消息、调整工具集或系统提示。 - 组装起始消息:把当前输入、待处理的下一轮消息和扩展注入的消息整理好,然后交给引擎的
Agent。
注意:这里交给 Agent 的是「这次要新增的消息」,不是整段历史。完整历史会在真正发请求前从会话账本重新算出来。
阶段 D:Agent 启动循环
跳转到“阶段 D:Agent 启动循环”Agent 收到起始消息后启动 runLoop。这个循环只有一条主线:
准备请求 → 请求模型 → 模型要调用工具吗? ├─ 要:执行工具,记录结果,回到「准备请求」 └─ 不要:结束本轮;若没有后续工作,结束本次 run「工具结果回来后自动再问一次模型」并不是某个工具的魔法,而是循环本身的设计。
阶段 E:重建本次上下文
跳转到“阶段 E:重建本次上下文”这是整条链路最值得慢下来的一步。真正发给模型之前,Pi 会按顺序做三件事:
- 找活动分支:从当前 leaf 沿
parentId回溯到根,得到这条对话路径。 - 生成投影:在分支上应用最新压缩检查点和上下文编辑,得到「这次应该让模型看到的对话历史」。
- 转换数据格式:把 Pi 内部的
AgentMessage[]经convertToLlm变成模型接口要求的Message[],再连同系统提示词和工具声明组成请求。
用一张小图表示:
会话文件(完整账本,只追加) └─ 活动分支(当前这条路径) └─ 投影(应用压缩/编辑后,模型可见的对话历史) └─ convertToLlm(内部格式 → 模型格式) └─ 系统提示词 + 工具声明 + 当前输入 └─ 发给模型两个词的区别:
- 投影决定「哪些内容留下、哪些被摘要代替、哪些被编辑」,是内容层面的整理;
convertToLlm只负责「把数据从 Pi 的格式翻译成模型 API 的格式」,不决定历史内容。
阶段 F:调用模型,边生成边显示
跳转到“阶段 F:调用模型,边生成边显示”引擎通过 ai 选择 provider,带上鉴权信息和模型参数发出请求。回复不是等全部生成完才回来,而是以事件流返回:
- 文本开始 / 文本增量 / 文本结束;
- 思考开始 / 思考增量 / 思考结束;
- 工具调用参数增量;
- 完整消息与错误。
界面看到 message_update 就能实时刷新。等一条完整消息结束时,message_end 会触发落盘:消息被追加进会话 JSONL。
阶段 G:有工具调用,就再开一轮
跳转到“阶段 G:有工具调用,就再开一轮”模型的回复里可能只有文字,也可能同时包含一个或多个工具调用。若有工具调用:
- 引擎校验并执行工具;
- 工具结果变成
toolResult消息,追加到上下文并落盘; - 循环回到阶段 E,重新从会话账本计算上下文;
- 模型看到工具结果,决定继续调用工具还是给出最终回答。
例如你让它修一个登录 bug,实际可能连续发生:
用户:修复登录页报错 → 模型要读文件 → Pi 读文件,返回内容 → 模型要搜调用点 → Pi 搜索,返回结果 → 模型要改代码 → Pi 修改,返回结果 → 模型给出最终说明(没有工具调用了)这就是为什么一次用户输入可能对应很多次模型请求和工具执行。它们都属于同一个 run,但分属多个 turn。
阶段 H:agent_end 不等于「彻底结束」
跳转到“阶段 H:agent_end 不等于「彻底结束」”普通的 steering / follow-up 会在底层 runLoop 内部先处理完;当没有工具调用、也没有待处理消息时,才发出 agent_end。但这不代表一定空闲,因为会话层还可能:
- 自动重试一次失败请求;
- 在上下文超限时压缩并重试;
- 在
agent_end处理器里排入新的工作。
只有等到 agent_settled,才表示「Pi 已经没有任何会自动继续的工作,现在真正空闲」。交互界面通常到这时才把控制权完全还给你。
4.3 把全过程压成一张时序图
跳转到“4.3 把全过程压成一张时序图”你按回车 │ ▼入口层 → AgentSession.prompt() ├─ 扩展命令?──────────────是──► 立即执行,结束 │ ├─ 输入处理 / 模板展开 / 排队 / 认证 ▼ _prepareRun() ├─ 必要时压缩 ├─ before_agent_start 扩展事件 └─ 组装起始消息 │ ▼ Agent.runLoop ◄──────────────────────────────┐ │ │ ▼ │ 从活动分支生成投影 │ │ │ ▼ │ convertToLlm → 系统提示 + 工具声明 → 请求模型 │ │ │ ▼ │ 模型回复 ──有工具调用?──是──► 执行工具 ─────┘ │ 否 ▼ agent_end │ ├─ 自动重试 / 压缩恢复 / agent_end 新工作?──是──► 继续运行 │ 否 ▼ agent_settled(真正空闲)一句话记住:AgentSession 把一次输入安排成 run;runLoop 每一轮都从会话账本重建上下文去问模型;模型要工具就执行后接着问,直到没有自动工作才停在 agent_settled。
4.4 四个常见误区
跳转到“4.4 四个常见误区”| 容易这样理解 | 更准确的理解 |
|---|---|
| 「会话文件里有 10 万字,模型每次就收到 10 万字。」 | 不会。模型只收到投影后的对话历史,再加上系统提示词、工具声明等;压缩过的旧内容由摘要代替,原文仍留在文件里。 |
| 「压缩就是把旧消息删掉。」 | 不删。压缩只是追加一个摘要检查点,后续投影用它代替旧消息;原始 entry 还在,之后仍可回溯。 |
「看到 agent_end 就可以继续输入了。」 |
这是底层循环结束,不是整个系统空闲;真正的空闲信号是 agent_settled。 |
| 「模型会记住上一轮。」 | Pi 每次都要把当前上下文重新发给模型;模型本身不保存这段会话,账本和投影由 Pi 负责。 |
完整细节见阶段 1(请求旅程、事件对照)、阶段 2(循环状态机、三个插口)与阶段 3(会话树、压缩与投影、系统提示词)。
五、六个关键设计取舍
跳转到“五、六个关键设计取舍”Pi 的很多设计初看有些「拐弯」,其实都在解决一个具体麻烦。下面每个选择都按同一顺序讲:不这么做会怎样 → Pi 怎么做 → 你得到什么、要付出什么。
5.1 小核心,能力放在扩展里
跳转到“5.1 小核心,能力放在扩展里”麻烦:如果每增加一个功能都往核心塞,核心会越来越难读、难改、难测试。
做法:核心只保留缺了就不能工作的东西:循环、会话、工具接口、模型接入。MCP、工具搜索、codemode 这类能力以扩展或内置模块的形式接入,可以按需启用。
结果:核心小,能力可替换、可组合。代价是扩展机制本身要设计周全;读源码时要分清「核心」和「随产品内置的扩展」。
可以把它想成操作系统内核和应用程序:内核不必内置所有软件,但必须提供稳定的进程、文件、网络接口。
5.2 会话是树,不是一条聊天记录
跳转到“5.2 会话是树,不是一条聊天记录”麻烦:如果聊天记录只能是一条从头到尾的数组,想回到旧消息重开、保留原文做压缩、查看某条分支都会很别扭;直接覆盖旧记录还可能破坏历史。
做法:每个 entry 都有 id 和 parentId,形成一棵只追加的树。当前所在的 leaf 决定活动分支;从旧位置继续聊天,就是在同一文件里长出新枝。压缩摘要和上下文编辑也各追加一条记录,不覆盖原消息。
结果:可回溯、可分支、可回放;写入时不必改写已有历史。代价是「读历史」不能直接顺着数组读,必须先找到活动分支,再生成投影。
5.3 模型请求无状态,上下文每次重建
跳转到“5.3 模型请求无状态,上下文每次重建”麻烦:模型不会替 Pi 保存整段会话;而 Pi 又会在历史中压缩、编辑。若把「原始记录」和「这次实际发送的内容」混在一起,就很难判断下一次到底该发什么。
做法:把两者彻底分开。每次请求前,Pi 都从活动分支现算一份投影:应用最新压缩检查点和上下文编辑,再经 convertToLlm 转成模型消息。压缩和编辑只记录「怎么改」,不覆盖原消息。
结果:任何一次请求都能从会话文件重新推导出来,压缩后仍可回到原文;代价是每次请求都要重新计算投影,相关逻辑必须非常可靠。
5.4 用事件流做统一接口
跳转到“5.4 用事件流做统一接口”麻烦:终端界面、脚本、外部程序都想知道 agent 正在做什么。如果每种界面各写一套调用逻辑,就会出现五套行为、五套 bug。
做法:引擎把所有状态变化发成事件;各种界面只是事件的消费者。TUI 负责绘制,print 只输出最终结果,JSON 把完整事件写成 JSONL,RPC 转发给外部进程,SDK 让 TypeScript 程序直接订阅。
结果:一套核心服务多种形态,调试时直接看原始事件流就能知道执行到哪一步。代价是事件格式必须稳定,消费者要正确处理增量、结束和错误。
5.5 把不同模型厂商翻译成同一套接口
跳转到“5.5 把不同模型厂商翻译成同一套接口”麻烦:Anthropic、OpenAI、Google 的鉴权方式、请求字段、流式协议和工具调用格式都不一样。如果在循环里到处写厂商分支,新增一家模型就会牵动全身。
做法:ai 包在内部提供 provider 适配器,把请求和回复统一成同一套内部事件。模型目录另外记录上下文窗口、价格、能力等信息;目录数据与代码骨架分开维护,避免频繁变化的数据产生大量无关改动。
结果:新增 provider 只需要改接入层,循环和界面不受影响。代价是适配层要处理各家边界情况;某些厂商独有能力需要通过能力标记或降级策略处理。
5.6 安全边界交给操作系统与容器
跳转到“5.6 安全边界交给操作系统与容器”麻烦:工具能读文件、跑命令,扩展还能执行进程内代码。自己写一个「权限沙箱」听起来安全,实际很容易留下漏洞,反而给人虚假的安全感。
做法:Pi 不自建一套细粒度权限沙箱。工具和扩展直接使用 Pi 进程的操作系统权限;打开项目时先做项目信任决定;需要强隔离时,把整个 Pi 放进容器(Gondolin 扩展、整进程 Docker、OpenShell 策略沙箱)。
结果:权限模型简单、可预期、可审计。代价是默认权限很大:不要在不信任的仓库里随意运行工具,高风险任务应放进容器。
5.7 把六个选择连起来
跳转到“5.7 把六个选择连起来”- 小核心 + 扩展:系统能长大,但核心不必跟着膨胀。
- 树形账本:历史能回看、能分支,不必只保留一条线。
- 每次投影:压缩和编辑不破坏原文,请求内容始终可重新推导。
- 事件流:同一个引擎可以服务人、脚本和外部程序。
- provider 适配:换模型不用改循环和界面。
- 操作系统/容器:安全边界简单明确,不制造「假沙箱」。
这六条不是孤立的设计,而是互相配合的:树形账本负责保存事实,投影负责生成本次视图,事件流负责把过程交给外部,provider 适配负责连接不同模型,小核心和操作系统权限则决定了系统的边界。
六、包速查与依赖
跳转到“六、包速查与依赖”11 个包的一句话职责(阶段 0 自检的答案表,这里加依赖备注):
| 包 | 一句话职责 | 内部依赖 |
|---|---|---|
| agent(pi-agent-core) | 通用 Agent 运行时:工具调用循环与状态管理,与 UI/模型解耦 | ai |
| ai | 统一多供应商 LLM API:流式事件归一化 + 模型目录 + 认证 | telemetry |
| coding-agent | 完整 CLI 应用:会话、工具、模式、界面组装 | agent、ai、codemode、mcp、tui |
| tui | 终端 UI 库:差分渲染 | 无 |
| mcp | 独立的 MCP 客户端(外部工具协议) | 无 |
| codemode | 沙箱 JS 运行时:唯一能力是调用注入的工具 | 无 |
| chord | 插件宿主:热重载、契约、复制状态、JSON-RPC | 无 |
| durable | 持久化对话/任务/文档运行时 | chord、ai、codemode |
| env | 远程执行环境(SSH 部署的守护进程 + 客户端) | chord、durable |
| telemetry | 遥测数据的共同格式:统一事件和指标的结构,不绑定某家厂商 | 无 |
| evals | 评测框架(开发期工具) | ai、coding-agent |
主干:coding-agent → agent → ai → telemetry。完整依赖图见阶段 13.2 节,画图练习见第七章。
七、文档地图
跳转到“七、文档地图”文档(packages/coding-agent/docs/) |
内容 | 对应阶段 |
|---|---|---|
| how-pi-works.md | 官方心智模型(六节:loop / context / sessions / interfaces / extensions / trust) | 1–3 起步必读 |
| session-format.md | 会话树 JSONL 格式:entry 类型、分支、压缩、编辑 | 3 |
| cli.md / json.md / rpc.md / sdk.md / usage.md | 五种界面与用法 | 7 |
| extensions.md / skills.md / prompt-templates.md / themes.md / packages.md | 扩展与资源体系 | 6 |
| 其余(models、containerization、security 等) | 按需查阅 | 5 / 8 |
| examples/sdk/01–14 | 教程式示例,由浅入深 | 7、9 |
| 仓库根 CONTRIBUTING.md、AGENTS.md、.pi/skills/ | 开发规则、发布流程 | 8 |
配套章节(可在侧栏继续阅读):
| 章节 | 内容 | 对应阶段 |
|---|---|---|
| 学习路线 | 路线总纲:七块框架、分阶段路线、通关标准(含完整文档地图) | 总纲 |
| 阶段 0 | 环境搭建与两种基础用法 | 0 |
| 阶段 1 | 一条请求的端到端生命周期 | 1 |
| 阶段 2 | agent 循环与事件流 | 2 |
| 阶段 3 | 会话树、上下文组装与压缩 | 3 |
| 阶段 4 | 工具管线八道关口 | 4 |
| 阶段 5 | 模型接入与凭据体系 | 5 |
| 阶段 6 | 扩展、技能、MCP、codemode | 6 |
| 阶段 7 | 五种界面形态与集成 | 7 |
| 阶段 8 | 工程化、测试与发布 | 8 |
| 阶段 9 | 完整 mini agent、测试与毕业验收 | 9 |
| 选修区 | 选修区五块(telemetry / durable / env / chord / evals)与缓存诊断,按需深入 | 选修 |
阶段 1–9 按同一种学习节奏组织:先说明问题,再讲概念与流程,然后给出代码位置或小实验,最后用常见误区和自检收束;阶段 0 则按安装步骤展开。做题时以详解为准,官方 docs 用来对照。
八、学习区信息
跳转到“八、学习区信息”- 源码基线:v1.3.0(
71023aec,2026-10-15 发布);请从官方仓库检出对应版本。 - 开发区:
$PI_DEV——主仓库;如果要跟随上游开发线,在这里动手。本课程的主线内容和实验以固定在 v1.3.0 的学习区为准。 - 参考示例:在线文档 https://pi.dev/docs/latest ;实跑入口是
pi-test.ps1(源码直跑,不过构建)。
配套学习路线编写 · 2026-10-19 · 基于 v1.3.0(71023aec)