Site logo
Published on

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

Authors
  • avatar
    Name
    Stone
    Twitter
本篇目录

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 负责推进任务;职责分离后,可以在新的界面后面接入已有运行时。不过仍然需要处理前后端通信、运行环境和权限,不能把服务端执行能力直接等同于浏览器能力。

参考源码

Footnotes

  1. Pi v0.84.1 · packages/agent/README.md ↩

  2. Pi v0.84.1 · packages/coding-agent/docs/sdk.md ↩ ↩2 ↩3

  3. Pi v0.84.1 · packages/agent/src/agent-loop.ts ↩

  4. Pi v0.84.1 · packages/ai/README.md ↩

  5. Pi v0.84.1 · packages/coding-agent/package.json ↩

  6. Pi v0.84.1 · packages/tui/README.md ↩

  7. Pi v0.84.1 · packages/ai/src/types.ts ↩

  8. Pi v0.84.1 · packages/agent/src/types.ts ↩