Pi - 极简又强大的 AI 编码智能体框架
"一个调用 LLM 的 while 循环,加上四个基础工具。" — Armin Ronacher & Mario Zechner
为什么 Pi 有价值
S (情境):当前 AI Agent 平台都在比拼功能复杂度,工具列表越来越长,配置越来越重。
T (任务):Pi 选择反其道而行 —— 用极简架构证明:足够强大的 LLM(如 Claude Sonnet)不需要过度设计的工具链。
A (行动):只做一件事:把 Unix 工具链的威力交给 AI。
R (结果):"Bash 就是你所需要的一切" —— 证明减法比加法更难,但也更有价值。
1. 核心循环:就是一个 while 循环
// packages/agent/src/agent-loop.ts
while (true) { // 外层循环:处理后续消息
while (hasMoreToolCalls || pendingMessages.length > 0) {
// 1. 把用户消息发给 AI
const message = await streamAssistantResponse(...);
// 2. AI 说"我要用工具" → 执行 → 告诉 AI 结果
if (toolCalls.length > 0) {
const results = await executeToolCalls(...);
currentContext.messages.push(...results);
}
// 3. AI 继续思考,可能还要用工具 → 重复
}
// 没新消息就结束,有就继续
}
人话版:
- 把用户消息发给 AI
- AI 说"我要用工具" → 执行 → 把结果告诉 AI
- AI 继续思考 → 重复
- AI 说"完成了" → 检查有没有新消息 → 有就继续,没有就结束
没有状态机,没有工作流引擎,没有递归调用 —— 就是一个简单的"对话-执行-反馈"循环。
2. 四个基础工具
// packages/coding-agent/src/core/tools/index.ts
export const codingTools: Tool[] = [readTool, bashTool, editTool, writeTool];
| 工具 | 职责 | 为什么够用 |
|---|---|---|
| read | 读取文件内容 | AI 需要知道代码长什么样 |
| bash | 执行 shell 命令 | 整个 Unix 工具链都是 AI 的延伸 |
| edit | 精确修改文件 | 修改现有代码 |
| write | 写入新文件 | 创建新文件 |
Pi 的哲学:不要为每个功能写新工具,让 AI 用 Bash 调用现有工具。
3. 自我扩展:技能系统 (Skill System)
核心思想:渐进式披露 (Progressive Disclosure)
// 启动时:扫描 SKILL.md 文件
export function loadSkills(options): LoadSkillsResult {
// 从 ~/.pi/agent/skills/、.pi/skills/、--skill 参数 加载
}
// 系统提示词中:只告诉 AI"有什么技能"
export function formatSkillsForPrompt(skills: Skill[]): string {
return `<available_skills>
<skill>
<name>pdf-processing</name>
<description>Extracts text from PDF files</description>
<location>/path/to/pdf-processing/SKILL.md</location>
</skill>
</available_skills>`;
}
// AI 按需加载:用 read 工具读取完整 SKILL.md
热重载:Skill 就是 Markdown 文件,读取即生效,没有注册过程,没有重启需求。
4. 实时干预:转向队列 (Steering Queue)
export class Agent {
private steeringQueue: AgentMessage[] = []; // 转向队列(紧急)
private followUpQueue: AgentMessage[] = []; // 后续队列(非紧急)
// 发送转向消息:中断当前执行
steer(m: AgentMessage) {
this.steeringQueue.push(m);
}
// 发送后续消息:等当前轮次结束后处理
followUp(m: AgentMessage) {
this.followUpQueue.push(m);
}
}
区别:
- steer:当前工具执行完后立即处理,跳过剩余工具(像开车时"现在转向")
- followUp:等 AI 这一轮完全结束后再处理(像说"下一站停")
可迁移经验:区分"紧急"和"非紧急",给用户"干预权"。
5. 没有外部记忆:代码即真理
拒绝向量数据库、记忆银行。
export interface CompactionSettings {
reserveTokens: number; // 预留 token 数(默认 16384)
keepRecentTokens: number; // 保留最近对话 token 数(默认 20000)
}
// 压缩策略:保留最近 N 个 token 的对话,更早的用 LLM 总结
export function findCutPoint(entries, keepRecentTokens) {
// 从最新消息开始累积 token,超过限制就切断
// 更早的内容会被 LLM 总结成摘要
}
摘要格式(结构化信息,不是向量嵌入):
- 目标
- 约束
- 进度
- 关键决策
- 下一步
可迁移经验:
- ✅ 结构化摘要优于向量检索
- ✅ 源码即真相:让 AI 直接读文件
- ✅ 渐进压缩:保留最近完整对话,旧的只保留摘要
可迁移经验清单
工具设计
渐进式披露
用户干预
记忆管理
相关笔记
- AI Editors - Index — AI 代码编辑器对比
- AI 辅助软件工程:实践与案例解析