earendil-works/pi 深度技术研究:从 4 个原子工具到 4 层扩展的代码级解剖
本笔记是对
earendil-works/pi的纵深研究,配合横向对比笔记pi-agent-vs-claude-code-codex.md食用。30k 视角放在那一份;这一份只挖实现层:源码文件分布、agent loop 主循环长什么样、4 个原子工具的真实参数与截断策略、系统提示与压缩机制的字符串原文、扩展生命周期事件名一一列举、Session 树的 v1/v2/v3 schema 演进、pi-ai 12 个内建 provider、pi-tui 差分渲染机制等。截至 2026-06-05,主线版本为 v0.78.1。
摘要
earendil-works/pi 表面是一个 ~60k stars 的 CLI 编码代理,本质是一套故意保持骨架级最小的 agent harness:核心由 4 个 TypeScript 包构成(ai / agent / coding-agent / tui,分别对应 npm 上的 @earendil-works/pi-ai、@earendil-works/pi-agent-core、@earendil-works/pi-coding-agent、@earendil-works/pi-tui),系统提示控制在 1000 token 以内,工具集只暴露 read / write / edit / bash 四个原子动作,整个低层 agent loop 据中文综述大约 1500 行代码 / 5 个文件(silenceper 综述),其余所有”产品功能”——MCP、subagent、plan mode、permission popup、todo list——一律下放给用户用 4 层扩展(skills / prompt templates / extensions / packages)自行组合。本笔记从代码结构层和设计原理层把这套机制拆开:哪几个文件在跑 agent loop、bash 工具是怎么截断输出、edit 是怎么避免并发改文件、Session JSONL 的 V1→V3 schema 怎么自动迁移、扩展事件总线上有哪些可阻断 hook、20+ provider 是怎么 lazy load、ChatGPT Pro / Claude Pro / Copilot 三种订阅 OAuth 怎么挂在同一个抽象层之下、pi-tui 又是用 CSI 2026 同步输出 + 三策略差分渲染做到无闪烁。最后给出与 Claude Code / Codex CLI 在实现机制层(不是产品功能层)的逐项对比。
项目身份与活跃度(精简)
详细身份见对比笔记,这一节只列与代码结构相关的少量事实。
- 仓库:
earendil-works/pi(旧名badlogic/pi-mono,2026-04 随 Mario Zechner 加入 Earendil PBC 后整体迁移;GitHub 已对旧 URL 做 transfer-redirect) - License:MIT
- 主语言:TypeScript(93.5%)
- 最新版本:v0.78.1(2026-06-04,226 个 release)
- stars / forks / open issues:≈59.9k / ≈7.2k / 45(GitHub 仓库主页)
- monorepo 包:
packages/{ai, agent, coding-agent, tui}4 个;这是 GitHub 上的目录名,对应 npm 包名分别为@earendil-works/pi-ai/pi-agent-core/pi-coding-agent/pi-tui。坐落在earendil-works组织下的姊妹仓库还有gondolin(microvm 沙箱)、pi-chat(IM 集成)、pi-review(评审扩展)、pi-tutorial(教程模式)、absurd(Postgres durable workflow 实验)等共 10 个仓(组织页)。
设计哲学:”Primitives, not products” 深度解读
pi.dev 主页的官方定调:*”Pi is a minimal terminal coding harness… Rather than shipping with pre-built features, Pi emphasizes letting users build what they need. The philosophy centers on providing ‘primitives, not features’.”*(pi.dev)—— 注意 pi.dev 主页用的是 “primitives, not features”,而 README 里更常见的措辞是 “primitives, not products”,社区中文综述则把它泛化成”五个 No”:
No MCP / No sub-agents / No plan mode / No permission popups / No bloated system prompts(CSDN 深度解读 by 程超)。
把这个哲学翻译成具体的代码取舍,可以归纳为四点:
- 核心包尺寸的硬约束 — 中文社区按文件数粗算
packages/agent/src/大约 5 个文件 / 1.5k LoC 就跑完整个 agent loop(agent-loop.ts/agent.ts/proxy.ts/types.ts/index.ts,仓库当前主分支与社区描述相符),任何额外功能都得放进上层包或扩展(silenceper 综述)。 - Token 预算的硬约束 — 系统提示 < 1000 token;对照 Claude Code 的 10k+,这是个两个量级的差距。代价是模型必须自己掌握编辑/搜索的常识,pi 不教,pi 只暴露工具(CSDN)。
- 责任倒置(trust the model) — 不内置 plan mode / sub-agent / todo 不是因为没需求,而是因为把这些做成内核会强迫一种工作流。pi 的态度是”把 4 个原子动作交给现代 LLM,让模型自己决定怎么组合”,需要 plan/subagent 的时候用扩展(仓库
examples/extensions/plan-mode/与examples/extensions/subagent/是官方示例)就好。 - 责任倒置(trust the user) — 对应”不做权限弹窗”。官方 README 直说:”Pi runs with the permissions of its launching user/process—there’s no built-in access control. For stricter isolation, the documentation recommends containerization using OpenShell, Gondolin extensions, or Docker approaches.”(README)这让 pi 在企业落地时有明显短板,但保持了 harness 层的纯净。
社区把这条路线和 Claude Code/Codex 形成的对照称为”fat harness vs thin harness“。与之对应,社区已经出现明显的”补完”型分叉项目,Oh-My-Pi(omp) 是其中代表:保留 pi 的 4 工具内核,但默认装齐 subagent / MCP / 权限层等”成品功能”(SegmentFault:Pi 极简 vs Oh-My-Pi 全能)。
4 包架构
packages/ai — 统一 LLM provider 层(@earendil-works/pi-ai)
依赖关系最底层,纯抽象 LLM 协议,不知道什么是 agent,也不依赖 tui。核心源文件(packages/ai/src):
1 | api-registry.ts # 注册/查找/卸载 ApiProvider |
注意:providers/ 里的文件数比 README 宣传的 “20+ providers” 少。原因是一个文件可以服务多个 provider——例如 openai-completions.ts 同时承担 Ollama / vLLM / LM Studio / DeepSeek / xAI / Groq / Together / OpenRouter / Hugging Face 等所有”OpenAI Completions 兼容”的提供商,靠 ~/.pi/agent/models.json 里 api: "openai-completions" + 不同 baseUrl 区分(docs/custom-provider.md 思路 + docs/models.md 显式)。register-builtins.ts 用动态 import() lazy 加载每个 provider 模块,并把 stream / streamSimple 两套接口都注册到中央 registry,这样 clearApiProviders() + resetApiProviders() 可以做到运行时换 provider 不重启进程(register-builtins.ts)。
packages/agent — Agent 运行时(@earendil-works/pi-agent-core)
中层,依赖 pi-ai,不依赖 coding-agent 与 tui。核心源文件(packages/agent/src):
1 | types.ts # AgentMessage / AgentTool / AgentEvent / AgentLoopConfig 定义 |
关键设计:把”低层循环”与”高层有状态 Agent”切开。agentLoop() 是纯函数风格的 EventStream 生成器,没有持久状态;Agent 类包一层,管 transcript / streaming flag / pendingToolCalls / errorMessages / steer 队列 / followUp 队列。文档明确:”Agent owns the current transcript, emits lifecycle events, executes tools, and exposes queueing APIs for steering and follow-up messages.”(agent.ts 摘要)。
harness/ 这一层是 coding-agent 走 SDK 路径时使用的”半成品 harness”,把 system prompt 构造、skills 加载、compaction 触发、session manager 整合在一起;如果你只是用 Agent + agentLoop(),可以完全绕过 harness 层。
packages/coding-agent — 交互式 CLI 与高层 SDK(@earendil-works/pi-coding-agent)
依赖 pi-agent-core、pi-tui、pi-ai,是用户实际跑的旗舰包。源码文件分布(packages/coding-agent/src):
1 | src/ |
注意四件事:
- 工具不止 4 个。除了广告里宣传的
read / write / edit / bash外,仓库tools/目录下其实还实现了find/grep/ls三个”helper 工具”。SDK 文档把它们也列出来了:*”Enable or disable built-in tools (read, bash, edit, write, grep, find, ls) or create custom tools”*(docs/sdk.md)。但它们默认不暴露给 LLM——coding-agent默认只把 4 个原子工具塞进 system prompt 与 tool-call schema;find/grep/ls主要给 SDK 集成方与扩展开发者用,模型可以调用bash自行rg/find/ls(system prompt 里有专门一句 “Use bash for file operations like ls, rg, find” 引导模型走 bash 而非内建工具,见下文)。 edit-diff.ts与file-mutation-queue.ts是为了让 edit 安全可重放。file-mutation-queue给所有写文件操作排队,避免同一会话里多个 tool call 并发写同一文件出现 race。extensions/目录是分层的:loader.ts负责发现 + 加载、runner.ts负责事件分发、wrapper.ts负责把 ExtensionAPI 适配到 Agent,types.ts是公开 API 类型。compaction/与export-html/单独分包,配合 docs/compaction.md 与 docs/session-format.md 共同把”上下文管理”与”分享”做成可独立替换的子系统。
packages/tui — 终端 UI 库(@earendil-works/pi-tui)
最底层与 pi-ai 平级、可被独立使用的包。源文件清单(packages/tui/src):
1 | autocomplete.ts editor-component.ts fuzzy.ts index.ts |
设计目标在 README 里说得很直接:*”a lightweight framework for building flicker-free interactive CLI applications using differential rendering and synchronized output.”* 关键能力包括 three-strategy 差分渲染、CSI 2026 synchronized output(让多行更新看起来像一次原子提交,从而消除闪烁)、Kitty/iTerm2 行内图像协议、IME 光标定位(CJK)、>10 行粘贴自动转占位符标签。
4 包依赖箭头
1 | tui |
四个包都可以独立安装与使用。具体的:pi-ai 可以单独做 LLM proxy 库;pi-agent-core 可以嵌入 Web/Desktop 应用;pi-coding-agent 同时暴露 CLI 二进制与 SDK 入口;pi-tui 也是独立 npm 包。
agent loop 与 4 个原子工具
启动一次 pi 命令到第一次 token 输出
把 main.ts → cli.ts → agent-session.ts → agent.ts → agent-loop.ts 串起来,发生顺序大致如下(综合 main.ts、agent-session.ts、agent-loop.ts 的官方/AI 摘要):
parseArgs()解析 CLI flags →SessionCreateOptions。readPipedStdin()检测 stdin 是否被管道喂入。createSessionManager()决定是新建 / resume / fork /--no-session,并打开/创建 JSONL 文件。createAgentSessionServices()装配 model-registry、settings、auth、resource-loader(加载全局/项目两层 settings + extensions + skills + prompts + themes)。system-prompt.ts:buildSystemPrompt()拼接:默认 prompt 头 + tool 列表 + guidelines + 项目 context 文件(AGENTS.md/CLAUDE.md)+ skills 索引 + 当前日期 + cwd。- 选择 mode:
InteractiveMode/runPrintMode/runRpcMode/ JSON 模式(按 stdin/--mode决定)。 - 实例化
AgentSession(运行模式都共享同一个),订阅 agent events,把每个 event 转写成 SessionManager 里的 entry 并 append 到 JSONL。 - 用户敲入第一条消息 →
Agent.prompt(messages)→agentLoop()把 messages 通过convertToLlmMessages()转成 LLM 协议消息 → 调用pi-ai的stream()→ 模型首 token 通过 EventStream 流回 → UI 渲染。
_runAgentPrompt 主循环(伪代码)
agent-session.ts 的核心方法是 _runAgentPrompt,根据 WebFetch 摘要 还原的伪代码:
1 | async _runAgentPrompt(messages) { |
而下层 agent-loop.ts 的 runLoop() 是双层循环架构:外层处理 follow-up 消息、内层处理 tool call + steer 消息(agent-loop.ts 摘要)。每次 LLM 调用前都会 validate context ends with appropriate message roles,避免 tool_use/tool_result 配对错乱。
4 个原子工具的真实 schema 与截断策略
read — 文本/图像读取(read.ts)
- 参数:
path(相对/绝对都行)、可选offset(1-indexed 行号)、可选limit。 - 默认上限:2000 行 或 4 KB(哪个先到先截)。
- 图像:JPG / PNG / GIF / WebP;自动 resize 到 ≤ 2000×2000;非 vision 模型会拿到一段 “image omitted” 的文字说明(避免把 base64 灌爆 context)。
- 特殊截断分支:源码注释里特意写道 *”First line alone exceeds the byte limit. Point the model at a bash fallback.”*——遇到一行就超 4 KB 的怪文件,直接劝模型改用
bash+head/sed。 - 可插拔后端:通过
ReadOperations接口可委派到 SSH / 容器 / 远程 VM;gondolin扩展正是用这个钩子把所有 read 路由进 microvm。
write — 文件创建/覆盖(write.ts)
- 参数:
path(兼容file_path别名,处理不同模型的 schema 漂移)、content。 - 行为:创建文件;父目录自动
mkdir -p;存在则覆盖。 - **
WriteHighlightCache**:每次渲染时增量做语法高亮,避免大文件被反复全量高亮。 - 并发安全:经过
file-mutation-queue排队,与edit互斥。 - AbortSignal 处理:每次
await后再检signal.aborted,避免半写状态。
edit — 精确文本替换(edit.ts)
- 参数:
path+ 一个edits数组,每个元素{ oldText, newText }。是精确字符串替换,不是 unified diff、不是 patch、不是 line-number 偏移。 - 预处理:BOM 剥离 + 行尾归一化(回写时还原原始 CRLF/LF)。
- 重叠校验:拒绝
oldText互相 overlap 的 edits。 - diff 输出:执行结果同时返回两种 diff —— 给用户 UI 看的”展示型 diff” + 给 LLM 后续 reasoning 用的 unified patch;并返回首个改动行号供编辑器跳转。
- Live preview:用户输入未提交时就能在 TUI 里预览将要应用的改动。
edit-diff.ts单独承担 diff 生成;**file-mutation-queue.ts** 防并发。
设计取舍很明显:
edit不做 fuzzy 匹配、不做 line-number、不做 patch。这把”上下文是否准确”的责任彻底压给模型——它必须先read拿到精确字符串。这种简单接口反过来逼 LLM 用更可靠的工作流(先 read 再 edit),并大幅降低工具执行失败率,是 pi 哲学的代表性体现。
bash — Shell 执行(bash.ts + bash-executor.ts)
- 参数:
command(字符串)、可选timeout秒数。 - 流式输出:
stdout+stderr实时回传;UI 节流到 每 100ms 刷一次。 - 截断:50 行 或 1 MB(先到先截)。截断时全量内容写 temp 文件,路径通过
fullOutputPath字段返回,模型可以在下一轮用read把 temp 文件内容拿回。 - Sanitize:剥 ANSI、把二进制乱码替换成可见字符、归一换行符;输出 buffer 上限
DEFAULT_MAX_BYTES * 2。 - AbortSignal:被取消时
cancelled: true+exitCode: undefined,与正常退出区分;底层走 process tree kill。 BashOperations接口:把”实际执行”抽到 interface 层,允许扩展把整个 bash 路由到 SSH / Docker / Gondolin microvm。- **
BashSpawnHook**:扩展可以在每个命令真正 spawn 前拦截并改写(典型用法:在git push前再确认一次)。
设计哲学层的特别说明:
bash是 pi 的真正逃生舱。模型如果发现 4 个工具不够用(要重命名、要 grep、要 build),就直接 bash。这把”工具列表庞大”的复杂度从核心搬到LLM 的常识——这也是 pi 把 system prompt 控制在 < 1k token 的根本前提。
与 Claude Code / Codex 工具集对照(实现层)
| 工具 | pi | Claude Code | Codex CLI |
|---|---|---|---|
| 读取文件 | read(2000 行 / 4 KB) |
Read |
内建 |
| 创建/覆盖 | write |
Write |
内建 |
| 编辑 | edit(多个 oldText/newText) |
Edit(含 Multi-Edit,类似机制) |
apply_patch(unified diff) |
| Shell | bash(50 行 / 1 MB) |
Bash(含 BashOutput、KillBash 子工具) |
shell(带 local_shell 类型) |
| 搜索 | 让 LLM 直接 bash rg/grep/find;内建 grep/find 仅 SDK 用 |
一等公民工具 Grep、Glob |
自带 |
| Web | 不内建(需 pi-web-access 扩展) |
WebSearch、WebFetch |
扩展 |
| Plan | 不内建(示例扩展 plan-mode/) |
一等公民 | 不内建 |
| Subagent | 不内建(示例扩展 subagent/) |
一等公民(多 subagent 并行 + 仲裁) | 不内建 |
apply_patch vs edit 的差别值得单独点出:Codex 把”让模型生成 diff”这个负担显式化,对应能力较强的模型上下文消耗更小;pi 把这个负担留给”模型自己组装 oldText/newText”,简单但容易漏字符串。
系统提示与上下文管理
默认系统提示原文
packages/coding-agent/src/core/system-prompt.ts 的默认 prompt 模板(WebFetch 抓取的 verbatim 字符串):
1 | You are an expert coding assistant operating inside pi, a coding agent harness. |
变量填充:
${toolsList}— 形如- read: <snippet>的 4 行(可被--exclude-tools/-xt减成 3 行甚至更少)。${guidelines}— 默认包含 3 条:- *”Use bash for file operations like ls, rg, find”*(仅当 bash 可用时拼入;这是把”搜索/列目录”显式劝退到 bash 的关键句)
- “Be concise in your responses”
- “Show file paths clearly when working with files”
- 用户通过
promptGuidelines/.pi/SYSTEM.md/ 自定义 prompt 追加的内容。
末尾自动追加:
AGENTS.md或CLAUDE.md内容(项目级 context 文件)+ skills 索引(仅 name + description,不含正文)+Today's date is YYYY-MM-DD+Current working directory: /path/to/cwd。
Token 预算实测:以默认 4 工具 + 3 guidelines + 没有项目 AGENTS.md 时,整个 system prompt 大约 400–600 token 区间,远低于 1000 token 上限。即便在所有 27 个 docs 路径都列出来的扩展 reference 段,也不会超 1k——因为这一段只是路径清单,模型按需 read 即可。
Compaction(自动压缩)
core/compaction/compaction.ts + utils.ts 实现两套机制(docs/compaction.md):
Compaction(沿主线压缩)
触发:上下文 token 超过
windowSize - reserveTokens(默认reserveTokens = 16384)。算法:从最新消息往前回溯,累加 token,直到
keepRecentTokens(默认 20000)。把更老的消息提取出来,序列化成文本(每条 tool_result 上限 2000 字符),喂一个独立 LLM 调用做摘要,写回成CompactionEntry添加到 session 末尾。SUMMARIZATION_SYSTEM_PROMPTverbatim(compaction/utils.ts):1
2
3
4
5
6You are a context summarization assistant. Your task is to read a conversation
between a user and an AI coding assistant, then produce a structured summary
following the exact format specified.
Do NOT continue the conversation. Do NOT respond to any questions in the
conversation. ONLY output the structured summary.注意 issue #5401 指出这里硬编码了 “AI coding assistant”,对非编码会话不够通用——这是当前的 known limitation。
结构化输出:摘要格式固定为 markdown 章节
goal / progress / decisions / critical context,并把 file operations 累计到details.fileOperations(这样多次压缩之后还能追溯哪些文件被改过)。Split-turn 处理:单个 turn 自身就超预算时生成两份摘要再合并,避免消息丢失。
Branch Summarization(切分支时压缩)
- 触发:用户在
/tree里跳到一个不同分支时。 - 算法:找当前活跃叶子与目标节点的最近公共祖先,把”被放弃的那一支”的所有 entries 收集起来生成
BranchSummaryEntry,附在新分支起点,让模型继续工作时仍能感知”被丢弃的那条思路”。
可定制点
两个 hook:
session_before_compact(扩展可阻断或替换 compaction,例如换更便宜的摘要模型)session_before_tree(同样可在 branch summary 前拦截)
reserveTokens / keepRecentTokens 可在 ~/.pi/agent/settings.json 里调(docs/settings.md)。
上下文窗口耗尽时的回退
_handlePostAgentRun 的代码路径里压缩失败/不足时:
- 触发自动重试(指数退避,可配置
maxAttempts)。 - 如果是
contextOverflow(已超窗),压缩成功后自动重试(return true)。 - 如果是
contextThresholdReached(接近超窗),压缩后不重试(return false)——等用户下一条消息再继续。 - 模型切换:
modelChange事件会跳过 overflow 检查(因为换模型可能换 window size),让用户手动决定是否压缩。
4 层扩展系统(重点章节)
pi 的扩展是分四层的洋葱模型,从外到内:”Skills(知识层)→ Prompt Templates(提示工程层)→ Extensions(运行时代码层)→ Packages(分发层)“。这一节把每一层的机制单独剖一遍,再讨论它们互相的边界与组合关系。
4.1 Skills — 按需加载的知识包(progressive disclosure)
数据形态
每个 skill 是一个目录,必含 SKILL.md,frontmatter 强制要求 name(≤64 字符、小写字母/数字/连字符、不能首尾连字符也不能连续连字符)+ description(≤1024 字符)。可选字段含 license、disable-model-invocation(设 true 后只允许 /skill:name 显式触发,不进 system prompt)(docs/skills.md)。
支持目录树嵌套;.gitignore / .ignore / .fdignore 都被尊重。Symlink 会用 canonical 路径去重。
Progressive Disclosure 的具体机制
core/skills.ts 的逻辑(综合 skills.ts 摘要 + docs/skills.md):
- 启动时扫描:
loadSkills()从 4 处加载——~/.pi/agent/skills/(用户级)<cwd>/.pi/skills/(项目级)- npm package 内的
skills/目录(来自package.json的pi.skills) - CLI
--skill参数显式指定的路径
- 进 system prompt 的只是索引:
formatSkillsForPrompt()把所有 skill 的name + description打包成 XML 风格列表附在 system prompt 末尾(可能形如<skills><skill name="..." description="..."/>...</skills>),不含 SKILL.md 正文。 - 匹配后才加载正文:模型如果决定使用某个 skill,会用
read工具去读对应SKILL.md的完整内容;或者用户手动/skill:name触发。这样”100 个 skills”在静态状态下的 token cost 还是可控(每个 skill 大约 50–100 token 的索引开销)。
Skills 与 Claude Code Skills / MCP 的对应关系
- Claude Code Skills:完全对标。pi 文档明确说 “Following the Agent Skills standard”,即遵循同一份
Anthropic-skills-spec。一个细微差异:pi 允许name与目录名不一致(在多工具共享 skills 目录时方便)。 - MCP:MCP 是协议层(外部进程提供工具/资源),Skills 是知识包(喂 prompt 文本 + 触发模型调用既有工具)。pi 不内建 MCP。社区
pi-mcp-adapter(≈99K 月下载)通过 extension 把 MCP 桥接到 pi(pi.dev/packages)。
4.2 Prompt Templates — /cmd 斜杠命令
prompt-templates.ts + docs/prompt-templates.md 的关键点:
- 形态:每个模板是一个
.md文件(可选 YAML frontmatter,含description/argument-hint),文件名决定命令名(review.md→/review)。 - 加载位置:
~/.pi/agent/prompts//<cwd>/.pi/prompts// npm package 内prompts// settings.jsonresourceLoader/ CLI--prompt。prompts/默认非递归,需要子目录得在 settings 显式开。 - 参数替换:bash 风格——
$1$2位置参数、$@/$ARGUMENTS全部参数 join、${@:N}${@:N:L}切片。 - 防注入:源码注释明确——*”Argument values containing patterns like $1, $@ are NOT recursively substituted.”* 用户传的参数不会被二次展开成另一个占位符。
4.3 Extensions — TypeScript 运行时模块
这是 pi 扩展系统里”代码量最大、能力最强”的一层。文件分布 src/core/extensions/: index.ts / loader.ts / runner.ts / types.ts / wrapper.ts。
加载位置
自动发现:
~/.pi/agent/extensions/*.ts(全局)<cwd>/.pi/extensions/*.ts(项目级)settings.json里resourceLoader.extensions: [npm:..., git:..., ./local]
ExtensionAPI 能力清单
来自 core/extensions/types.ts + docs/extensions.md + examples/extensions/README.md:
1 | interface ExtensionAPI { |
生命周期事件清单(从 types.ts 摘要 + docs 还原)
按出现顺序:
| 阶段 | 事件名 | 可阻断/可改写 |
|---|---|---|
| Session | session_start |
— |
| Session | session_before_switch / session_before_fork / session_before_compact / session_before_tree |
可 cancel |
| Session | session_shutdown |
— |
| Agent | before_agent_start |
可改 system prompt / 工具集 |
| Agent | agent_start / agent_end |
— |
| Turn | turn_start / turn_end |
— |
| Message | message_start / message_update(流式)/ message_end |
— |
| Tool | tool_call(参数已就绪、未执行) |
可阻断(→ permission gate) |
| Tool | tool_execution_start / tool_execution_end |
— |
| Tool | tool_result |
可改写返回值 |
| 模型/思考 | model_select / thinking_level_select |
— |
| 输入 | input |
可改写或拦截(→ input transform) |
| 队列 | queue_update(steer/followUp 队列变化) |
— |
tool_call 与 tool_result 的可阻断/可改写性是 pi 扩展能做”权限门 / 路径保护 / 输出 sanitize”的关键。例子见 examples/extensions/permission-gate.ts、protected-paths.ts、tool-override.ts。
ctx.ui 与 RPC 模式协议
事件 handler 收到的 ctx 提供 UI 原语:
ctx.ui.notify(text, level)— 火-忘式ctx.ui.select(options)/confirm(text)/input(prompt)/editor()— 阻塞式 dialogctx.ui.custom(component)— 用 pi-tui 组件渲染任意 UIctx.mode—"interactive" | "rpc" | "json" | "print",扩展可据此降级(v0.78.1 才稳定下来,release notes)ctx.getSystemPromptOptions()— 拿原始 system prompt 选项做检查
RPC 模式下 ctx.ui.* 走的是文档化 JSON 协议(docs/rpc.md),父进程实现这些方法即可在外部 UI(Web / 桌面)里弹出 select / confirm / input。
60+ 个示例扩展的概貌
examples/extensions/ 下 9 个子目录 + 70+ 单文件扩展。挑能反映扩展系统能力边界的几个:
- plan-mode/ — Claude Code 风 plan mode:bash allowlist(
cat/grep/ls/pwd等)+ 模型用Plan:header 列出步骤 + 完成时打[DONE:n],进度组件展示。/plan--planCtrl+Alt+P三种触发(plan-mode/README)。 - subagent/ — 委派任务给隔离 subagent,每个跑独立进程独立 context window;最大 8 任务、并发 4。内置 4 个角色:Scout(Haiku,快速侦察)/ Planner(Sonnet)/ Reviewer(Sonnet)/ Worker(全权)。
Ctrl+C可中断子 agent 进程(subagent/README)。 - gondolin/ — 把所有内建工具路由进 microvm;auth 留宿主、tools 进 VM。
- sandbox/ — OS 级沙箱(Linux Landlock / macOS Seatbelt / Docker),按项目配置。
- doom-overlay/ — DOOM 在 35 FPS 跑在 overlay 里。仪式性的”看 pi-tui 多能整活”展示。
- dynamic-resources/ — 用 resource discovery API 动态加载 skills/prompts/themes。
- custom-provider-anthropic / custom-provider-gitlab-duo / with-deps — 自定义 provider 的样板(前者带 OAuth)。
- 单文件(>60 个)覆盖
permission-gate.ts / protected-paths.ts / git-checkpoint.ts / git-merge-and-resolve.ts / github-issue-autocomplete.ts / ssh.ts / interactive-shell.ts / structured-output.ts / todo.ts / preset.ts / questionnaire.ts / handoff.ts / pirate.ts / snake.ts / tic-tac-toe.ts / space-invaders.ts。
一个隐蔽的设计点:例子里有完整 snake / tic-tac-toe / space-invaders 三个游戏,是 Mario 故意展示”扩展系统的表达力”——证明你可以在 agent harness 里嵌任意交互 UI。这种”博物馆式过度展示”在 Claude Code/Codex 里基本看不到。
4.4 Packages — 分发层
package.json 声明(docs/packages.md)
1 | { |
或者直接放约定目录(extensions/ / skills/ / prompts/ / themes/)即可被 auto-discover。
安装来源 4 种 + 命令对应
1 | pi install npm:@foo/bar@1.0.0 # → ~/.pi/agent/npm/<scope>__<name>/ |
管理:pi list / pi update / pi update <pkg> / pi remove。版本走的就是 npm semver / git tag。
安全模型(明确推卸责任)
文档原文:*”Pi packages run with full system access. Extensions execute arbitrary code, and skills can instruct the model to perform any action including running executables.”* 责任明确推到用户——审计自己装的代码。这是 pi 与 Claude Code/Codex 的”权限弹窗 + 文件白名单”路线最大的哲学分歧。
注:v0.78.1 引入了”安装目录权限收紧”——extension 安装目录改成私有 directory,至少避免他人写入;但运行时权限仍然等同进程。
与 Claude Code / MCP / Plugins 的对应
| 概念 | pi | Claude Code |
|---|---|---|
| 知识包 | Skills(SKILL.md) |
Skills(同标准) |
| Slash 命令 | Prompt Templates | Slash Commands |
| 运行时代码 | Extensions(TS) | Hooks(pre/post)+ MCP server |
| 协议工具 | 不原生(需 pi-mcp-adapter) |
MCP 一等公民 |
| 分发 | Packages(npm/git/local) | npm + Anthropic registry |
简化说法:pi 用一种统一机制(Extensions)覆盖了 Claude Code 的 Hooks + MCP + 部分 Skills,代价是用户自己写更多 TS 代码;好处是边界清楚(一切都是同一种 API),不需要在 hook / mcp / skill 之间纠结边界。
Session 树
V3 schema 与 JSONL 格式
docs/session-format.md + session-manager.ts:
每个 session 文件是 JSONL,每行一个 JSON 对象,含 type 字段。文件首行是 header(含 schema version、id、timestamp、cwd),其后是 entries。所有 entry 都有 id + parentId,”current position” 是被指向的活跃 leaf。
Schema 演进
- V1:纯线性序列(旧版 pi-mono 早期)。
- V2:引入 tree(
parentId)。 - V3:引入 unified custom roles(让扩展持久化的 entry 可以同时进/不进 LLM 上下文)。
migrations.ts 在打开旧文件时自动升级 schema。
Entry 类型枚举(综合 docs + session-manager.ts)
| 类型 | 含义 |
|---|---|
SessionMessageEntry |
一次对话 turn 的消息载荷(AgentMessage) |
CompactionEntry |
压缩生成的摘要(含累计 file operations) |
BranchSummaryEntry |
切分支时被丢弃路径的摘要 |
CustomEntry |
扩展持久化的非 LLM 状态(不进上下文) |
CustomMessageEntry |
扩展持久化的 LLM 上下文(进上下文) |
ModelChangeEntry / ThinkingLevelChangeEntry |
配置变更 |
LabelEntry |
用户给某个 entry 打书签 |
SessionInfoEntry |
display name 等元信息 |
buildSessionContext() 的还原逻辑
session-manager.ts 把”从 JSONL 还原 LLM 输入”做成一个明确函数:
“buildSessionContext() walks from the current leaf to the root, producing the message list for the LLM” —— 中间遇到
CompactionEntry时会用摘要 替换 它对应的原始消息段,遇到BranchSummaryEntry时会把摘要插入分支起点。
/tree /fork /clone /share /export 怎么做
/tree— 用 pi-tui 渲染整棵树,方向键导航、Ctrl+←/→折叠/展开。选中 user 消息会把它拷进编辑器(resubmit 模式);选中 assistant 消息则保留空 editor 续写。这就是树编辑的核心 UX。/fork— 把当前节点为根的子树拷到一个新文件,原文件不动。AgentSessionRuntime.fork()实现,支持before/at两种锚点。/clone— 复制活跃分支到新文件,但不切到新文件。/share— 把当前 session 上传成 GitHub gist 并生成可访问的 HTML 链接(实际工具是badlogic/pi-share-hf)。/export [file]— 渲染独立 HTML(包含 markdown / 代码高亮 / tool result 折叠等),用core/export-html/下的代码生成。注意 v0.78.1 修了一次 HTML 导出 XSS(URL sanitization),见 release notes。
与 HuggingFace 数据集的衔接
仓库 README 里说:”Public OSS session data helps improve coding agents with real-world tasks, tool use, failures, and fixes instead of toy benchmarks.”(README)
机制:用户 /share 后,配套工具 badlogic/pi-share-hf 把 session 上传到 HF 数据集 badlogicgames/pi-mono(沿用旧 owner,没改名)。这是 pi 想做”非 toy benchmark”的诚意所在。
隐私 / 数据治理
文档里没有自动脱敏。export-html 与 share 都包含完整的 tool input/output。XSS 修复是 v0.78.1 才有的(针对导出 HTML 时 URL 不被转义)。这意味着如果 session 里调用过含 API key 的命令,share/export 时 key 会跟着走。这是当前已知的硬限制,生产场景下应配合扩展手动 sanitize。
pi-ai:统一 provider 层
接口形态
pi-ai README 摘要:聚焦 tool-calling capable models;统一接口 stream() 与 complete();Streaming event 类型有 text_delta / thinking_delta / toolcall_delta;用 TypeBox schema 做工具签名 + 自动校验;支持跨 provider handoff(中途切模型保留上下文);图像 I/O;thinking/reasoning blocks;OAuth;context 序列化。
Provider 总览
packages/ai/src/providers/ 下源文件:
| 文件 | 服务 |
|---|---|
anthropic.ts |
Anthropic Messages |
openai-completions.ts |
OpenAI Chat Completions + 任意 OpenAI 兼容(DeepSeek / xAI / Groq / Together / OpenRouter / Mistral 兼容入口 / Hugging Face Inference / Ollama / vLLM / LM Studio) |
openai-responses.ts + openai-responses-shared.ts |
OpenAI Responses API |
openai-codex-responses.ts |
OpenAI Codex 通道(订阅 OAuth) |
azure-openai-responses.ts |
Azure OpenAI Responses |
mistral.ts |
Mistral 原生 API |
google.ts + google-shared.ts |
Google Gemini Generative AI |
google-vertex.ts |
Google Vertex AI |
amazon-bedrock.ts |
AWS Bedrock |
cloudflare.ts |
Cloudflare AI Gateway / Workers AI |
github-copilot-headers.ts |
GitHub Copilot OAuth headers 处理 |
openai-prompt-cache.ts |
OpenAI prompt caching 优化 |
transform-messages.ts |
provider 共用消息转换 |
simple-options.ts |
简化配置入口 |
register-builtins.ts |
lazy 注册全部 |
faux.ts |
测试 mock |
宣传里的”20+ providers”靠两个机制凑齐:**(a)** 一个 openai-completions.ts 文件覆盖任意 OpenAI 兼容服务;**(b)** 用户在 ~/.pi/agent/models.json 里配 baseUrl + api 类型注册自定义 provider。v0.78 系列陆续新增了 Ant Ling、NVIDIA NIM、MiniMax-M3、xAI、Moonshot Kimi 等(v0.78.0 / v0.78.1 release notes)。
三种订阅 OAuth
packages/ai/src/oauth.ts 是 export * from "./utils/oauth/index.ts" 的 re-export(oauth.ts),实际逻辑在 utils 子目录。从 docs/providers.md + release notes 整合:
- ChatGPT Plus/Pro(OpenAI Codex 通道) — 走
openai-codex-responses.ts,2025 年 OpenAI 把 Codex CLI 的订阅认证开放后接入。v0.77.0 起加 device-code flow 支持 headless(v0.77.0 release notes)。 - Claude Pro/Max — 走 Anthropic 的 OAuth flow,token 到期自动 refresh。
- GitHub Copilot —
github-copilot-headers.ts管 token;浏览器登录后 token 写~/.pi/agent/auth.json,过期前主动 refresh。
token 都存 ~/.pi/agent/auth.json,文件权限 0600。CLI flag > auth.json > env > 自定义 provider key 是优先级(docs/providers.md)。
值得注意:配置 value 支持动态值——!command 执行 shell 命令并缓存 stdout、$VAR / ${VAR} 环境变量插值、$$ / $! 字面转义。这让 secret 管理可以挂到 1Password CLI / vault 等工具。
与 LiteLLM / OpenRouter 的差异
| 对比项 | pi-ai | LiteLLM | OpenRouter |
|---|---|---|---|
| 形态 | npm 库(嵌入) | Python 库 + 独立 proxy server | 云服务 |
| 协议归一 | Anthropic / OpenAI / Google 三套并行,不强制翻译成 OpenAI | 全部翻译成 OpenAI 格式 | 全部翻译成 OpenAI 格式 |
| Tool calling | 一等公民、TypeBox schema | 一等公民 | 一等公民 |
| Thinking blocks | 一等公民 | 间接支持 | 间接支持 |
| 订阅 OAuth | ChatGPT/Claude/Copilot 三家 | 不主打 | 不支持 |
| 跨 provider handoff | 一等公民 | 不主打 | N/A |
最大差异:pi-ai 不把所有 provider 翻译成 OpenAI 而是保留各自原生协议——这是 thinking blocks / prompt cache / tool calling 在不同模型上能拿到最佳性能的前提。这也是它能直接接 ChatGPT/Claude/Copilot 三家订阅 OAuth 而不是只支持 API key 的根本原因。
pi-tui:差分渲染终端 UI
三策略差分渲染 + CSI 2026
pi-tui README 概述:
- Three-strategy 渲染:每帧只更新变化区域;具体策略有 “整行重写 / 行内 cursor 移动后局部重写 / 不变” 三档(具体阈值未在 README 公开,由实测结果驱动)。
- CSI 2026 同步输出(synchronized output):把多行 update 包在
\x1B[?2026h…\x1B[?2026l里,让 terminal 把整批 update 当成一次原子提交,消除高速刷新时的局部撕裂。这是 pi-tui 不用 Ink/React-style 双缓冲也能无闪烁的关键。 truncateToWidth()/visibleWidth()在保留 ANSI escape 的同时计算可见宽度——对接全角字符 / emoji / 颜色码必须做这步。- Kitty / iTerm2 行内图像协议:
terminal-image.ts自动探测协议,不支持就 fallback 到文本。 - IME 光标定位:
Editor组件给硬件光标定位,让 macOS / Windows / Linux 的 CJK IME 浮窗出现在正确位置。 - `>10 行粘贴 自动转占位符**:避免黏贴一大段日志时卡渲染。
与 Ink / Textual / Bubble Tea 的关系
pi-tui 完全独立——没有用 React / blessed / Ink,也不用 Charm 的 Bubble Tea(Go 系)或 Python 的 Textual。它就是一个手写的 TypeScript TUI 库。设计理念偏向”以 component class 为单位,每个组件实现 render() 返回字符串数组” + 主循环做 diff,与 Bubble Tea 的 Elm-style 比更命令式、与 Ink 的 React-style 比更轻量。
兼容性
- tmux / screen / 远程 ssh:基本兼容(OSC 8 hyperlinks v0.78.0 起在 tmux 内也能用,release notes)。
- Windows:v0.77 修过 MSYS2 启动兼容;issue #5394 还在跟踪 WezTerm(Windows)下 footer thinking-level 文字截断的 bug。
- Termux(Android):有专门 docs(docs/termux.md)。
生态:官方 / 社区扩展清单
官方仓库内(earendil-works 组织)
| 仓库 | 类型 | 说明 |
|---|---|---|
earendil-works/pi |
主仓 | monorepo |
earendil-works/gondolin |
microvm 沙箱 | QEMU/krun + JS 控制 VFS + 可编程出站策略 + 凭据占位注入 |
earendil-works/pi-chat |
扩展 | Discord/Telegram 集成,每个 channel 独立 Gondolin VM |
earendil-works/pi-review |
扩展 | /review /end-review 命令;支持 PR/branch/commit/folder 4 种 review 输入 |
earendil-works/pi-tutorial |
扩展 | 实验性教程模式 |
earendil-works/absurd |
实验 | 纯 Postgres 的 durable execution workflow(与 pi 路线相关但独立) |
earendil-works/website |
站点 | pi.dev |
社区扩展(由 pi.dev/packages 月下载量排序,截至 2026-05–06)
| 包 | 月下载 | 功能 |
|---|---|---|
context-mode |
≈121.5K | “MCP 插件,节省 ~98% context window”(沙箱执行 + 知识库搜索) |
pi-subagents |
≈103.2K | 任务委派给 subagent,支持并行 + 交互澄清 |
pi-mcp-adapter |
≈99.2K | 把 Model Context Protocol 桥接进 pi |
pi-web-access |
≈84.7K | web 搜索 + URL 抓取 + GitHub clone + PDF 提取 + 视频分析 |
rpiv-ask-user-question |
≈52.4K | 结构化问卷工具,让模型按 typed schema 提问 |
rpiv-todo |
≈33.2K | 持久 TODO 列表 |
pi-lens |
≈21K | 实时代码反馈(LSP/linter) |
数据来源:pi.dev/packages + TheAIEra 综述。社区还提到 OthmanAdi/planning-with-files(plan 自动执行 + attestation)、w-winter/pi-rewind-hook(基于 git ref 回滚)、dnouri/pi-coding-agent(Emacs 前端)等。
据中文综述(BAAI、2048ai.net)社区已经出现”补完”型 fork——**Oh-My-Pi (omp)**:保留 pi 的 4 工具内核,把 subagent / MCP / 权限层做成默认开。这是 pi 哲学激起的典型反弹。
未来与商业化
路线图(从 issues + release 节奏推断)
最近 1–2 个月的 issue 标签集中在三处(issue list):
- provider 修复(高频):
maxTokens映射错误(#5331)、zai thinking 参数错误(#5330)、Vertex GCP metadata server 支持(#5323)、新 provider 申请(#5363)。这反映 pi-ai 的”统一 + 模型无关”承诺会随每个新 provider 引入回归压力。 - 可观测/可集成:
Expose when Pi is waiting on user input for host integrations(#5329)、Allow custom OAuth callback page rendering(#5372)。说明 RPC 模式被越来越多 host 应用集成,他们要更细的 hook。 - 跨平台/SDK 路径:#5350 报告 SDK 自定义工具拿到的是 host OS 解析后的路径,Windows host 接 Linux 远程文件工具会断裂——这是 pi 跨 OS 路径处理一致性的硬骨头。
possibly-openclaw-clanker label(出现在 #5350)暗示 pi 团队对来自 fork(OpenClaw 是 pi 的下游)的”机器人式 issue”有专门标注——这本身揭示了一件事:pi 的下游已经形成一定规模的二次开发生态,团队需要专门 triage。
Earendil 的商业化方向(推测)
公开信号:
- 组织页 tagline “Bearer of Light” + Tolkien 的 Eärendil(迷雾之海上指引航道的星)暗示主理人偏向”基础设施 / 工具”路线,不是产品向。
- 主理人 Armin Ronacher(Flask 之父,Sentry 出身)公开发文《I’ve sold out》解释加入 PBC 的动机(changchen.me 中文解读),核心是希望把”基础设施级 AI 工具”做成可持续的 PBC 而非传统 VC 公司。
gondolin(microvm)+absurd(durable workflow)+pi-chat(Discord/Telegram) 三块在做”可托管的 agent 执行环境”——典型的 SaaS 雏形。- 截至 2026-06,没有公开的商业产品页 / 价格表 / SaaS 入口。
合理推测路线图:先靠开源建生态、靠 PBC 拿与 VC 不同的资金(行善让利的 LP 圈),后续可能围绕 “managed Gondolin sandbox + pi-chat / pi-review 等扩展”做 SaaS。但这是推测,不是公开声明。
Mario Zechner 的设计 rationale
直接英文一手资料(如 Mario 的个人博客 / Twitter 长文)截至本笔记发稿在公开搜索里没有完整命中。中文社区综述(CSDN by 程超、silenceper、BAAI)转述的几条要点:
- “做 pi 的起因是对 Claude Code 频繁 update / 行为漂移的不满”——希望有一个”我能完全掌控、产品行为不会被官方一夜改掉”的 harness。
- “现代 LLM 已经足够聪明,不需要 fat prompt 来教它做事;4 个原子动作 + bash 兜底足够解 90% 编码任务”。
- “MCP 太烧 token——Chrome DevTools MCP 一上线就吃 18K context,对单用户 agent 是无谓开销”。
- “subagent 是底层 primitive 而非应用——你要 subagent 自己 spawn
pi.exec()即可”。
这些表述是中文综述的翻译/转述,不是 Mario 的原话引用。如果以后能找到他的英文一手贴,应替换本节。
已知局限与社区抱怨
综合 issue list 与社区评测(2048ai.net、CSDN、SegmentFault):
- 学习曲线陡 — “blank canvas” 风格让初学者无所适从;要先知道自己想要什么扩展。
- 没有内置权限 / 沙箱 — 默认 YOLO 模式;要安全得自己上 Gondolin / Docker。社区批”过于宽松”,主理人立场是”传统 permission popup 是 security theater”。
- TUI 美学被批 ugly / unintuitive — 相比 Cursor / Claude Desktop GUI 不够”漂亮”,主理人立场是”TUI 的 simplicity 与透明度匹配 pi 哲学”。
- 社区扩展质量参差 — 部分 PR 含 AI 生成代码,仓库已强化 audit;issue #5350 的
possibly-openclaw-clankerlabel 是这个问题的具象化。 - 依赖冲突 / Build 失败 —
protobuf/numpy等版本不兼容偶发;force-pushed git 仓库的扩展更新失败(PR #961,旧仓 URL)。 - non-coding 场景不通用 —
SUMMARIZATION_SYSTEM_PROMPT硬编码 “AI coding assistant”,做非编码任务时摘要策略不太合适(#5401)。
与 Claude Code / Codex CLI 的实现机制对比
这一节不重复对比笔记的”产品功能”层对照;只看实现机制层面的差异。
| 实现机制 | pi | Claude Code | Codex CLI |
|---|---|---|---|
| 语言 / runtime | TypeScript(Node + 可选 Bun) | TypeScript(Node) | Rust 核心 + Node CLI 包装 |
| 主仓代码量级 | 4 包 / pi-agent ~1.5k LoC 内核 + ~数万 LoC 上层 | 闭源 | codex-rs/ Rust + codex-cli/ + mcp-server/ |
| Agent loop 形态 | EventStream + 双层 loop(follow-up 外、tool 内) | 闭源 | Tokio 异步 + Ratatui TUI |
| 默认工具数 | 4(read/write/edit/bash) | ~10+(含 Read/Write/Edit/MultiEdit/Bash/BashOutput/KillBash/Grep/Glob/Web*/Plan/SubAgent) | ~5+(含 shell/local_shell/apply_patch/…) |
| 编辑机制 | 多个 oldText/newText 精确替换 | 同源思路(Edit / MultiEdit) | apply_patch unified diff |
| Bash 输出截断 | 50 行 / 1MB,超时 + 全量 temp 文件 | 类似(具体阈值闭源) | 同档(具体闭源) |
| System prompt token 预算 | < 1000 | 10k+(含 plan/skill/MCP 描述) | 中等(不含 MCP 时较小) |
| 上下文压缩 | 自动 + 可阻断 hook | 自动 + skills/AGENTS.md 长记忆 | session resumption |
| 扩展机制 | TypeScript 模块(同时承担 hook + tool + UI + provider) | Skills / Hooks / MCP 三套 | MCP(client+server 双向)+ 命令白名单 |
| 沙箱 | 不内建(OpenShell / Gondolin / Docker 三选一) | plan mode + permission prompt | OS 级:macOS Seatbelt、Linux Landlock+seccomp、Windows WSL2 |
| 订阅认证 | ChatGPT Pro / Claude Pro / Copilot 三家 OAuth 同时 | 仅 Claude(自家) | 仅 ChatGPT(自家) |
| Session 形态 | JSONL 树(v1/v2/v3 自动迁移)+ /tree /fork /clone /share | 文件级 memory | session resumption + prompt 库 |
| TUI 实现 | 自有 pi-tui(差分渲染 + CSI 2026) | 闭源 | Ratatui(Rust) |
| Skills 实现 | progressive disclosure(只放 name+desc 进 system prompt) | 同思路 | N/A |
实现层最关键的三处差异:
- System prompt 预算差两个量级(pi <1k vs Claude Code 10k+)—— 决定了 pi 必须把”工具足够正交、模型必须懂常识”作为前提。
- Edit 接口:pi 的”多对 oldText/newText” vs Codex 的
apply_patchunified diff vs Claude Code 的 Edit/MultiEdit。三者背后是”让模型负担 vs 让工具负担”的不同选择。 - 扩展的统一性:pi 用一个 ExtensionAPI 同时覆盖 hook / tool / UI / provider;Claude Code 把 Skills / Hooks / MCP 切成三套独立机制;Codex 把 MCP 推到中心、其余靠白名单。pi 的统一性让边界清楚,但代价是新手要写 TS。
不确定性
<1000 token的实测值不在仓库 docs 里。这个数字来自中文社区综述(CSDN / silenceper);本笔记沿用,但若用tiktoken真测一次,结果可能在 600–1000 区间漂动,且会随项目 AGENTS.md 是否存在剧烈波动。- agent loop “5 个文件 / 1.5k LoC” 是中文综述的描述。仓库当前
packages/agent/src/实际有agent-loop.ts / agent.ts / proxy.ts / types.ts / node.ts / index.ts6 个文件 +harness/子目录,LoC 也未实测;本笔记把这条标为社区描述、不当作精确事实。 SUMMARIZATION_SYSTEM_PROMPT我抓到了 verbatim,但 issue #5401 暗示后续可能改名/重写——本笔记引用的是 v0.78.1 当前版。- Mario Zechner 的英文一手 blog/Twitter 长文 没有命中。中文转述算二手。如果用户能给到原始链接(personal blog / Twitter thread),应替换。
- Earendil PBC 的商业化方向 完全是从仓库结构推测,不是官方声明。SaaS / 托管沙箱仅是合理猜测。
pi-share-hf的现状:HuggingFace 数据集badlogicgames/pi-mono还在用旧 owner / 旧名,更新节奏与新仓 release 节奏是否同步未确认。- OAuth 三家 token refresh 的具体参数(refresh window / retry policy)需要去看
packages/ai/src/utils/oauth/子目录,本笔记没抓到该层源码。 - pi-tui 的”three-strategy 渲染”具体三档阈值 README 没披露,本笔记按”全行重写 / 局部 cursor 移动 / 不变”做了合理还原,但不是源码字面意义。
- 社区扩展月下载量 来自 pi.dev/packages 当前快照,会随时间变化。
- OpenClaw 的实际下游影响:搜索结果反复出现 “pi 下游 OpenClaw 在 2 个月内拿到 210k stars” 的说法,本笔记未独立验证 OpenClaw 仓库当前的真实 stars / 与 pi 的代码继承关系。把
possibly-openclaw-clankerlabel 视为 pi 团队对该下游的客观存在的反应即可。
后续行动
- 用
tiktoken实测 v0.78.1 的默认 system prompt token 数(带/不带 AGENTS.md 两组)。 - 在本机跑一次
wc -l packages/agent/src/**.ts验证 1.5k LoC 的说法。 - 把
gondolin在本机搭起来,跑 5 条bash命令验证凭据隔离 + VFS 控制的实用强度。 - 单独追:
packages/ai/src/utils/oauth/三家 OAuth refresh 的具体参数。 - 把
pi-mcp-adapter在本仓装一次,对照 Claude Code MCP 一等公民,量化 token 消耗差异。 - 跟 issue #5401 的修复——若 SUMMARIZATION 走向”按场景分支”,对长程非编码任务表现可能改善。
- 跟 v0.79.x 的 release notes,看 sandbox / 权限层是否会”软化为内建可选”——这关系到 pi 哲学是否在企业落地压力下让步。
- 找 Mario Zechner 的英文一手 blog/Twitter,替换中文综述转述。
来源
仓库与官方 docs
- earendil-works/pi — GitHub 主页
- earendil-works 组织页
- pi.dev — 官方站
- pi.dev/packages — 社区扩展目录
- pi monorepo README
- packages/coding-agent README
- packages/ai README
- packages/agent README
- packages/tui README
- docs/index.md
- docs/extensions.md
- docs/skills.md
- docs/packages.md
- docs/sessions.md
- docs/session-format.md
- docs/providers.md
- docs/containerization.md
- docs/sdk.md
- docs/compaction.md
- docs/prompt-templates.md
- docs/usage.md
- docs/keybindings.md
- docs/settings.md
- docs/models.md
- docs/json.md
- docs/rpc.md
- docs/development.md
关键源码文件
- src/core/system-prompt.ts
- src/core/agent-session.ts
- src/core/agent-session-runtime.ts
- src/core/session-manager.ts
- src/core/skills.ts
- src/core/prompt-templates.ts
- src/core/event-bus.ts
- src/core/bash-executor.ts
- src/core/tools/bash.ts
- src/core/tools/read.ts
- src/core/tools/edit.ts
- src/core/tools/write.ts
- src/core/compaction/compaction.ts
- src/core/compaction/utils.ts
- src/core/extensions/types.ts
- packages/agent/src/agent-loop.ts
- packages/agent/src/agent.ts
- packages/agent/src/types.ts
- packages/ai/src/providers/register-builtins.ts
- packages/ai/src/oauth.ts
- packages/ai/src/api-registry.ts
示例扩展
- examples/extensions/README.md
- examples/extensions/plan-mode/README.md
- examples/extensions/subagent/README.md
Release Notes & Issues
- Releases 列表
- v0.78.1 release notes
- v0.78.0 release notes
- v0.77.0 release notes
- Open issues
- Issue #5401 — SUMMARIZATION_SYSTEM_PROMPT 硬编码 “AI coding assistant”
- Issue #5394 — Footer 在 WezTerm(Windows)截断
- Issue #5350 — SDK 自定义工具收到 host OS 解析后的路径
- Issue #5331 — pi-ai 的 maxTokens 映射错误
- Issue #5330 — zai provider thinking 参数错误
Earendil 姊妹仓库
- earendil-works/gondolin — Linux microvm sandbox
- earendil-works/pi-chat
- earendil-works/pi-review
- earendil-works/pi-tutorial
- earendil-works/absurd
第三方综述与社区
- silenceper — Pi Coding Agent Harness 综述
- CSDN/程超 — pi-mono 4 个原子工具源码解读
- TheAIEra — There Are Many Agent Harnesses, But pi.dev Is Yours
- SegmentFault — Pi 极简 vs Oh-My-Pi 全能主义
- BAAI — Pi 设计 rationale 解读
- 2048ai.net — Pi 安全与扩展性争论
- Juejin — Pi 是什么:一个极简、能自己长大的 AI 编程 Agent
- changchen.me — Mario Zechner 加入 Earendil 的中文解读
- w-winter/pi-rewind-hook — 社区扩展
- dnouri/pi-coding-agent — Emacs 前端
- planning-with-files release tracker