- Published on
Pi 源码解读(一):整体架构与完整执行链路
- Authors

- Name
- Stone
NOTE
这节课只解决一个问题:Pi 里面,谁负责什么?
先看懂整体分工,再进入循环和工具。暂时不用记住一大堆类名。
本系列对照 Pi v0.84.1 的官方源码,例子是教学场景,不是实际运行记录。
一、Pi 不是模型,而是使用模型干活的程序
你可以把两者的关系理解成:模型根据已有信息提出下一步,Pi 负责组织信息、执行工具,并把结果交回去。 Pi 的通用 Agent 运行时把模型、消息和工具接到一起;编程助手应用再为它配置代码任务需要的能力。12
例如你提出:
把 src/App.vue 里的页面标题从 Hello 改成你好,其他地方不要动。
假设文件内容还没有进入模型的上下文,一条可能的执行过程是:
先读文件。 模型提出读取请求,Pi 调用工具,拿到实际内容。
再改文件。 模型根据读到的内容提出修改请求,Pi 执行,并记录结果。
最后回复。 模型看到修改结果后,才有依据告诉你做了什么。
这条路径里,用户只说了一句话,却可能触发多次模型调用。第二课会专门展开这个过程;现在只记住:模型提出请求,不等于操作已经完成。3
你以后看到 Harness,先把它理解成“围绕模型搭起来的运行框架”:模型以外,还得有人管理工具、上下文和任务过程。不必先纠结这个词的翻译。
二、四个模块,对应四种分工
把 Pi 想成一款你要开发的产品,它至少需要有人对接模型、推进任务、组织业务和显示界面。下面这四个包就对应这些主要职责。45
| 模块 | 用大白话理解 | 源码目录 |
|---|---|---|
| pi-ai | 负责“跟模型沟通”,适配不同模型服务的接口。 | packages/ai |
| pi-agent-core | 负责“让任务继续”,管理消息、调用模型、执行工具。 | packages/agent |
| pi-coding-agent | 负责“组装编程助手”,把项目、工具、会话等能力组合起来。 | packages/coding-agent |
| pi-tui | 负责“终端里的输入和显示”。 | packages/tui |
这里不是一条必须依次经过的流水线。编程助手应用使用 Agent 运行时推进任务,使用模型接口与模型通信;终端界面负责接收输入、展示过程。 TUI 是交互设施,不负责决定下一步该读哪个文件。6
对你来说,可以类比前端里的“请求适配、状态与流程、业务组织、界面展示”。它们不是同一种东西,也不该全部写在一个组件里。
为什么要分开? 一个直接的好处是:不使用终端界面,也能通过 SDK 接入 Pi 的编程助手能力。由此可以推导,换成网页界面时,可以复用执行部分,而不是重新写一遍 Agent Loop。2
三、过程中流动的,不只是聊天文字
先认识三个词就够了:
Message:一条记录。 可以是用户需求、模型的工具请求,也可以是工具返回的结果。工具结果不是随手打印的日志,而是后续模型可能需要使用的信息。7
Context:这一次给模型的材料。 包括规则、对话记录和可用工具的说明。模型根据这些材料生成这一轮输出。8
Session:这一段持续交互的会话。 它负责把前后过程组织起来,可以涉及历史保存与恢复。不要把“完整会话历史”和“某次请求实际交给模型的内容”当成同一回事。2
用改标题的例子理解:用户需求是一条记录,读取结果也是一条记录;Pi 把本轮需要的记录整理后交给模型。程序读到了文件,只有把结果交回模型,模型才通过这条链路得知文件内容。
四、第一次读源码,只验证一条主线
先根据上面的表,在仓库里找到四个目录。然后打开 agent-loop.ts,带着这三个问题读:
哪里调用模型?哪里执行工具?工具结果在哪里回到上下文?
找到它们之间的联系,就完成第一轮阅读。复杂类型、会话分支、压缩和扩展机制先不展开;它们值得单独学习,但不是理解主流程的前提。
这一课也不要求安装项目或抄写代码。先能用自己的话讲清:用户需求 → 模型提出动作 → Pi 执行 → 结果交回模型。
五、面试时,先讲清这一段
下面是理解并对照源码之后可以采用的表达,不需要声称自己研究完了整个项目:
我通过 Pi 学习 Coding Agent 的实现。它把模型接口、任务运行时、编程助手应用和终端界面分开。比如修改 Vue 页面的标题,模型可以先请求读文件,再根据内容请求修改,运行时负责执行这些工具,并把结果放回上下文。我理解它的核心不是一次模型调用,而是把模型和真实执行环境接成一个可以持续推进的过程。
一个不用写代码的小练习
把 Pi 的终端界面换成网页聊天窗口,是否必须重写 Agent Loop?为什么?
想过之后再看答案
不一定。界面负责输入和展示,Agent Loop 负责推进任务;职责分离后,可以在新的界面后面接入已有运行时。不过仍然需要处理前后端通信、运行环境和权限,不能把服务端执行能力直接等同于浏览器能力。
