Agent 本质与 pi-agent 拆解

核心观点
智能体本质 = 模型 + 工具 + 循环。用 300 行代码就能构建一个极简 Coding Agent。
但 pi-agent 能火(GitHub 数千 star)不只是因为"能跑",而是它的极简核心 + 扩展系统架构设计——系统提示词不到 1000 token,内置工具仅 4 个,却能通过扩展做任何事。
pi-agent 三种用法
1. 作为 Coding Agent 直接使用
可替代 Claude Code / Codex,社区很受欢迎。支持自己扩展功能,玩法多。
安装:
# 方式一:npm 全局安装
npm install -g @earendil-works/pi-coding-agent
# 方式二:curl 一键安装(macOS/Linux)
curl -fsSL https://pi.dev/install.sh | sh
# 启动
cd your-project
pi
配置模型:~/.pi/agent/models.json 中写入模型配置,支持 OpenAI / Anthropic / Google / Ollama 等任意 provider。
日常使用:
pi # 进入交互模式
pi --print "解释这段代码" # 单次执行,输出到 stdout
pi -m "重构 src/utils.ts" # 直接给任务
⚠️ GLM Coding Plan 套餐不支持 pi-agent。
2. 学习生产级 Agent 开发
pi-agent 代码极简清晰,是学 Agent 架构的最佳教材。相比 Claude Code(30k+ token 提示词、20+ 内置工具),pi-agent 核心只有 4 个工具 + < 1000 token 系统提示,一眼能看到头。
3. 基于 pi-agent 构建自己的 Agent
非常适合作为底层框架。官方 packages 市场已有 3,300+ 个包可用,自己定制也很方便——写一个 TypeScript 文件放到 ~/.pi/agent/extensions/,/reload 即生效。
深入架构:三层解耦
pi-agent 是 monorepo 架构(TypeScript),核心设计原则:分离不稳定的外部世界与稳定的核心循环。

三层各自职责
| 层 | 包名 | 职责 |
|---|---|---|
| pi-ai | @earendil-works/pi-ai |
统一多 Provider LLM API,屏蔽 OpenAI/Anthropic/Google/Mistral 等差异,处理 Streaming、Tool Schema、Token 统计 |
| pi-agent-core | @earendil-works/pi-agent-core |
Agent 运行时核心:Agent Loop、Tool Calling 执行、消息状态管理、Steering/Follow-up 队列 |
| pi-coding-agent | @earendil-works/pi-coding-agent |
产品层:CLI 入口、TUI 交互、会话管理、扩展系统、内置工具组合 |
两个关键边界
- LLM 边界:
pi-ai层统一 Provider 接口——统一消息进,统一事件出。model 切换不需要改业务代码。 - 副作用边界:模型只能 提议 工具调用,实际执行在本地发生,可以被扩展拦截/修改/阻止。
这种分层使得每一层可独立测试——pi-ai 可以不依赖 Agent 循环测试,pi-agent-core 可以不依赖 UI 测试。
pi-agent 扩展生态
四种扩展类型(补充)
| 类型 | 说明 |
|---|---|
| Skill | 技能扩展,按需加载的能力包(SKILL.md 格式) |
| Extension | ⭐ 代码扩展,最核心。TypeScript 文件,可拦截 Agent 任何行为 |
| Template | 提示词模板,/name 展开 |
| Theme | 主题 |
热门扩展推荐(2026)
| 扩展 | 功能 |
|---|---|
| context-mode | 节省 98% 上下文窗口,沙盒代码执行 + FTS5 知识库 |
| pi-subagents | 子 Agent 任务委派,支持链式/并行执行 |
| pi-mcp-adapter | MCP 协议适配器,连接任意 MCP Server(DB/API/文件系统) |
| pi-web-access | 补足网络能力:Web 搜索、URL 抓取、GitHub 仓库探索、YouTube 转录 |
| pi-hermes-memory | 跨会话持久记忆,记住项目偏好和历史决策 |
| pi-lens | 实时代码反馈:LSP、linter、formatter、类型检查 |
| pi-simplify | 代码质量守门员,自动审查变更代码的清晰度 |
| pi-tinyfish | 免费 Web 搜索 + 页面抓取,无需 API key |
安装:pi install npm:<package-name> → /reload
写一个扩展有多简单
// ~/.pi/agent/extensions/minimal-footer.ts
export default function (api: ExtensionAPI) {
api.on('session_start', () => {
console.log('🟢 Agent 已启动')
})
}
放到目录 -> /reload -> 生效。Pi 每次启动自动加载 ~/.pi/agent/extensions/*.ts。
Extension API 能力
| 能力 | 说明 |
|---|---|
| 订阅 30+ 生命周期事件 | session_start、before_agent_start、tool_call、tool_result、context、input 等 |
| 注册自定义工具 | registerTool(tool: ToolDefinition) |
| 注册命令/快捷键/CLI 标志 | registerCommand() / registerShortcut() / registerCliFlag() |
| UI 交互原语 | showSelector() / showConfirmation() / showNotification() |
关键事件 tool_call:可在工具执行前拦截、修改参数、甚至阻止调用。所有子 Agent、MCP、权限弹窗等功能均由扩展实现,核心不内置。
Agent Loop 深度拆解
双循环架构
pi-agent 的循环不是一层,而是两层:

内循环:Agent 类的核心
LLM 调用
↓
返回含 tool_call 吗?
├─ 否 → 返回 final message,结束
└─ 是 → 逐条执行工具
↓
工具结果作为 toolResult 消息加入上下文
↓
再次调用 LLM(含工具结果)
↓
└─ 循环直到没有 tool_call
关键设计点:
- 工具执行模式:支持
sequential和parallel。默认并行执行多个 tool_call,可设为串行。 - 输出截断:大工具输出自动截断(
truncateHead/truncateTail),防止撑爆上下文,提示"完整输出在 xxx 文件中"。 - File Mutation Queue:写文件工具进入队列串行执行,避免并行工具同时改同一文件的冲突。
Steering / Follow-up 队列
Pi 支持在 Agent 工作中提交消息,不打断当前任务:
- Enter — Steering 消息:当前助手回合工具执行完后送达
- Alt + Enter — Follow-up 消息:整个 Agent 循环完成后送达
- Escape — 中止操作,队列消息恢复到编辑器
- Alt + Up — 队列消息取回编辑器
会话管理与压缩
- 存储格式:JSONL(每行一个 JSON 对象),树形结构
- leafId:决定模型看到的上下文路径——从根到叶子节点的消息链
- 压缩(Compaction):
- 自动触发:上下文窗口快满时
- 手动触发:
/compact命令 - 无损:完整历史保留在 JSONL,压缩只是创建摘要条目替代旧消息
极简哲学 vs 主流方案
系统提示词大小对比
| Claude Code | Codex | Pi | |
|---|---|---|---|
| 系统提示词 | ~15,000 tokens | ~12,000 tokens | < 1,000 tokens |
| 内置工具数 | 20+ | 适中 | 4 个(read/write/edit/bash) |
| Plan Mode | 内置(黑盒子) | 内置 | ❌ 无(用文件代替) |
| MCP 支持 | 内置 | 内置 | ❌ 无(扩展实现) |
| Sub-Agent | 内置(不可观测) | — | ❌ 无(bash 自我调用) |

Pi 做了什么减法
- 不内置子 Agent → 通过
pi-subagents扩展实现 - 不内置 Plan Mode → 写 AGENTS.md 文件 + 只读工具模式
- 不内置 MCP → 通过
pi-mcp-adapter扩展 - 不内置权限弹窗 → 默认 YOLO 模式,用 Docker/OpenShell 隔离
为什么极简反而更强
- Token 省 10 倍:同等任务 Pi 消耗 ≈ Claude Code 的 30-35%
- 响应更快:上下文短,模型推理加速明显
- 更听话:没有 1 万字预设指令抢注意力,日常任务更精准
- 透明可控:整个提示词链肉眼可见,可随意定制
Token 效率的秘密
1,500 vs 15,000 的差距从哪来?
Claude Code 的提示词里塞了大量预设:代码索引流程、Git 操作说明、测试框架指令、MCP 连接逻辑……这导致每次调用(哪怕只是"读这个文件")都要携带 1.5 万吨"行李"。
Pi 的选择:只教最基本的东西——“你有读/写/改/跑四个工具,文档在 node_modules 里,自己去查”。其余能力通过扩展按需加载。
Pi = 一张白纸。Claude Code = 写满了注记的稿纸。画同一个东西,白纸更自由。
智能体循环的本质
(保留原内容)
三种模型使用方式对比
| 方式 | 特点 | 是否算 Agent |
|---|---|---|
| 单轮调用 | 输入→回答,一次结束 | ❌ 只是模型调用 |
| 工作流 | 预先设计好步骤 | ❌ 只是流程编排 |
| 智能体循环 | 模型自主决定是否调用工具、何时结束 | ✅ 真正的 Agent |
循环过程

核心代码(极简版,约 200 行)
- 定义模型:选择支持 function calling 的模型
- 定义工具:读取文件、列出目录、编辑文件(本质是
str.replace) - 工具说明:用 JSON/自然语言描述工具签名,让模型知道如何调用
- 系统提示词:设定角色和做事方法
- 循环维护:
- 首次调用模型 → 检查返回是否含工具调用
- 有 → 逐条执行 → 拼接结果 → 下一轮循环
- 无 → 返回结果,结束
深度思考:为什么"不调用工具"=循环结束?
模型在训练阶段学会的规则:
- 要么调用工具 → 得到结果 → 再决策
- 要么给出最终答复
如果不调用工具又没给出答复,训练时会得低分。因此模型学会了在完成任务前持续调用工具。
"完成任务"不等于一定解决问题,能正确回答"不知道"也是完成任务。
学习建议
- 先看 pi-agent 源码中的 Agent Loop:
packages/agent/src/agent-loop.ts只有几百行,是理解 Agent 本质的最佳入口 - 先跑极简版:写一段提示词 + 给定一批工具 → 先把循环跑起来
- 观察效果 → 针对问题打补丁 → 逐步迭代
- 然后读
packages/coding-agent/src/core/agent-session.ts理解外层循环(重试、压缩、扩展系统交互) - 最后对比 Claude Code 的设计:体会"加法"和"减法"两种架构哲学的差异
更多推荐

所有评论(0)