https://www.youtube.com/watch?v=gTeujlv8qK0
本视频深入讲解了 AI 编码代理 Pi 的完整架构,分为两大模块:PiCore(代理核心) 与 PiInteractive(交互层)。作者强调,Pi 的设计风格是 极简、模块化、完全自研,非常适合学习或二次开发。
第一章:介绍(Intro)
Pi 是一个极简且架构优美的 AI 编码代理,近年来广受欢迎。 视频目标: 理解 PiCore(代理循环,可通过 RPC/SDK 编程调用) 理解 PiInteractive(终端用户界面 TUI 的交互功能)
第二章:代理循环(Agent Loop)
PiCore 的核心是 每轮对话都执行的一套固定步骤:
初始化上下文
加载硬编码的 系统提示词(system prompt) 附加 agents.md文件(位于 home 和当前工作目录)加载所有 技能(skill)的描述 加载所有 工具(tool)的描述 拼接消息历史(或压缩后的摘要)和当前消息 转换上下文
判断是否需要 压缩(compaction) 如需要,由 LLM 对历史消息进行总结并替换原消息历史 调用 LLM
调用用户选择的 LLM(OpenAI GPT-5、Anthropic、Kimi、MiniMax 等) LLM 可能返回 工具调用(读文件、写文件、搜索等) 工具返回结果后,LLM 可继续调用工具(可循环数百次) 当 LLM 不再需要工具时,返回最终响应给用户
关键点:Pi 的整个 agentic loop 完全从零手写,未使用 OpenAI Agents SDK、Vercel AI SDK 等现成库。
第三章:会话与内存(Sessions & Memory)
Pi 的会话存储设计非常优雅:
存储位置: ~/.pi/agent/sessions/按 工作目录 分类存储(如 /dashboard、/weather-app等)每个会话使用 JSONL 格式(每行一个 JSON 对象) 优点:新消息只需追加一行,无需重写整个数组 每个消息对象包含: type、id、parent、timestamp、content
亮点:会话不是线性列表,而是 树形结构。通过
parent字段,可以实现 对话分支(fork)。例如用户从某条消息分叉出两条不同方向的对话。Pi 使用/tree命令可视化该结构。
视频中实际演示了:
在终端执行 /tree查看对话树在文件系统和 VS Code 中查看 JSONL 文件的内容
第四章:工具(Tools)
Pi 默认仅包含 4 个核心工具:
read– 读取文件 bash– 执行 shell 命令 edit– 编辑文件 write– 写入文件
极简主义:作者本人会额外添加
web_search作为第 5 个工具。
另外还有两个 默认禁用的工具:grep 和 find。启用方式:pi --tools read,grep,find → 进入 只读模式,适合程序化调用(RPC 场景)时防止意外修改文件。
第五章:扩展(Extensions)
扩展是可安装的 TypeScript 包,用于修改 Pi 的行为,无需改动核心代码。
扩展可以做到:
注册新工具 订阅事件(工具调用、代理响应、用户消息等) 注册命令与快捷键 添加 CLI 标志 修改系统提示词 渲染自定义消息
安全提示:扩展会执行本地代码,不要安装不可信来源的扩展。可以用 Pi 自身先阅读扩展源码确保安全。
第六章:系统提示词(System Prompt)
Pi 的默认系统提示词非常短(约 20 行),结构如下:
基本角色设定:"你是 Pi,一个有用的助手" 追加 append-system.md的内容(用户可自定义)列出所有可用技能(使用类似 markdown 的格式) 包含当前日期和当前工作目录
用户可通过以下方式覆盖:
创建 .pi/system.md运行时: pi --system-prompt "你的提示词"
第七章:交互入口点(Interactive Entry Point)
当用户在终端输入 pi 命令时,实际流程:
client.ts接收命令,设置进程标题等 调用 main.ts:解析参数 解析配置(工作目录等) 加载扩展 - 创建代理会话
– 此时才真正初始化 PiCore 运行选定模式:交互模式 / RPC / 直接打印到 STDIO
第八章:终端用户界面(Terminal UI)
Pi 的 TUI 特点:
完全 自研,未使用 Textual 等现成库 - 基于组件
,每个组件负责自己的渲染和输入 组件可动态更新,可订阅 PiCore 发出的事件 界面不闪烁,底部有状态条 设计极简:上方显示消息,下方为输入区
作者强调:你可以用同样的 PiCore 构建自己的 GUI 或 Web UI,Pi 自带的 TUI 只是其中一种实现。
第九章:压缩(Compaction)
Pi 处理上下文窗口超限的方式:
- 不主动估算 token 数
(不像某些代理用字符数除以 4 来估算) 而是 依赖 LLM 返回的 usage 信息 在两个时机调用 check_compaction:代理结束一个回合(返回响应后) 用户发送新消息之前
计算上下文 token 数的方式:
如果有 usage.context_tokens直接使用否则计算: input_tokens + output_tokens + cache_read + cache_write
压缩提示词 非常结构化,要求 LLM 生成包含以下字段的摘要:
目标(goal) 约束与偏好 进度(已完成、进行中、被阻塞) 关键决策 下一步计划 关键上下文(保留完整文件路径、函数名、错误信息)
视频中现场演示了执行压缩后生成的摘要内容。
第十章:技能(Skills)
技能 与 自定义斜杠命令 是两个不同的东西:
自定义斜杠命令(如
/mycmd):由 CLI 层拦截,直接替换为预设的提示词,不会 进入 PiCore。技能(Skills):
存放在 .md文件中,文件头部包含name和description技能描述被加载到系统提示词中,因此 LLM 知道存在哪些技能 用户通过 /skill:技能名调用交互层 不会 自动把技能内容替换进去 而是向 LLM 发送一个特殊结构,包含:技能名称、描述、文件路径 LLM 收到后,会使用 read工具主动读取该技能文件内容,然后继续执行
这种设计与其他代理(如直接粘贴技能内容)不同,体现了 Pi 在分层与 token 效率之间的权衡。
最终总结
观看完本视频后,你应该能够:
理解 Pi 的极简 agentic loop 设计 理解其 JSONL + 树形会话存储方案 了解其工具、扩展、技能、压缩机制的分层实现 有能力自己动手实现一个类似 Pi 的 AI 编码代理
作者寄语:这是一个非常有教育意义的项目,欢迎在评论区提问交流。
夜雨聆风