Pi Agent 详解

基于 pi-coding-agent 官方文档整理


目录


一、Pi Agent 是什么

核心定位

Pi 是一个极简的终端编码智能体框架(minimal terminal coding harness)。它将大型语言模型(LLM)的能力封装为一个可直接在命令行中交互的编码助手,让模型能够通过调用工具来读取文件、执行命令、修改代码,从而完成用户提出的开发任务。

与其他编码助手不同,Pi 的核心设计目标是高度可扩展、不绑定特定工作流——它提供强大的默认能力,但把子代理、计划模式、权限弹窗等功能留给扩展或第三方包去实现,保持核心最小化。

设计哲学

原则 说明
不内置 MCP 通过 CLI 工具 + README(Skills)或扩展自行集成
不内置子代理 用户可通过 tmux、扩展或第三方包自行实现
不内置权限弹窗 由用户根据环境自行构建确认流(扩展)
不内置计划模式 用户可写计划到文件,或通过扩展实现
不内置待办列表 避免模型混淆,可用 TODO.md 或扩展替代
不内置后台 Bash 推荐用 tmux 实现完整可观测性

Pi 的设计理念是:适应你的工作流,而不是让你适应它

运行形态

Pi 运行时呈现为一个终端 TUI(Terminal User Interface),从上到下分为:


二、底层工作原理

1. 核心架构:LLM + 工具系统

Pi 的本质是 LLM 与工具之间的循环代理(Agent Loop)

用户输入
    ↓
系统组装 Prompt(System Prompt + AGENTS.md + Skills + 历史消息)
    ↓
发送给 LLM
    ↓
LLM 生成回复(文本 或 工具调用请求 ToolCall)
    ↓
若含 ToolCall → 本地执行工具 → 返回 ToolResult → 再次送入 LLM
    ↓
若无 ToolCall → 向用户输出最终结果

默认内置工具(可配置、可禁用、可覆盖):

工具 功能
read 读取文件内容
write 写入/创建文件
edit 精确文本替换编辑
bash 执行 shell 命令
grep 文本搜索
find 文件查找
ls 列出目录内容

模型通过 ToolCall 内容块声明要调用的工具及参数,Pi 在本地执行后将结果以 ToolResultMessage 形式回传给模型,形成**观察-推理-行动(Observation-Reasoning-Action)**循环。

2. 会话机制:树形 JSONL 存储

Pi 的所有对话以**会话(Session)**为单位持久化存储,文件格式为 JSONL(JSON Lines),位置在 ~/.pi/agent/sessions/ 下,按工作目录组织。

关键设计:树形结构而非线性

每条记录都有 idparentId,形成一棵树:

[user msg] ─── [assistant] ─── [user msg] ─── [assistant] ─┬─ [user msg] ← 当前分支(active leaf)
                                                            │
                                                            └─ [user msg] ← 另一分支

这使得:

会话中的消息类型

角色 说明
user 用户输入(文本或图片)
assistant 模型回复(含文本、思考过程、工具调用)
toolResult 工具执行结果
bashExecution Bash 命令执行的详细输出记录
custom 扩展注入的自定义消息(可参与或不参与 LLM 上下文)
branchSummary 分支切换时生成的摘要
compactionSummary 上下文压缩摘要

3. 上下文构建与压缩

上下文构建(buildSessionContext: 从当前叶子节点沿 parentId 回溯到根节点,收集路径上所有消息,组装成 LLM 的输入消息列表。

上下文压缩(Compaction): 当对话过长接近上下文窗口上限时,Pi 会自动或手动触发压缩:

  1. 定位切分点:从最新消息反向累积,保留最近约 20K Token 的内容
  2. 生成摘要:调用 LLM 将更早的消息压缩为结构化摘要
  3. 写入 CompactionEntry:记录摘要及保留消息的起点 firstKeptEntryId
  4. 重建上下文:LLM 看到的是「摘要 + 从 firstKeptEntryId 之后的完整消息」

分支切换时(/tree),Pi 还可以为被放弃的分支生成 BranchSummaryEntry,保留重要上下文而不需要重放整条分支。

4. 扩展系统:插件化架构

Pi 的核心极简,几乎所有进阶功能都通过 TypeScript 扩展(Extensions) 实现:

export default function (pi: ExtensionAPI) {
  // 1. 注册自定义工具供 LLM 调用
  pi.registerTool({ name: "deploy", ... });

  // 2. 拦截生命周期事件
  pi.on("tool_call", async (event, ctx) => { ... });

  // 3. 注册自定义命令(如 /deploy)
  pi.registerCommand("deploy", { ... });

  // 4. 自定义 UI 组件
  ctx.ui.custom(...);

  // 5. 持久化扩展状态到会话
  pi.appendEntry(...);
}

扩展能做什么

Skills(技能): 遵循 Agent Skills 标准 的 Markdown 文件,通过 /skill:name 按需加载,用于给模型提供特定领域的步骤化指导。

Pi Packages: 通过 npm 或 git 分发的扩展/技能/提示模板/主题包,可在社区共享。

5. 四种运行模式

模式 用途
Interactive(交互式) 默认 TUI 界面,持续对话
Print(打印式) pi -p "prompt",执行一次输出结果后退出
JSON --mode json,输出结构化 JSON Lines 事件流
RPC --mode rpc,通过 stdin/stdout 的 JSONL 协议与其他进程集成
SDK 在 Node.js 应用中嵌入 Pi:createAgentSession()

三、可以用来做什么

1. 日常编码工作

消息队列机制

2. 项目级能力扩展

通过 AGENTS.md(或 CLAUDE.md)为项目注入持久化指令:

文件加载层级(从当前目录向上级联 + 全局):

~/.pi/agent/AGENTS.md(全局)
<parent-dirs>/AGENTS.md
./AGENTS.md

3. 自动化与集成

扩展驱动的场景

4. 非交互式场景

5. 典型生态场景

场景 实现方式
多模型对比 Ctrl+P 循环切换已配置模型,同一会话对比输出
长会话管理 自动压缩 + /tree 分支回溯 + /compact 手动压缩
团队协作 通过 Pi Packages 共享技能、提示模板、扩展
安全沙箱 扩展拦截危险命令,或容器化运行 Pi
自定义外观 主题系统(热重载)+ 扩展替换 TUI 组件
等待时娱乐 Doom、Snake 等扩展(是的,真的可以在等模型时玩游戏)

总结

Pi Agent = 极简终端框架 + LLM 工具循环 + 树形会话 + 高度可扩展的插件系统

它不预设你的工作方式,而是通过一套干净的核心机制(模型调用、工具执行、会话树、扩展 API),让你和第三方社区能够按需组装出最适合自己的编码智能体工作流。