π Pi Agent Study
目录页 · 后续逐章扩展

任务一:规划学习路径

从源码读懂 coding agent

这是一套给新手跟学的 Pi agent 核心课程。HTML 教程走主线,Markdown 学习记录保留更深入的源码笔记。

8 章 从 00 基础概念,到入口、模型、循环、工具、会话、扩展和 SDK/RPC。
8 页教程 每章都有教程页和学习记录,后面可以继续扩展图、实验和复盘问题。
1 条主线 追踪一次 prompt 如何变成模型调用、工具执行和最终回答。

你适合这套课吗

这不是 API 文档,也不是完整源码索引。它是一条从概念到源码主线的跟学路线。

A

适合

对 agent、tool calling、上下文、session 还不熟,但有一点 JavaScript/TypeScript 基础的人。

B

适合

想读懂 Pi agent 源码主线,并能讲清一次 prompt 如何触发模型和工具循环的人。

C

不适合

第一遍就想穷尽所有 provider、TUI 细节、扩展边角和每个类型定义的人。

D

学习定位

HTML 教程是主线;Markdown 学习记录是进阶读源码资料。第一遍先看 HTML。

学习前准备

不需要先读完整仓库。准备好运行环境和几个观察动作,就可以开始跟学。

先准备 Pi 运行环境

能在仓库或你的安装位置跑起 pi,最好能用 JSON/print mode 观察事件流。第一遍不需要改源码。

pi --mode json -p "Read README.md" ./pi-test.sh

准备源码阅读方式

先按章节给出的文件读,不从随机实现文件开始。复杂链路优先画图。

packages/ai packages/agent packages/coding-agent

准备验证方式

每章都要用一个行为验证理解:跑命令、看 JSON event、画 tree、解释一次 toolResult 回填。

先放下边角

第一遍不要追所有 UI、provider 和扩展细节。学习重点是流程、边界、状态变化。

推荐学习路径

第一遍建立 agent 核心主线;第二遍再看扩展和复用边界。

00基础概念LLM、Context、toolCall、toolResult、loop。
01入口从 CLI 到 AgentSession、Agent、runLoop。
02模型接口Context 到 provider payload 和 stream event。
03Agent loop模型生成、工具执行、结果回填、继续生成。
04默认工具read、edit、write、bash 如何成为模型可调用动作。
05Sessionsession tree、分支、恢复和 compaction。
06/07进阶扩展系统、SDK、RPC 和宿主复用。
第一遍必读 00 -> 01 -> 02 -> 03 -> 04 -> 05。先把 agent 核心跑通。
第二遍进阶 06 -> 07。再看 skill、tool、command、hook、SDK 和 RPC 如何把同一套 agent 能力扩出去。

先看项目分层

这个仓库不是一个单包 CLI。它把模型调用、agent runtime、coding-agent 应用层和终端 UI 分开了。

packages/agent

通用 agent runtime。真正的核心在这里:消息状态、上下文转换、事件流、工具执行、steering、follow-up 和停止条件。

src/agent-loop.ts src/agent.ts src/types.ts

packages/ai

模型与 provider 抽象层。重点看统一消息格式、stream event、tool calling 和 provider payload 转换。

README.md src/providers

packages/coding-agent

把通用 agent 包装成编码助手。这里有默认工具、系统提示词、session、扩展、CLI、SDK 和 RPC。

src/core/tools src/core/sdk.ts

packages/tui

终端 UI 层。先不深入,等理解交互模式和事件订阅之后,再看它如何渲染消息和工具输出。

src/components README.md

学习目录

HTML 教程按主线学习;Markdown 学习记录用于第二遍深入源码。第一遍从 00 开始,不要跳过基础概念。

00 基础概念

Agent 基础:先分清模型、工具和循环

给完全小白的前置缓冲层。先把 LLM、Context、toolCall、toolResult、agent loop 和 session 的边界讲清楚。

这一节学什么 学 agent 为什么不是普通聊天:模型提出 toolCall,本地工具执行后产生 toolResult,agent loop 把结果回填上下文,再让模型继续推理。学完要能区分 Context 和 session,以及 Pi 的 packages/aipackages/agentpackages/coding-agent 三层。

  • 00-agent-basics-tutorial.html
  • 00-agent-basics-notes.html
  • 首页的推荐学习路径。

  • toolCall 不等于工具已执行。
  • toolResult 必须回填给模型。
  • Context 是模型输入视图,session 是长期历史。

  • 画出 user -> model -> toolCall -> toolResult -> model。
  • 用自己的话解释 agent loop。
  • 说出 Pi 三层源码各自负责什么。
01 入口与运行

使用入口:先把 pi 跑起来

先不要急着读源码。用一次 pi,观察它如何显示消息、工具调用、模型、上下文和 session。

这一节学什么 学 CLI 入口如何把一次用户输入送进 AgentSession.prompt(),再由 Agent.prompt() 启动一次 run,最后进入 runAgentLoop()。学完要能讲清 print/json/interactive/RPC/SDK 的区别,以及一次 prompt 为什么不是单次模型调用。

  • README.md
  • packages/coding-agent/README.md
  • docs/quickstart.md

  • interactive、print、JSON、RPC、SDK 的区别。
  • 默认工具如何暴露给模型。
  • 一次交互里有哪些消息和事件。

  • ./pi-test.sh 启动。
  • 让它读一个 README。
  • 记录工具调用输出。
02 模型边界

模型接口:理解 tool calling

先学模型层,知道一个 provider 如何接收 context,如何返回 text、thinking、toolCall 和 done。

这一节学什么 学 Pi 内部的 Context 如何成为 agent/provider 边界:agent 只整理 system prompt、messages、tools,provider 再转成 OpenAI/Anthropic/Google 的具体 payload。重点理解流式 tool call 为什么要等参数完整后才能执行,以及 tool result 为什么必须回填给模型。

  • packages/ai/README.md
  • packages/ai/src/index.ts
  • packages/ai/src/providers

  • Context 的结构。
  • stream event 的含义。
  • tool 参数 schema 和 validation。

  • 画消息序列图。
  • 找一个 provider 看 payload 转换。
  • 解释 toolResult 为什么要回到上下文。
03 执行引擎

Agent loop:读懂核心循环

这是整条路线最重要的一章。agent 的本质不是聊天,而是一个持续把模型输出、工具执行和新上下文串起来的循环。

这一节学什么runAgentLoop() 如何反复执行“模型生成 -> 工具调用 -> 工具结果回填 -> 下一轮生成”。重点看 pending/steering 消息、assistant message 定稿、顺序/并行工具、hook、turn_end、prepareNextTurn 和停止条件。

  • packages/agent/src/agent-loop.ts
  • packages/agent/src/agent.ts
  • packages/agent/src/types.ts

  • runLoop 的内外循环。
  • 工具执行后的上下文更新。
  • steering 和 follow-up 的差异。
  • 停止条件和继续条件。

  • runLoop 画流程图。
  • 标出每次 emit 的时机。
  • 解释 hook 放在循环中的位置。
04 默认工具

默认工具:拆 read、edit、write、bash

coding agent 的能力来自工具。这里要学的是工具定义、参数校验、路径处理、输出截断和文件修改安全。

这一节学什么 学产品层 ToolDefinition 如何被 wrap 成 agent core 使用的 AgentTool。重点拆 read 的截断策略、edit 的唯一匹配、write 的文件写入队列,以及 bash 的 partial update 和最终结果回传。

  • src/core/tools/index.ts
  • read.tsedit.ts
  • write.tsbash.ts
  • file-mutation-queue.ts

  • 工具定义和执行为什么分开。
  • 文件路径如何约束。
  • 工具输出如何截断。
  • 文件修改为什么要排队。

  • 选一个工具写源码讲解。
  • 比较 readbash 的风险边界。
  • 列出一个工具的失败路径。
05 会话历史

Session:上下文、分支和压缩

产品级 agent 必须保存历史、支持恢复、允许分支,并在上下文变长时压缩。这里是 pi 很值得学的部分。

这一节学什么SessionManager 如何用 append-only JSONL 保存 user、assistant、toolResult、compaction 等历史,并把它们组织成可分支的树。重点理解 /tree 切分支后为什么还要 rebuild context 覆盖 agent.state.messages,以及 compaction 为什么只改变模型视图、不删除原始历史。

  • docs/session-format.md
  • docs/compaction.md
  • src/core/session-manager.ts
  • src/core/compaction

  • JSONL session 为什么是树。
  • /tree/fork/clone 的差异。
  • compaction 如何取舍历史和近期上下文。

  • 打开一个 session 文件并标注 entry。
  • 说明上下文溢出时如何恢复。
  • 画出分支恢复路径。
06 扩展能力

扩展系统:skills、commands、templates

pi 的设计重点是可扩展。这里学的是如何把专用能力装进 skill、prompt template、extension tool、command 和 hook。

这一节学什么 学 skill 的渐进式披露、slash command 的接管顺序、extension loader/runner 的注册与运行边界、runtime ctx 的 getter/stale 检查,以及 extension tool、hook、resources_discover 如何进入统一的工具和资源管线。

  • packages/coding-agent/src/core/skills.ts
  • packages/coding-agent/src/core/extensions/loader.ts
  • packages/coding-agent/src/core/extensions/runner.ts
  • packages/coding-agent/src/core/agent-session.ts

  • skill 为什么不是 tool。
  • extension command 为什么先于 prompt 展开。
  • registerTool 如何进入 agent.state.tools。
  • hook 如何插入 agent loop。

  • 画出 skill 的渐进式披露路径。
  • 解释 loader / runner / AgentSession 的边界。
  • 比较 command、tool、hook、resources_discover。
07 复用边界

SDK 和 RPC:把 agent 放进别的应用

最后看复用边界。interactive mode 只是一个宿主,SDK 和 RPC 展示了同一套 agent 能力如何被其他进程或应用使用。

这一节学什么createAgentSession() 为什么创建完整产品级 AgentSessionAgentSessionRuntime 为什么负责 new/resume/fork/switch/import 的 session replacement,以及 RPC mode 如何把同一套 agent 能力暴露成长期 JSONL 服务。

  • packages/coding-agent/src/core/sdk.ts
  • packages/coding-agent/src/core/agent-session-runtime.ts
  • packages/coding-agent/src/core/agent-session-services.ts
  • packages/coding-agent/src/modes/rpc

  • SDK 为什么创建完整 AgentSession
  • Runtime replacement 为什么独立出来。
  • RPC prompt response 为什么只代表 accepted。
  • RPC 为什么是长期 agent server。

  • 画出 SDK 创建链路。
  • 解释 services/session 拆分。
  • 比较 print/json 和 RPC。

每次怎么学

固定一个学习动作,降低复杂源码带来的混乱感。

Q

先提出一个问题

比如:工具结果为什么要写回上下文?session 为什么用树?steering 为什么不直接打断?

R

再定位入口文件

先读 README 或 docs,再读 index、types、核心实现。不要从随机实现文件开始。

F

把流程画出来

把函数调用、消息变化、事件发射、状态更新画出来。agent 项目最重要的是流程。

V

用行为验证理解

跑一个例子、加一个日志、写一个小工具或 template,看实际行为是否符合你的解释。

学完以后要能讲清这条链路

用户输入进入 pi,session 构造上下文,agent loop 调用模型,模型产生文本或 toolCall,工具执行后生成 toolResult,toolResult 回到上下文,模型继续直到给出最终回答。

最终检查

  • 能解释 AgentAgentSession 的关系。
  • 能追踪一次工具调用的完整事件序列。
  • 能说明 session tree 和 compaction 的作用。
  • 能写一个小 skill、template 或 SDK demo。