数据截至 (上游 commit 565d53515b54)
oh-my-pi — 架构与原理(总览与阅读地图)
30 秒导读: oh-my-pi(命令行叫
omp)是一个装在终端 里的 AI 编码 agent——你打字说需求,它读代码、跑命令、改文件、调试器都能上。它是 Mario Zechner 的 Pi 的 fork,主打"开箱即全"(batteries-included):40+ 模型 provider、32 个内置工具、把 IDE 的 LSP/DAP 直接接进 agent。工程上分两层——TypeScript 做编排,Rust 做重活且在同进程内跑。本章只做全景和阅读地图,每个机制的原理交给后面六章。
本页定位: 这是 omp 子库的全长总览(子库总览);货架层另有一张同名的短卡片(
../index.md,只给一句话本质 + 阅读地图入口)。想要一句话判断相关性看短卡片;想在进任何一章前先建立全景,读本页。
1. 这是什么(零基础也能懂)
一句话定义: omp 是一个跑在终端里的编码 agent——你像跟同事聊天一样描述任务,它自己决定去读哪些文件、跑哪些命令、改哪几行,直到活干完。
解决谁的什么问题。 假设你在一个几十万行的项目里,想让 AI "把 formatBytes 改个名、顺带修掉调用点"。裸调模型做不到:模型只会说话,不会真的落到磁盘、不会知道你 IDE 里的符号引用。omp 补上的就是这套"手脚 + 感官":
| 模型缺的 | omp 补的东西 |
|---|---|
| 落到真实文件的能力 | edit / write / ast_edit 等 32 个工具 |
| 知道符号在哪、引用有几处 | 内置 LSP(14 类操作)、DAP 调试器(28 类操作) |
| 跑命令、开子进程 | 进程内的 Rust bash(brush shell)、grep、find |
| 换模型不掉链子 | 40+ provider,一个 /model 就切 |
用起来什么样。 三种最常见的启动姿势:
omp # 打开交互式 TUI,像聊天一样干活(默认)
omp -p "修好 CI 里失败的那个测试" # 一次性跑完就退出,适合脚本/管道
omp acp # 让 Zed 之类编辑器来驱动它
一句话直觉。 把 omp 想成"一个会用你整套开发工具的实习生":它有嘴(模型)、有手脚(工具)、有 IDE 的眼睛(LSP/DAP),而且这套工具箱是焊死 在它身上、开箱即用的,不用你一个个插件去配。
本节到此不碰任何代码细节。记住一件事:omp = 模型 + 一整套已经接好线的开发工具。
2. 顶层全景(它大概怎么转)
2.1 两层结构:TS 编排,Rust 干重活
omp 是个 monorepo,东西分两大层。看懂这张分工图,后面所有章节都好定位:
┌───────────────────────────────────────────────────────────────┐
│ TypeScript 编排层 (packages/*, 跑在 Bun 上) │
│ │
│ coding-agent ── CLI/TUI/会话/工具装配 (最外层,你启动的就是它) │
│ agent-core ── 回合主循环:prompt→模型→工具→再来一轮 │
│ pi-ai ── 统一 LLM 客户端 + 方言层 (40+ provider) │
│ catalog ── 模型目录:哪些模型、能力、等价关系 │
│ hashline ── edit 工具背后的补丁语言 │
│ tui/wire/utils/mnemopi/snapcompact/collab-web/stats/swarm ... │
└───────────────────────────┬───────────────────────────────────┘
│ N-API(同进程调用,无 fork-exec)
▼
┌───────────────────────────────────────────────────────────────┐
│ Rust 原生层 (crates/*, 编成一个平台标记的 .node 插件) │
│ │
│ pi-natives ── 聚合入口:grep / 剪贴板 / 图像 / 高亮 / PTY │
│ pi-shell ── 嵌入式 bash(brush)、PTY、进程管理 │
│ pi-ast ── tree-sitter 代码摘要(50+ 语言语法) │
│ pi-iso ── 任务隔离后端:APFS clone / reflink / overlayfs │
└───────────────────────────────────────────────────────────────┘
为什么这么切。 TS 适合写"决策与胶水"(解析参数、装配工具、管会话、和模型流式对话);而 grep、bash、语法解析这些又热又重的活,shell 出去调 rg/grep 会有 fork-exec 的往返开销、还依赖机器上装没装这些二进制。omp 把这些用 Rust 实现、通过 N-API 链进同一个进程,一次调用不再是一次进程启动(依据:根 README『Native Core』一节、packages/natives 的 N-API 绑定)。原生层的规模与"无 fork-exec"的确切范围见 05-native-core(实测约 6.2 万行 Rust,不含 vendor)。