跳到正文

目录

oh-my-pi:把 IDE 接进 Agent 循环的终端 Coding Agent

oh-my-pi:把 IDE 接进 Agent 循环的终端 Coding Agent

它解决的是 harness 问题,不是模型问题

同一个模型,换一个 agent 外壳,编辑成功率可能相差十倍——oh-my-pi(下称 omp)的作者把这称为 harness 问题:瓶颈往往不在模型,而在模型之外的那层执行环境。多数 coding agent 的编辑工具靠行号或旧文本做锚点,模型一旦找错位置就进入"改错—重试—再改错"的循环;调试靠在代码里插 print;搜索要 fork 一个 grep 子进程。这些损耗全部发生在模型之外。

omp 的做法是把这层执行环境直接重写:LSP、调试器、shell、文件搜索、AST 重写全部做成 agent 的内置工具,其中搜索、shell、AST 等热路径用约 8 万行 Rust 实现,运行在进程内,没有 fork/exec 开销。它 fork 自 Mario Zechner 的开源项目 Pi,由 Can Bölük(GitHub 用户 can1357)重写为 coding-first 形态,MIT 协议,版权归属作者与 Stencil Labs, Inc.。

衡量这套重写是否有效,最直接的证据是编辑基准:Grok Code Fast 1 的编辑一次通过率从 6.7% 提升到 68.3%,换的只是编辑格式,模型权重没动。下文的 benchmark 一节会解释这组数字该怎么读。

项目速览

项数据(截至 2026-09-15)
GitHub Stars31,135(仓库 2025 年 12 月 31 日创建)
语言构成TypeScript(agent 层)+ Rust(原生核心,约 8 万行,另有约 8 万行 vendored 代码)
运行时Bun ≥ 1.3.14(推荐);提供 Node SDK
平台macOS · Linux · Windows(同一二进制,无 WSL 桥接)
模型接入60+ providers、上千模型、9 个角色槽位
内置能力31 个内置工具 · 14 个 LSP 操作 · 28 个 DAP 调试操作
开源协议MIT
官网omp.sh
npm 包@oh-my-pi/pi-coding-agent(版本已推进到 18.x)

两个值得注意的项目状态:更新非常频繁(2026 年 9 月中旬仍在活跃推送),生产环境建议锁定版本;贡献治理上,PR 目前处于向所有人开放的试验期——此前的 vouch(老成员担保)要求暂时取消,官方声明后续可能恢复。

系统地图:一个引擎,四种入口

所有能力都挂在同一个会话引擎上,外面套四种包装:

入口命令用途
交互式 TUIomp默认入口,工具调用渲染成卡片,编辑先预览后落盘
一次性执行omp -p "prompt"回答单个 prompt 后退出,适合脚本和 CI
Node SDK@oh-my-pi/pi-coding-agent把会话嵌进自己的 Node/TypeScript 进程
RPC / ACPomp --mode rpc / omp acp通过 stdio 交给别的程序驱动

SDK 暴露 ModelRegistry、SessionManager、createAgentSession 等接口,会话以类型化事件对外广播:

import {
  ModelRegistry,
  SessionManager,
  createAgentSession,
  discoverAuthStorage,
} from "@oh-my-pi/pi-coding-agent";

const auth = await discoverAuthStorage();
const models = new ModelRegistry(auth);
await models.refresh();

const { session } = await createAgentSession({
  sessionManager: SessionManager.inMemory(),
  authStorage: auth,
  modelRegistry: models,
});
await session.prompt("list .ts files");

RPC 模式面向非 Node 环境,NDJSON 命令进出:

$ omp --mode rpc --no-session
> {"id":"r1","type":"prompt","message":"list .ts files"}
< {"id":"r1","type":"response", ...}

ACP(Agent Client Protocol,Zed 主导的 JSON-RPC 协议)让 omp 跑在编辑器里:读你正在看的 buffer,走编辑器的 save 路径写文件,在编辑器终端里起 shell。bash 路由到 terminal/create,read 路由到 fs/read_text_file,破坏性操作统一过 session/request_permission 权限门。没有桥接层,也没有需要另外维护的同步副本。

主线一:编辑与代码智能

omp 内部其实有几条相对独立的主线。第一条围绕"改代码"这件事:编辑格式、语言服务、结构化重写、调试器。

hashline:用内容哈希做锚点

传统 diff 编辑靠行号或原文匹配定位,模型必须逐字复述要改的那一行:行号错一位、空白多打一个、引号漏一层,补丁就落空,只能重试。循环的根源在于锚点绑的是"位置"和"外观",而这两样恰好最容易被模型写错。hashline 把锚点从位置、外观换成内容本身:模型只需给出行内容对应的哈希指纹,工具按指纹定位,逐字复述被整个省掉——空白对齐问题从此无处发生,坏 diff 的重试循环也随之消失。行内容一旦真的被改过,旧哈希对不上新内容,补丁在写盘前就被拒绝,不会污染文件。

另一处收益直接反映在账单上:Grok 4 Fast 做同样的工作,输出 token 少 61%——坏 diff 触发的重试循环没有了。

LSP 写进每一次编辑

omp 的重命名走 workspace/willRenameFiles,所以 barrel 文件的重导出、别名导入都会在文件移动前更新。agent 调的就是 IDE 的语言服务,14 个 LSP 操作覆盖诊断、跳转、符号查找、代码动作。效果可以概括为一句话:IDE 知道什么,agent 就知道什么。

ast_edit:先预览,后落盘

基于 ast-grep 的结构化重写,覆盖 50+ 种 tree-sitter 语法。ast_edit 先返回一张 (proposed) 卡片和替换计数,改动处于暂存态;agent 往 xd://resolve 写一行理由后,TUI 生成 Accept 卡片,替换原子化落盘——要么全部生效,要么不动。

DAP:真的调试器,真的断点

omp 通过 DAP(Debug Adapter Protocol)驱动真实调试器,共 28 个调试操作:

  • lldb:attach 到 C/C++/Rust 原生二进制,单步到出错指针、读栈帧
  • dlv:attach 到 Go 服务,遍历 goroutine 栈
  • debugpy:暂停 Python 进程、检查变量、求值表达式

多数 agent 还停留在 print 调试——靠往源码里插日志、重新编译、看输出,改一行要重启一次进程。这里 agent 可以直接对运行中的进程下断点:看到的是真实的内存状态、真实的栈帧,而不是自己打印出来的二手信息。

16 个内部 scheme:GitHub 也是文件系统

read、grep、glob 这些文件工具对 16 个内部 scheme 透明解析:pr://1428 返回的内容和 read src/foo.ts 同构,grep 能像遍历目录一样遍历一个 diff,agent://<id>/findings.0.path 能按路径直接取子 Agent 输出里的字段。常用的还有 issue://、skill://、rule://、ssh://、conflict://N。

主线二:进程内执行层

第二条主线是"工具怎么跑"。其他 agent 大多 shell out 到 rg、grep、find、bash——很多机器上这些二进制根本不存在,存在的每次调用也要付一次 fork-exec 往返:新进程带着参数表从零拉起、加载解释器、把结果一行行打回 stdout,agent 再解析成结构化数据。一次搜索走完这条链路,毫秒级开销在路上,数据结构却还是文本。omp 把真实实现链接进了进程。

约 8 万行 Rust 分布在六个 crate,挂在一个平台标注的 N-API 插件上:

Crate职责约行数
pi-shell内嵌 bash 引擎 · 持久会话 · 进程内 coreutils 分发38,000
pi-nativesN-API 接口层:grep、桌面控制、文本处理、PTY、剪贴板等25,000
pi-walker并行文件遍历 + 扫描缓存,grep/glob/workspace/shell 共享5,200
pi-iso工作区隔离:APFS clone、btrfs/zfs reflink、overlayfs3,300
pi-asttree-sitter + ast-grep 匹配与结构化摘要2,900
pi-voice音频采集播放 · Opus · WebRTC1,000

shell 语义来自 vendored 的 brush bash fork;coreutils、findutils、sed、jq、ripgrep 后端的 grep、fd、diff 等工具被移植进 builtins crate,随主程序一起编译。bash 工具本身提供 46 个进程内 coreutils、可选 PTY 和后台任务调度,会话跨调用存活。二进制覆盖 linux/darwin/win32 各 x64/arm64 六个平台目标,x64 附带 AVX2 与基线两个构建——Windows 上直接跑,不需要 WSL。

eval 工具提供持久的 Python 和 JavaScript(Bun)执行单元格,两者共享 prelude,并且能通过 loopback 桥回调 agent 自己的工具:在 Python 里用 read 加载 CSV,到 JavaScript 里画图,全程不离开单元格。

桌面与 Web 能力也在这条主线上:browser 驱动 Chromium 或 Electron(Puppeteer 标签页,可接管你已打开的 Chrome),stealth 默认开启;computer 枚举窗口、截屏、发原生输入、走系统无障碍树;web_search 一条查询串起 23 个搜索后端,按站点定制 extractor,GitHub、arXiv、Stack Overflow、npm/PyPI 等注册表页面转成保留锚点的结构化 markdown,另有 NVD、OSV、CISA KEV 三个漏洞数据库直查。注意 github、security_scan、generate_image、tts 等工具默认关闭,需在配置里显式开启。

主线三:模型接入与路由

第三条主线决定"哪个模型干哪件事"。60+ providers 分三类:直连 API(Anthropic、OpenAI、Gemini、xAI、DeepSeek、Bedrock、Azure、OpenRouter 等)、订阅式 coding plan(Cursor、GitHub Copilot、Kimi Code、GLM/Z.AI、MiniMax、阿里、Qwen、小米 MiMo 等)、本地推理(Ollama、LM Studio、llama.cpp、vLLM、LiteLLM)。

路由围绕 9 个角色槽位组织:default 日常、smol 便宜的子 agent 扇出、slow 深度推理、plan 规划模式、commit 写变更日志,其余 vision、task、advisor、tiny 各司其名。会话里 /model 随时切换,Ctrl+P 在当前角色的备选模型间循环。

让这套路由真正可用的四个配置项:

  • 自定义 provider——任何支持 openai-completions、anthropic-messages、bedrock-converse-stream、google-generative-ai 等协议的服务端都能在 ~/.omp/agent/models.yml 里声明
  • fallback 链——retry.fallbackChains 按角色或模型配置,主模型 429 或配额耗尽时同轮切换到下一个,冷却后自动恢复
  • 按路径定模型——enabledModels/disabledProviders 可限定 path: 前缀,单个仓库用不同模型集,不动全局配置
  • 凭据轮转——同一 provider 堆多个 API key,带会话亲和与按凭据退避

自定义 provider 的最小配置(README 原例):

providers:
  spark:
    baseUrl: http://192.168.10.223:8000/v1
    api: openai-completions
    apiKey: dummy
    models:
      - id: minimax-m3
        name: MiniMax M3
        contextWindow: 100000
        maxTokens: 32000

主线四:多 agent、规则与记忆

第四条主线解决"一个上下文装不下、一个模型看不全、一条会话记不住"。

子 agent。task 把工作扇出到隔离的 worker(可选独立 worktree,靠 pi-iso 的文件系统克隆实现),每个 worker 有自己的工具面,最终产出是经 schema 校验的对象,父 agent 直接读字段,不解析散文,兄弟之间也不会互相改脏文件。Alt+A 打开 Agent Hub,能看每个子 agent 的实时转录、发引导消息、复活或终止卡住的 worker。

Advisor。把第二个模型配到 advisor 角色,它会读主 agent 的每一步动作,在旁注里给出提醒、疑虑或硬阻断。它有自己的上下文和模型,能抓住执行者赶进度时漏掉的问题。

TTSR(时间旅行式流规则)。规则文件平时静默,不占上下文;模型的输出流命中正则时,流被中途掐断,规则以 system reminder 注入,从同一点重试。注入在 context 压缩后依然存活,所以修复是持久的。官方示例:模型准备写 Box::leak 时规则触发,模型改用 Arc<str> 并向用户确认。

记忆。retain 写入事实、learn 沉淀可复用经验(可提升为受管 skill)、recall 检索、reflect 综合回答,每次会话压缩成心智模型供下次首回合加载。引擎经 memory.backend 选择:本地 SQLite(pi-mnemopi)、Hindsight 或 Mnemopi,默认按项目隔离——这个仓库学到的事留在这个仓库。

协作。/collab 把当前会话挂上中继,返回链接和二维码;队友用 omp join 从另一个终端加入,或在浏览器里打开。/collab view 给只读链接。帧在客户端加密,中继看不到你的密钥。

一次调试任务的完整路径

把四条主线串起来,看一个 C 二进制段错误从发现到提交的全过程:

  1. agent 通过 bash(进程内 shell)编译并运行二进制,捕获到 segfault
  2. 调用 debug 工具 attach lldb,下断点、单步到坏指针、读栈帧——DAP 会话的适配器、状态、指令指针都渲染在 TUI 卡片里
  3. 定位到问题函数后,用 edit 的 hashline 补丁修掉,锚点哈希保证落在正确的位置
  4. 需要重命名函数时,LSP rename 经 workspace/willRenameFiles 更新所有引用,包括 barrel 文件里的重导出
  5. 收尾跑 omp commit:它经 git_overview/git_file_diff/git_hunk 读工作树,把无关变更按依赖顺序拆成原子提交,出现循环依赖则在写入前拒绝,源码文件排在测试、文档、配置之前,锁文件不参与分析

每一步用到的都是内置工具,没有一步需要 agent"灵机一动"拼外部命令。

编辑基准:这组数字该怎么读

官方给出的模型对比数据:

模型指标说明
Grok Code Fast 16.7% → 68.3%编辑格式修好后一次通过率提升十倍
Gemini 3 Flash+5 个百分点相对 str_replace 格式,超过 Google 自己给出的最佳格式方案
Grok 4 Fast输出 token −61%坏 diff 重试循环消失后输出坍缩
MiniMax2.1×同权重、同 prompt 下通过率翻倍

读这组数字前先回答三个问题。

测的是什么:同一批编辑任务在不同 edit 工具格式下的一次通过率和输出 token,测的对象是 harness 而非模型。仓库里的 typescript-edit-benchmark 包表明基准建立在 TypeScript 源码变异之上,完整方法论见官方博客 The Harness Problem。

数字反映系统的哪部分:变化集中在 edit 工具的锚点设计与重试策略上。6.7% → 68.3% 这种量级的变化来自格式而非模型——对照组里模型权重没有动。

不能推出什么:不能推出这些模型整体编码能力的排序——通过率只针对"按 hashline 格式输出编辑"这一件事;也不能把 −61% 的输出 token 直接换算成账单节省,输入侧 token 和会话长度不在统计里。另外这些数字由项目方自己测得,第三方复测结果尚未见到。

规则继承与扩展

第一次运行时,omp 直接读取磁盘上已有的规则、skills 和 MCP 配置,来源包括 .claude、.cursor、.windsurf、.gemini、.codex、.cline、.github/copilot、.vscode——共 8 种格式以原生形态支持(Cursor MDC、Cline .clinerules、Codex AGENTS.md、Copilot applyTo 等),没有迁移脚本,也没有"支持子集"的脚注。团队上季度写的配置今晚就能用。

扩展侧,一个 extension 就是一个 TypeScript 模块,用的是与内置功能相同的工具 API、斜杠命令注册表、快捷键表和 TUI 原语。让 omp 自己写一块缺失的功能,然后 /reload-plugins 生效;可以留在本地、放进 marketplace 或发到 npm。

几个改变会话行为的控制入口:

  • 提示词里的 ultrathink(深度思考)、orchestrate(并行子 agent 编排)、workflowz(确定性多 agent 工作流)——只在你输入的正文里触发,代码块和路径里不生效
  • /vibe 进入导演模式:以只读工具集驱动持久的 fast/good worker 会话
  • /fresh 重置 provider 流状态(陈旧的 prompt 缓存、卡死的流),不动本地转录
  • /review 拉起评审子 agent,并行扫分支、单提交或未暂存的工作,每个问题标 P0–P3 和置信度,最后给出能否合入的明确结论

快速开始

macOS / Linux:

curl -fsSL https://omp.sh/install | sh

Homebrew:

brew install can1357/tap/omp

Bun(推荐):

bun install -g @oh-my-pi/pi-coding-agent

Nix(免安装试用):

nix run github:can1357/oh-my-pi

Windows(PowerShell):

irm https://omp.sh/install.ps1 | iex

版本锁定可用 mise use -g github:can1357/oh-my-pi。两个环境注意点:Alpine/musl 的预编译二进制动态链接 libstdc++/libgcc,需先 apk add libstdc++ libgcc;shell 补全由 omp 按实际命令元数据生成,bash/zsh/fish 分别执行 omp completions <shell> 挂载即可,模型名和 --resume 会话名都能补全。

日常高频命令集中在会话层:/model 切模型、/login 接入订阅、/collab 发起协作、/review 评审、/debug 打开调试与性能面板。

适用边界与采用建议

适合现在就上的情况:

  • 重度终端工作流:omp 的全部能力以 TUI 为第一入口,编辑器只经 ACP 接入
  • 需要真实调试:要在 agent 循环里 attach 调试器,而不是靠 print 猜
  • 多模型策略:想在同一个会话里按角色混用多家模型、本地推理和订阅 plan
  • Windows 原生环境:同一二进制直接跑,不依赖 WSL
  • 已有规则资产:Cursor/Cline/Codex/Copilot 规则零迁移继承

可以先观望的情况:项目 2025 年 12 月底才创建,版本号已推进到 18.x,接口和配置面仍在快速变动,追求长期稳定 API 的团队需要自己锁版本、跟 changelog;依赖厂商商业支持的团队目前没有该选项。治理上 vouch 机制可能回归,贡献流程存在不确定性。

建议的采用顺序:先用 Homebrew 或安装脚本在个人项目里跑通一次编辑—调试—omp commit 闭环,感受 hashline 和 DAP 与现有工具的差异;然后把现有规则目录交给它的 discovery 机制继承,对比规则行为是否一致;最后才考虑在团队仓库里启用子 agent 隔离、记忆后端和按路径的模型路由这类需要配置投入的能力。

结语

omp 的判断很明确:agent 竞争的下一层不在模型,而在 harness——编辑格式、语言服务、调试器、进程内执行、模型路由,每一层都值得重写。它把"IDE 知道什么,agent 就知道什么"从口号做成了 14 个 LSP 操作和 28 个 DAP 操作;把 8 万行 Rust 塞进一个二进制,换掉 fork-exec 的老路。对在终端里写代码的人来说,它是目前把这条路线走得最完整的一个实现。

参考链接:

参与讨论

使用 GitHub 登录。欢迎补充事实、异议与实践。