深入 Pi:一個極簡主義 AI 編程框架的設計
发布于 2026-02-12 00:20:53(微信公众号导出记录)。
本文来自公众号后台的“导出文章内容”功能。博客正文由导出长图进行本地 OCR 转写,并保留原始排版图用于逐段核对。
原文链接:查看原文
OCR 转写有效文字约 5224 字;代码、流程图和版式以文末原始排版图为准。
正文(本地 OCR 转写)
最近在研究各种AI编程助手,偶然控到了一個叫Pi的项目。 今天就把对道個项目的分析整理一下,聊聊Pi是怎度想的,又是怎度實現的。 先聊聊Pi是什 用一句职:P1是一套「榮高精木式的AI工具套件。 跟别人把所有功能塞进一因大monol1th理不同,P1把束西拆成了好袋回狮立的包: 你會直接用的 mom coding-agent 命令行工具 Slack 概器人
核心底座 给用發者用的 agent-core web-uf 终UI Agent 证行時 Web 组件
LLM统一接口
這様做的好虑是什磨?每因包都可以单拿来用,想怎磨拼就怎磨拼。你要做国自己的AI助 手?直接用agent-core。要做個瑞工具?加個tui就行。不需要把整個大都莲走。
一個具體的感受
我第一次用的時候,最震撼的是它的要活性。比如我想用Google的Gemin1,但之前的代强
只能跑在内频的OpenAI兼容接口上—换成别的工具可能就要配置一堆境量或者改配青文
件,但在Pi理就一行代码的事:
const model = getModel("openai-conpatibilities*, ny-internal-model, {
baseurl: "https://internal .company.com/v1*
这種!不绑死任何束西;的感觉,真的很好。
架構的核心:一個雙層循環
P1的Agent遥行時有個很有意思的設計一斐唇循垢。我一陶始看源碼的时候有黏悟,为什座
要摘雨厚?後来琢磨明白了,這是為了支持雨疆插入消息:的機制
来看图:
用户验送消息
有 Steeing 消息鸣? 有:用户在等我 先虑理注典 有 胡用LLM
LLM决定 铜用工具? 要调用 轨行工具
用户又喻入 不期用 了乘西?
通有工具? 跳泌剩下工具 有
有 Follow-up 消良瞩?
SteeringvsFollow-up:為什要區分? 这個設計我觉得挺巧妙,曾单:
- Steering:你现AI走偏了,想馬上纵正。這種消息窗插陈:,掌前工具敦行完就虑
理,剩下的工具都不做了。
- Follow-up:你援AI醉完道事後再醉那事。道種消息乖乖排除,等AI完全間下来再
滤理。 攀個例子:你旗AI你重横一段代码。结果發现它開始别文件了,你赶装输入“停下别 到:。道就是Steering-立刻打。但你也可以「重完後我個测试:,这就是 Follow-up—按部就班。 在终端理:
-
按Enter =Steering(插原)
-
按Alt+Enter=Follow-up(排陈)
这種细微的交互差翼,现的是封用户意圈的精確理解。 事件疆動:一切都是流 另一個我觉得設計得好的地方是事件系统。整個Agent谨行時就是一個事件發射器,外维想 随就订阳: 德就打用:
这有什度好滤?解耦。TUI 不用知道Agent内部怎度跑的,只需要事件就行。你想加图 日喆?訂開事件就好。想做因進度條?也訂開事件。 這種设計旗摘展得超级單一你不需要改核心代碼,排烟事件监器就完事。 工具系統:簡单但強大 P1给 AI的工具挺有意思的,就展园最基本的:read、vrite、edit、bash、greP find、ls.没有花裡胡脂的束西。 但每個工具都設計得很考究, read工具的小细節 馨因例子,read工具不只是单地文件: 调用read
是圆像 格式?
測真實類型
检查是否支持 不確定 讀文本 支持
缩放到2000x2000 文件太大?
截取前部分 编碼为base64 否
返回给AI 公众 你看,一個髓单的“错文件!!
-
官自勤别图像亚虑理
-
會检查文件大小,太大就藏断(默308行或38KB)
-
支持分页额取(offset/Limit)
遗些组颌體现的是對生產境的考——AI真的用到这個工具的時候,不會因為一個频百MB 的日融文件就了。 工具接口的設計 工具的接口定美也很值得學智: interface AgentTool<TParameters> { 工具名 Label: string: //期示模 description: string: //始AI 看的就明 parameters: TSchcma; //参数Schcna(用於验) execute:( tootcallId: string. parans: TParaneters, signal?: Abortsignal, /可以中斯 onupdate?:(partial:any)=> vuid // 部分结果回调 = Pronisc<AgentToolResult<TDetails>>;
雨個設計亮點: 参数:用乒按CtrL+C的時候,正在行的工具能收到中断信號,可以做清理工 signal 作 onUpdate回調:支持增量更新。比如bash工具執行一個耗時命令,可以一遗執行一遗 把输出吐出来 这整個交互感凭很「活」,而不是發個請求就乾等。 會話管理:一棵樹的哲學 P1的會括存是因很有意思的設計。它不用多但文件存不同會話,而是把所有束西放在一個 JSONL 文件理,用parentId横成一模樹: 遭次對括的根 我:其管我想用Python 我:智我富伍排序 我:聚我客住排序 qd3ser 量 : Al: 好的用 JavaScript Al:或者用Go Al: 好的用 Python Al: 期用了 write 工具 Al: 寫了 Python 代碼 处:行租 Al: 期用了 bash 工具 為什要這做? 傅统做法是每個會話一個文件,想分支就復制一份。但P1的做法有费圆好處:
1.不浪囊空間:分支不需要復制整困文件,只需要記疑新的parentId
?.可以跳到任何節點:始入/trec,曾期示整模,遇任何一因郁贴都可以提那程“增續
3.墨也方便:盖的窗話可以继结成一CompactionEntry,不占上下文
/tree命令的體驗 运個功能真的好用。有時候你跟AI對适聊得了,想回到五输之前那個状然—不用重新睛個宝 話,直接/tree找到那個部點,远中继就行。整棵树的所有分支都在那理,歷史清活楚 楚。 这種设計我想到Git。鞋然存形式不同,但本货上都是“不可的歷史+指舒。 LLM抽象層:一個接口統治一切 P1 最强大的地方之一是射告種LLM 提供商的支持。OpenAI、Anthrop1c、Google、AbS Bedrock,Azure, Mistral...有 15+ 个 但神奇的是,你用的時候根本感觉不到差翼: 你的代碼 Pi统一层 session.prompt Agent Model 接口 宽现 青现 各種實现 Ilvuado 壹现 Anthropic Google Bedrock
怎做到的? 核心是定了一個Model接口,然後每细提供商去實现它。但显精巧的是strean5.inple 这個函敏—不管底恩API怎度梯,最後都酮成统一的事件流: 11所有提供商都逐回程事件 type Event = |{ type: start*; partial: AssistantMessage } | { type: “thinking_delta'; text: string ) |{ type: "toolcall_start';...} |{ type:done*} 遗檬上就不用管你是用OpenAI遇是Anthropic,虑理方式完全一楼。 為什这重要? 想像一下你公司的要求:必须用Azure OpenAI。但你在家暂情用Anthropic。换成别的工 具可能要改一堆配置,但在P1程就是换個modelID的事。 甚至道可以混著用: 接Ctr+P切旗
遗種霍活性在實原工作中真的很有用。 展系统:無限可能 我覺得P1最牛湿的地方是它的摘展系统。它不只是“支持插件:,而是把整圆系统做成了完 全可编程的。 展能幹什? 乎什座都能: agent_start tol_call 装换内建工具 事件验 替换编辑器 注民工具 自定覆操作 白定菱UI 搞展能力 添加状练橱 注用命令 自定羲灌染 非数解析 剩然操作 注册快捷键 路径遇薄 和内建共存 摧限查
一個簡單的例子
假設你想加因「部善到生產的工具: /// ,pi/agcnt/ cxtensfons/deploy t5 export default function (p1: ExtensionAPI){ //鞋得一留工具。AI可以原用 留工具,AI 可以旗用 pi.registerTool(( name: deploy_production, 'uotonpoud Aoldap. oueu description:“部置代码到生叠喂境”, 量 paraneters: ( type: object", properties: { confirm: { type: “boolean" } execute: async {{ confirn }1=> { if (!confinm){ “需要程才能部 return { content: [f type: text: 1贵账部著通辑 amait runDeplay(); return {content:[{ type:“text*, text:“邮黑成功")]}; }1: 签愿事件,每次bash敦行都配疑一 pi.on("taol call", asyne (event) => { if (event.toolName == *bash"){ console.log行命令:${event.args.command}); ({
就遗磨商单。存成文件,下次敏勤pi就自勤加载了。 携展加載的個来源 Pi會提据固地方找摘展:
揭流查地方 g安装 npm 安装
-
/.,p/agent/exter
-
pl/extensions/
全是的 项目本地的 加截益快行 挂册到原织 設計银分享接展得很简單——發图npn 包就行,别人piinstallnpm:your-packag 就装上了。 設計哲學:Pi跟别人哪狸不一檬 研究了运磨久,我景得Pi最特别的是它的設計哲學。在其他工具都在做加法的時候,它在微 减法。 它明確不的束西 這些是Pi官方文棉理明硫说「不微:的: 别人怎度做 Pi的服度 功能 Sub-agents 内建 用摄展實现,或間tmux 内建 用摘展實现 Plan node MCP 内建或大力支持 不解你做,但你可以寡展 弹出確框 内建 用Docker/客器,或自已展 用TODO.md文件,或自己摘展 Todo系统 用tmux 横台任释 内建 我资得這種“明碴说不:的魅虚挺好的。很多工具什磨都想做,结果成一個大鞋煌。P1知道 自己旅做什度,不该做什磨, 為什这檬設計? P1的作者Maria Zechner 宽過一篇博客解這。核心截贴是: 適愿你的工作流,而不是你適磨工具。 個例子,Sub-agents:
-
Cursor/ClaudeCode 有自己的實现,但你改不了它
-
Pi就:你可以開多個tmux pane,每個跑一個pi,想怎度作就怎度作
-
或者你寫個58行的提展,實现你自已想要的sub-agent 退辑
後者更露活,但需要你勤手。P1的假設是:用这個工具的人都是開狼者,有能力也有需求自己 定制。
一個對比表格
極簡核心
展一切 靈活但需要動手
完全可定製 用户掌控
傳统路 功能豐富
固定工作流 開箱即用
學智成本低 工具掌控
没有對,只是取舍不同。Pi選握了『给有需求的人充分的自由。 實際使用的體验 我用了這度一段時間,就就真實感受。 好的地方 L.终端原生髓验:就是一個CLI工具,不會有各種IDE的定和限制
2.模型切换超快:CtrL+L打開进挥器,想切哪家切哪家
3.會話树真的好用:聊偏了的時候直接跳回来,不用重新開會話
1.寫展很直觀:TypeScript,API清晰,文權用
需要適的地方 l.入同有門:如果你不熟悉TypeScript 或CLI工具,可能需要點時間
2.需要自己勤手:想要planmode?自己撰展或找别人寫好的包
3.文檔主要是英文:對中文用户不太友好
一個具體的使用場景
個我最近的例子:我想AI葡我密查一段代碼的安全性,但不希望它能修改任何束西。 只给它權限的tool
这種粒度的控制,是很多其他工具做不到的。 對開發者的發 看完Pi的源碼,我有點收稚:
1.抽象層次很重要
Pi把束西分成了三履抽象:
LLM抽象層 统一各種API
Agent抽象層 封装工具和狀態
UI抽象層 獨立的渲染系統
每一都可以立化。想换LLM提供商?只動L1。想换UI?只動L3。这種設計整個 系统很穩定。
2.事件動是解耦的法實
P1的核心和UI之間筹乎没有直接依赖,全靠事件通信。这你可以随便换UI组件— 端、Web、甚至自己寫個 GUI.
3.善用「不做的清單
很多產品不敢「我們不做這個」,怕用户凳得功能少。但P1明確列出了它不做的束西。这 其實是一種自信——核心钩强,用户可以自己實现剩下的。 寫在最後 Pi不是一個「開箱即用到無腦程度的工具。它更像是一個『给開發者的工具套件」——你需要 花點時間理解它,但理解之後,它的上限非常高。 如果你只是偶爾用用AI忙寫代碼,Cursor 或 Claude Code 可能更適合你。但如果你 是固重度用户,有自己的一套工作流,或者想做點自己的束西一Pi很值得一試。 它的核心承諾很單:我不會强迫你按我的方式工作,我给你足购的能力去實現你的方式。
原始排版图
原始导出图超过单张 WebP 的尺寸上限,以下图片按从上到下的顺序连续保存。
![]()

