opencode

oh-my-opencode 开始用起来还挺有意思 https://github.com/code-yeongyu/oh-my-openagent/tree/dev

特性功能说明
🤖自律军团 (Discipline Agents)Sisyphus 负责调度 Hephaestus、Oracle、Librarian 和 Explore。一支完整的 AI 开发团队并行工作。
ultrawork / ulw一键触发,所有智能体出动。任务完成前绝不罢休。
🚪IntentGate 意图门真正行动前,先分析用户的真实意图。彻底告别被字面意思误导的 AI 废话。
🔗基于哈希的编辑工具每次修改都通过 LINE#ID 内容哈希验证、0% 错误修改。灵感来自 oh-my-pi马具问题 →
🛠️LSP + AST-Grep工作区级别的重命名、构建前诊断、基于 AST 的重写。为 Agent 提供 IDE 级别的精度。
🧠后台智能体同时发射 5+ 个专家并行工作。保持上下文干净,随时获取成果。
📚内置 MCPExa (网络搜索)、Context7 (官方文档)、Grep.app (GitHub 源码搜索)。默认开启。
🔁Ralph Loop / /ulw-loop自我引用闭环。达不到 100% 完成度绝不停止。
Todo 强制执行Agent 想要摸鱼?系统直接揪着领子拽回来。你的任务,必须完成。
💬注释审查员剔除带有浓烈 AI 味的冗余注释。写出的代码就像老练的高级工程师写的。
🖥️Tmux 集成完整的交互式终端支持。跑 REPL、用调试器、用 TUI 工具,全都在实时会话中完成。
🔌Claude Code 兼容你现有的 Hooks、命令、技能、MCP 和插件?全都能无缝迁移过来。
🎯技能内嵌 MCP技能自带其所需的 MCP 服务器。按需开启,不会撑爆你的上下文窗口。
📋Prometheus 规划师动手写代码前,先通过访谈模式做好战略规划。
🔍/init-deep在整个项目目录层级中自动生成 AGENTS.md。不仅省 Token,还能大幅提升 Agent 理解力。

Sisyphus (claude-opus-4-6 / kimi-k2.5 / glm-5) 是你的主指挥官。他负责制定计划、分配任务给专家团队,并以极其激进的并行策略推动任务直至完成。他从不半途而废。

Hephaestus (gpt-5.4) 是你的自主深度工作者。你只需要给他目标,不要给他具体做法。他会自动探索代码库模式,从头到尾独立执行任务,绝不会中途要你当保姆。名副其实的正牌工匠。

Prometheus (claude-opus-4-6 / kimi-k2.5 / glm-5) 是你的战略规划师。他通过访谈模式,在动一行代码之前,先通过提问确定范围并构建详尽的执行计划。

每一个 Agent 都针对其底层模型的特点进行了专门调优。你无需手动来回切换模型。阅读背景设定了解更多 →

Anthropic 因为我们屏蔽了 OpenCode。这就是为什么我们将 Hephaestus 命名为“正牌工匠 (The Legitimate Craftsman)”。这是一个故意的讽刺。

我们在 Opus 上运行得最好,但仅仅使用 Kimi K2.5 + GPT-5.4 就足以碾压原版的 Claude Code。完全不需要配置。

智能体调度机制

当 Sisyphus 把任务分配给子智能体时,他选择的不是具体的模型,而是 类别 (Category)。系统会自动将类别映射到最合适的模型:

类别作用领域
visual-engineering前端、UI/UX、设计
deep深度自主调研与执行
quick单文件修改、修错字
ultrabrain复杂硬核逻辑、架构决策

智能体只需要说明要做什么类型的工作,框架就会挑选出最合适的模型去干。你完全不需要操心。

眼看着oh-my-opencode越发完善,很多设计理念都让我感到十分精妙,让最合适的模型去做最合适的agent,让每个agent配置对应不同的任务,各司其职的感觉不仅让我想起电台头的歌曲 Everything In Its Right Place(虽然歌名和实际表达的意思正好相反)。 由于oh-my-opencode更新很频繁,github上readme很多时候更新不及时,也不够详细,这里就简单介绍一下最新版的agents集群架构。https://zhuanlan.zhihu.com/p/2010730351564198918


简单来说就是oh-my-opencode通过把写代码,甚至是任何可以AI操作的电脑任务拆解成几个部分:规划、查阅、执行,具体的agent带着prompt、skills等上下文各司其职,团队分工合作完成复杂任务,多说无益我们看这个简化版的架构图:

我们大致可以拆成四个部分来看这张图:

a.编排器与调度器

  1. Sisyphus(主控 & 总工程师)
  • 西西弗斯主agent,绝大多数时候都是和用户对话的agent和所有任务的入口
  • 总规划编排调度,可以调用其他subagent,必要时还可以临时创建特定任务的agent
  • 非常简单的任务也会自己直接阅读/写代码,有时其他agent职责没有覆盖/完成的也会自己上手
  1. Atlas(调度器 & 计划执行器)
  • 阅读Sisyphus或者Prometheus的plan,逐条执行ToDo
  • 主要功能是调用其他subagent,分配具体任务
  • 简单问题也会自己直接执行读写文件

b.计划与验证

  1. Prometheus(战略规划师)
  • 生成plan给Atlas,一般由Sisyphus调用,如果用户对任务有详细的认知和描述可以手动切换直接与Prometheus对话,这样会更精确执行用户的目标
  • 可能会询问用户问题来澄清需求
  1. Metis(预分析规划顾问)
  • Prometheus的分析顾问,制定plan之前的风险分析和方案探索
  • 挖隐含需求、补上下文、避免过度设计
  1. Momus(战略审查师)
  • 作为Prometheus的审稿人对plan审查与结果验证

c.检索与顾问

  1. Oracle(架构/调试顾问)
  • 当其他agent(Atlas/Sisyphus等)有疑问的时候调用Oracle解决局部难点
  • 一般是解释代码给出建议,做头脑风暴、审阅
  1. Librarian(检索专家)
  • grep文档、API、README、GitHub代码
  • 当其他agent需要外部信息的时候调用它
  1. Explore(代码库探索)
  • 做结构化的语义grep,告诉其它agent某段逻辑、风格
  • 当其他agent需要本地文档信息的时候调用它
  1. multimodal‑looker(多模态分析师)
  • 查看PDF、图片、截图等内容

d.执行器

  1. Hephaestus(长周期执行器)
  • 利用codex系列长期工作的特性执行那些需要几十分钟起步的任务
  • 循环跑读、写代码、运行、检查结果的循环
  • 由Sisyphus或Atlas调用
  1. Sisyphus‑Junior(单任务执行器)
  • 由用户创建或者Sisyphus临时生成的特定任务执行器
  • 专注于某一种任务的执行,可以读写代码
  • 用户可以手动在categories字段创建(见下文的json配置)

*注:除了上面两个,Sisyphus和Atlas本身也可以读写文件,任务简单的时候也能直接修改代码,在早期版本中,Sisyphus会倾向于自己修改代码或者调用opencode的build agent修改代码,现在更加完善了

看完上面的每个agent分析,是不是发觉这个agents集群是一个精妙的系统,agent之间可以互相调用,可以返回各种信息,需要时还可以创建新的agent新的skill和其他约束最终高质量的交付。就这种各司其职的,让每个agent和模型做最适合自己的事情就像是拆解了一台精妙仪器一样。 在下一节的jsonc代码里我会列出每个agent最适合的模型


理解了上面的原理后,下面这份模板你就可以拿走改改变成最适合自己的了 首先在你的机器上找到.config/opencode路径(win上是%USERPROFILE%\.config\opencode),安装并运行oh-my-opencode(如果没有安装可以在opencode里的build模式里直接给AI说我要安装oh-my-opencode,把github链接甩过去他就会安装了)之后就会有一个oh-my-opencode.json文件,我们可以把这个json改成jsonc文件(这样兼容性更好,支持批注和更多语法),然后按照我下面的参考进行配置。

我自己在用的配置如下,其中fallback链是结合代码和作者的推荐给出的推荐模型顺序,优先选择上面靠前的模型,意味着这个模型更适合这个任务,当然没有相关模型的订阅也可以顺次换成其他推荐的模型。写的模型是我正在用的,因为我没有官方的claude订阅(用的第三方API),所以用GPT代替了一部分claude模型(OpenAI订阅真的量大管饱啊),你们也可以根据自己的订阅来切换不同的模型。

说说我的配置:

{
  "$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
  "auto_update": true,
  "agents": {
    "hephaestus": {
      "model": "deepseek/deepseek-v4-pro",
      "variant": "medium"
    },
    "oracle": {
      "model": "zai/glm-5.1",
      "variant": "high"
    },
    "librarian": {
      "model": "ds4/deepseek-v4-flash",
      "variant": "medium"
    },
    "explore": {
      "model": "ds4/deepseek-v4-flash",
      "fallback_models": [
        {
          "model": "deepseek/deepseek-v4-pro"
        }
      ],
      "variant": "medium"
    },
    "multimodal-looker": {
      "model": "deepseek/deepseek-v4-pro",
      "variant": "medium"
    },
    "prometheus": {
      "model": "zai/glm-5.1",
      "variant": "high"
    },
    "metis": {
      "model": "zai/glm-5.1",
      "variant": "high"
    },
    "momus": {
      "model": "deepseek/deepseek-v4-pro",
      "variant": "xhigh"
    },
    "atlas": {
      "model": "deepseek/deepseek-v4-pro",
      "variant": "medium"
    },
    "sisyphus-junior": {
      "model": "ds4/deepseek-v4-flash",
      "variant": "medium"
    },
    "sisyphus": {
      "model": "deepseek/deepseek-v4-pro",
      "variant": "medium"
    }
  },
  "categories": {
    "visual-engineering": {
      "model": "ds4/deepseek-v4-flash",
      "variant": "high"
    },
    "ultrabrain": {
      "model": "deepseek/deepseek-v4-pro",
      "variant": "xhigh"
    },
    "deep": {
      "model": "deepseek/deepseek-v4-pro",
      "variant": "medium"
    },
    "artistry": {
      "model": "deepseek/deepseek-v4-pro",
      "variant": "xhigh"
    },
    "quick": {
      "model": "ds4/deepseek-v4-flash"
    },
    "unspecified-low": {
      "model": "ds4/deepseek-v4-flash",
      "variant": "medium"
    },
    "unspecified-high": {
      "model": "deepseek/deepseek-v4-pro",
      "variant": "medium"
    },
    "writing": {
      "model": "ds4/deepseek-v4-flash",
      "variant": "medium"
    }
  }
}

{
  "$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-opencode/master/assets/oh-my-opencode.schema.json",
  
  //2026-02-16
  //"disabled_agents": ["oracle", "multimodal-looker"],//来禁用某个特定代理

  "agents": {

    // ======================
    // 1. 编排规划与验证系列
    // ======================

    "sisyphus": { 
      // 主编排器:委托任务编排分配、TODO、后台并行、动态组合技能,调用subagent
      // fallback:claude-opus-4-6 → kimi-k2.5 → glm-4.7 → gpt-5.3-codex → gemini-3-pro
      "model": "claude/claude-opus-4-6",
      "temperature": 0.1
    },

    "atlas": { 
      // 高级编排器:全生命周期管理,任务路由,基于skills调度,全局会话级别的编排器,一般由内部逻辑/hook唤起
      // fallback:claude-sonnet-4-5 → kimi-k2.5 → gpt-5.2 → gemini-3-pro
      "model": "openai/gpt-5.2",
      "temperature": 0.1
    },

    "prometheus": { 
      // 战略规划:澄清需求、验证计划、复杂任务分解,推荐内部plan而不是和用户直接交互
      // fallback:claude-opus-4-6 → kimi-k2.5 → gpt-5.2
      "model": "claude/claude-opus-4-6",  
      "temperature": 0.1
    },
    
    "metis": {
      // 预分析规划顾问:正式plan/执行前进行问题理解、风险与上下文分析,温度略高,探索更多方案
      // fallback:claude-opus-4-6 → kimi-k2.5 → gpt-5.2-high
      "model": "anthropic/claude-opus-4-6",
      "temperature": 0.3,
      "variant": "max"
    },

    "momus": {
      // 计划与结果验证:对计划/方案进行合理性检查和评审
      // gpt-5.2 → claude-opus-4-6 → gemini-3-pro
      "model": "openai/gpt-5.2",
      "temperature": 0.1,
      "variant": "medium"
    },

    // ======================
    // 2. 执行系
    // ======================

    "hephaestus": {
      // 深度自主工作专用,长周期,深度任务
      // 只推荐OpenAIcodex模型,如果没有codex则不会使用这个agent
      "model": "openai/gpt-5.3-codex",  
      "temperature": 0.1
    },

    // ======================
    // 3. 顾问与检索系
    // ======================

    "oracle": { 
      // 咨询/调试/架构专家:代码审查、复杂问题拆解,交互式问答
      // fallback:gpt-5.2-high → gemini-3-pro → claude-opus-4-6
      "model": "openai/gpt-5.2",
      "temperature": 0.1,
      "variant": "high"
    },

    "librarian": { 
      // 文档/仓库检索专家:文档/README/API 手册/GitHub 仓库搜索,大量输入,需要快速便宜长上下文的模型
      // fallback:glm-4.7 → gpt-5.3-codex-spark → gemini-3-flash
      "model": "openai/gpt-5.3-codex-spark" 
    },

    "explore": { 
      // 快速代码库探索:grep(上下文感知搜索)
      // fallback:gpt-5.3-codex-spark → grok-code-fast-1 → claude-haiku-4-5 → gpt-5-mini → gpt-5-nano
      "model": "openai/gpt-5.3-codex-spark" 
    },

    "multimodal-looker": { 
      // 多模态分析:PDF/图片分析,多模态好的模型
      // fallback:gemini-3-flash → kimi-k2.5
      "model": "gemini/gemini-3-pro-preview" 
    }
  },
  "categories": {
    // 快速小活:haiku / gemini-flash / nano
    "quick": { "model": "openai/gpt-5.3-codex-spark", "temperature": 0.1 },

    // 深度执行:codex / opus / gemini-pro
    "deep": { "model": "openai/gpt-5.3-codex", "variant": "medium", "temperature": 0.1 },

    // 超大脑:codex xhigh(更激进)
    "ultrabrain": { "model": "openai/gpt-5.3-codex", "variant": "xhigh", "temperature": 0.1 },

    // 视觉/前端/GUI:gemini-pro-high / glm-5 / opus
    "visual-engineering": { "model": "google/gemini-3-pro-preview", "temperature": 0.1 },

    // 文本/写作:glm4.7 / k2.5 / gemini-flash / sonnet
    "writing": { "model": "gemini/gemini-3-pro-preview", "temperature": 0.2 },

    // 未指定低/高档位
    "unspecified-low": { "model": "claude/claude-sonnet-4-5", "temperature": 0.1 },
    "unspecified-high": { "model": "claude/claude-opus-4-6", "variant": "max", "temperature": 0.1 }
  }
}

其中categories部分也是看自己的需求添加即可

一些模型选择的思路:

codex是那种说什么就做什么的模型,绝不多做,也不发挥主观能动性给你代码优化,而opus就更喜欢帮你优化代码,有更多主观能动性(GPT 5.2⁄5.3 codex对比opus4.5⁄4.6),所以codex就更适合做写代码的,opus更适合给codex布置任务、监工。又比如codex-spark是非常快的那种,就适合做大量grep的任务,Gemini多模态明显是御三家里最好的,所以就拿来多模态这样子。还有一些思路,比如说西西弗斯和阿特拉斯用不同家的模型互补,普罗米修斯和其他审阅plan的模型也不一样这样才能集思广益。

你已经花了大力气调教好了 Claude Code 的配置?太好了。

这里完美兼容所有的 Hook、命令、技能、MCP 以及插件。所有配置直接生效,包括插件系统。

赋予 Agent 世界级的开发工具

LSP、AST-Grep、Tmux、MCP 并不是用胶水勉强糊在一起的,而是真正深度的集成。

  • LSP: 支持 lsp_renamelsp_goto_definitionlsp_find_referenceslsp_diagnostics。给 Agent 提供 IDE 般的精准操作。
  • AST-Grep: 支持 25 种编程语言,能够理解语法树的模式匹配和代码重写。
  • Tmux: 真实的交互式终端环境,支持 REPL、调试器以及 TUI 工具。Agent 的进程持久运行。
  • MCP: 内置 Web 搜索、官方文档直连以及 GitHub 级代码搜索。

技能专属的按需 MCP 服务器

一堆全局 MCP 服务器极其消耗 Context 额度,我们修好了这个问题。

现在每个技能 (Skill) 都带着自己的专属 MCP。只在执行该任务时启动,任务完成即刻销毁。Context 窗口始终清爽。

拒绝瞎改:基于内容哈希的编辑工具 (Hash-Anchored Edits)

Harness 问题是真的。绝大多数所谓的 Agent 故障,其实并不是大模型变笨了,而是他们用的文件编辑工具太烂了。

“目前所有工具都无法为模型提供一种稳定、可验证的行定位标识……它们全都依赖于模型去强行复写一遍自己刚才看到的原文。当模型一旦写错——而且这很常见——用户就会怪罪于大模型太蠢了。”


Can Bölük, The Harness Problem

oh-my-pi 的启发,我们实现了 Hashline 技术。Agent 读到的每一行代码,末尾都会打上一个强绑定的内容哈希值:

11#VK| function hello() {
22#XJ|   return "world";
33#MB| }

Agent 发起修改时,必须通过这些标签引用目标行。如果在此期间文件发生过变化,哈希验证就会失败,从而在代码被污染前直接驳回。不再有缩进空格错乱,彻底告别改错行的惨剧。

在 Grok Code Fast 1 上,仅仅因为更换了这套编辑工具,修改成功率直接从 6.7% 飙升至 68.3%

深度上下文初始化:/init-deep

执行一次 /init-deep。它会为你生成一个树状的 AGENTS.md 文件系统:

project/
├── AGENTS.md              ← 全局级架构与约定
├── src/
│   ├── AGENTS.md          ← src 级规范
│   └── components/
│       └── AGENTS.md      ← 组件级详细说明

Agent 会自动顺藤摸瓜加载对应的 Context,免去了你所有的手动喂喂喂的麻烦。

让 Agent 动手前先过脑子:Prometheus

碰到了硬骨头?千万不要扔个 Prompt 就双手合十祈祷。

输入 /start-work,召唤 Prometheus 出场。他会像一个真实的主管那样去采访你,主动深挖需求、指出模糊地带,并在改动哪怕一行代码之前产出经过严密论证的计划。你的 Agent 终于知道了自己在干嘛。

技能系统 (Skills)

这里的 Skills 绝不只是一段无脑的 Prompt 模板。它们包含了:

  • 面向特定领域的极度调优系统指令
  • 按需加载的独立 MCP 服务器
  • 对 Agent 能力边界的强制约束

默认内置:playwright(极其稳健的浏览器自动化)、git-master(全自动的原子级提交及 rebase 手术)、frontend-ui-ux(设计感拉满的 UI 实现)。

想加你自己的?放进 .opencode/skills/*/SKILL.md 或者 ~/.config/opencode/skills/*/SKILL.md 就行。

想看所有的硬核功能说明吗? 点击查看 详细特性文档 (Features) ,深入了解 Agent 架构、Hook 流水线、核心工具链和所有的内置 MCP 等等。


第一次用 oh-my-opencode? 阅读 概述 了解你拥有哪些功能,或查看 编排指南 了解 Agent 如何协作。

如何卸载 (Uninstallation)

要移除 oh-my-opencode:

  1. 从你的 OpenCode 配置文件中去掉插件 编辑 ~/.config/opencode/opencode.json (或 opencode.jsonc) ,并把 "oh-my-opencode"plugin 数组中删掉: # 如果你有 jq 的话 jq ‘.plugin = [.plugin[] | select(. != “oh-my-opencode”)]’ \ ~/.config/opencode/opencode.json > /tmp/oc.json && \ mv /tmp/oc.json ~/.config/opencode/opencode.json
  2. 清除配置文件 (可选) # 移除全局用户配置 rm -f ~/.config/opencode/oh-my-opencode.json ~/.config/opencode/oh-my-opencode.jsonc # 移除当前项目的配置 rm -f .opencode/oh-my-opencode.json .opencode/oh-my-opencode.jsonc
  3. 确认卸载成功 opencode –version # 这个时候就应该没有任何关于插件的输出信息了

闲聊环节 (Author’s Note)

想知道做这个插件的哲学理念吗? 阅读 Ultrawork 宣言


我为了做个人项目,烧掉了整整 $24,000 的 LLM API Token 费用。我把市面上每个宣称好用的代码 Agent 全试了一遍,配置选项被我翻得底朝天。最后我得出了结论,OpenCode 赢了。

我踩过的坑、撞过的南墙,它们的终极解法现在全都被硬编码到了这个插件里。你只需要安装,然后直接用。

如果把 OpenCode 喻为底层的 Debian/Arch,那么 OmO 毫无疑问就是开箱即用的 Ubuntu/Omarchy

本项目受到 AmpCodeClaude Code 的深刻启发。我把他们好用的特性全都搬了过来,且在很多地方做了底层强化。它仍在活跃开发中,因为毕竟,这是 OpenCode。

其他调度框架只会给你画饼画一张很酷的 Multi-Agent 大饼。我们把饼烙出来了。不仅能用,而且极其稳定。所有的功能都不是为了炫技,而是真的能把任务干完。

因为我自己就是这个项目最偏执、最神经质的极端用户:

  • 哪个模型在处理变态业务逻辑时最不容易晕?
  • 谁是修 Bug 的神?
  • 谁文笔最好、最不 AI 味?
  • 谁能在前端交互上碾压一切?
  • 后端性能谁来抗?
  • 谁又快又便宜适合打杂?
  • 竞争对手们今天又发了啥牛逼的功能,能抄吗?

这个插件是以上一切的结晶 (Distillation)。直接拿走去用。如果有更好的点子,PR 大门永远敞开。

别再浪费时间去到处对比选哪个框架好了。 我会去市面上调研,把最强的特性全偷过来,然后在这更新。

听起来很自大吗?如果你有更牛逼的实现思路,那就交 PR,热烈欢迎。

郑重声明:本项目与文档中提及的任何框架/大模型供应商均无利益相关,这完完全全就是一次走火入魔的个人硬核实验成果。

本项目 99% 的代码都是直接由 OpenCode 生成的。我本人其实并不懂 TypeScript。但我以人格担保,这个 README 是我亲自审核并且大幅度重写过的。

以下公司的专业开发人员都在用

oh-my-opencode 3.0.0 深入解析:从单代理到编排革命的演进

https://zhuanlan.zhihu.com/p/1999083955228542369

Hephaestus 的 prompt 末尾要求 agent 在结束每个 turn 前做四项检查,任何一项失败就不能结束 turn。这是一种”自我约束”的 prompt 工程技巧,确保 100% 完成。

3.4 3.4 Prometheus 三段式质量链

Prometheus 的 prompt 模块化程度最高,拆分为 6 个语义独立的文件:

文件职责
identity-constraints.ts身份锁定(“YOU ARE A PLANNER. YOU ARE NOT AN IMPLEMENTER. YOU DO NOT WRITE CODE.”)
interview-mode.ts7 种意图类型的面谈策略(Trivial → Tiki-Taka 快速来回;Architecture → 必须咨询 Oracle)
plan-generation.tsMetis 咨询 → gap 分类 → 摘要格式
high-accuracy-mode.tsMomus 审查循环
plan-template.ts计划文件 Markdown 模板
behavioral-summary.ts行为总结和最终约束
Prometheus 三段式质量保证链

身份锁定是最核心的设计决策——即使用户说”just do it”,Prometheus 也必须拒绝并解释为什么需要规划。这种设计通过 prometheus-md-only hook 在系统层面强制执行——非 .md 文件的写入会被 hook 拦截。

三段式质量保证链:Metis(前置 gap 分析)→ Prometheus(计划生成)→ Momus(后置可执行性验证)。Momus 有明确的”APPROVAL BIAS”(默认通过),只拦截真正的 blocker,避免无限修改循环。

增量写入协议identity-constraints.ts:163-228):大型计划会超出 LLM 的输出 token 限制,所以 prompt 要求先 Write 骨架,再用 Edit 分批追加任务(每批 2-4 个)。这是对 LLM 输出限制的显式适配。

3.5 3.5 构建、注册与权限控制

Agent 构建流程:所有 agent 遵循统一的工厂模式:

1 2 3 4// src/agents/types.ts export type AgentFactory = ((model: string) => AgentConfig) & { mode: AgentMode // "primary" | "subagent" | "all" }

buildAgent()src/agents/agent-builder.ts)是构建管线的核心,做三件事:

  1. 调用工厂函数source(model) 生成基础配置
  2. 应用 category 配置:如果 agent 声明了 category,从用户配置中继承 model/temperature/variant
  3. 注入 skill 内容:解析 skills 数组,将 skill 内容前置拼接到 prompt(skill 指令优先级高于 agent 自身 prompt)

createBuiltinAgents()src/agents/builtin-agents.ts:60)是整个 agent 系统的入口函数,执行顺序有严格依赖:

  1. fetchAvailableModels() — 查询当前 provider 的可用模型
  2. collectPendingBuiltinAgents() — 收集除 Sisyphus/Hephaestus/Atlas 外的所有 agent,进行模型解析和配置构建
  3. parseRegisteredAgentSummaries() — 解析外部插件注册的 agent,为它们生成 metadata
  4. maybeCreateSisyphusConfig() / maybeCreateHephaestusConfig() / maybeCreateAtlasConfig()最后构建主 agent

Sisyphus/Hephaestus/Atlas 必须最后构建,因为它们的动态 prompt 需要知道有哪些 subagent 可用。系统通过 isGptModel() 检测模型类型,对 GPT 模型使用 reasoningEffort: "medium" 而非 thinking: { type: "enabled", budgetTokens: 32000 }。Prometheus、Atlas、Sisyphus-Junior 都有完全独立的 GPT 优化 prompt(gpt.ts 文件)。

工具权限矩阵src/shared/permission-compat.ts)通过 createAgentToolRestrictions()createAgentToolAllowlist() 实现精细控制:

Agent策略被禁工具设计意图
Oracle黑名单write, edit, apply_patch, task只读顾问,防止”顾问自己动手”
Librarian / Explore黑名单write, edit, apply_patch, task, call_omo_agent只搜索不修改,不能派生子 agent
Multimodal Looker白名单只允许 read最严格,只能读文件
Metis / Momus黑名单write, edit, apply_patch, task只分析/审查不执行
Atlas黑名单task, call_omo_agent可以读写文件,但不能再派生 agent
Sisyphus-Junior黑名单task(但允许 call_omo_agent)可调 explore/librarian,但不能用 task() 委派

微妙的设计:Sisyphus-Junior 允许 call_omo_agent禁止 task。这意味着它可以调用 explore/librarian 做搜索,但不能像 Sisyphus 那样通过 task() 委派工作给其他 category。这防止了无限递归委派。

全局权限设置(tool-config-handler.ts):webfetch=allow, external_directory=allow, task=deny(默认禁止 task,仅特定 agent 开放)。CLI 运行模式下禁用 question 工具(非交互环境)。

自定义 Agent 支持parseRegisteredAgentSummaries() 解析外部插件注册的 agent,过滤掉 hiddendisabledenabled: false 的条目,buildCustomAgentMetadata() 为它们生成标准元数据(默认 category: "specialist", cost: "CHEAP")。这意味着:安装一个新的 OpenCode 插件注册的 agent,Sisyphus 会自动知道它的存在并在合适的场景下委派任务给它


4 四、工具体系

OMO 的工具体系分为三层:原生工具(src/tools/,直接与 AI agent 交互)、功能模块(src/features/,提供后台 agent、tmux、context injector 等复杂功能)、MCP 集成(src/mcp/,外部服务连接)。所有工具统一使用 @opencode-ai/plugin/tooltool() 工厂函数定义,遵循相同的 (args, context) => Promise 接口。

三层工具体系

4.1 4.1 完整工具清单

工具目录核心职责关键设计
ast-grep/AST 感知代码搜索/替换25 语言,元变量 $VAR/$$$,空结果智能提示
lsp/LSP 集成(6 个工具)4 层架构,双重诊断源(pull + push)
hashline-edit/行哈希精确编辑CID 哈希防幻觉,bottom-up 应用
interactive-bash/tmux 命令执行子命令黑名单,超时保护
background-task/后台任务 CRUD创建/输出查看/取消
delegate-task/任务委派中枢category 路由 + subagent 直接调用
call-omo-agent/内置 agent 调用explore/librarian,同步/异步
look-at/多模态文件分析创建子 session 调用 multimodal-looker
session-manager/历史 session 操作list/read/search/info,60s 超时保护
skill/ + skill-mcp/Skill 执行与 MCP 代理加载 Skill 内容注入 prompt / 代理 MCP 调用
task/任务 CRUDcreate/get/list/update + todo-sync
glob/ + grep/文件搜索与内容搜索内置 ripgrep 自动下载

工具注册入口在 src/tools/index.ts,LSP 的 6 个工具作为 builtinTools 静态导出,其余工具通过工厂函数按需创建。这种设计区分了”无状态工具”和”需要上下文的工具”。

4.2 4.2 Hashline Edit:防幻觉的精确编辑

src/tools/hashline-edit/ 是整个工具体系中最具创新性的设计,通过行级哈希防止 AI 编辑过时内容。

核心机制:每行内容生成 2 字符 CID 哈希(字符集 ZPMQVRWSNKTXJBYH),格式 LINE#ID(如 5#VK)。编辑操作必须携带正确的 LINE#ID 锚点,哈希不匹配则拒绝编辑并提示重新读取文件。4 种操作:set_linereplace_linesinsert_afterreplace。编辑从底部向上应用(bottom-up),保持行号引用稳定。

解决的核心痛点:传统的精确文本匹配(如 Claude Code 的 Edit)在 AI 记忆不一致时会静默失败或错误编辑。Hashline Edit 将”文件是否过时”的检测前置到工具层,从根本上消除了基于过时内容编辑的问题。2 字符哈希在 token 开销和碰撞率之间取得了平衡——16^2 = 256 种组合,对于单个文件的行数来说碰撞概率极低。

4.3 4.3 LSP 与 AST-grep

LSP 4 层架构

1 2 3 4LSPClient (lsp-client.ts) — 高层 API:openFile/definition/references/diagnostics └── LSPClientConnection — JSON-RPC 连接管理、请求/通知 └── lsp-client-transport.ts — stdio 传输层 └── lsp-process.ts — LSP 服务器进程管理

提供 6 个工具:

工具功能LSP 方法
lsp_goto_definition跳转到定义textDocument/definition
lsp_find_references查找引用textDocument/references
lsp_symbols文档/工作区符号textDocument/documentSymbol, workspace/symbol
lsp_diagnostics获取诊断信息textDocument/diagnostic + 推送诊断
lsp_prepare_rename重命名预检textDocument/prepareRename
lsp_rename执行重命名textDocument/rename

关键设计:

  • 文档版本追踪documentVersions Map 维护每个文件的版本号,确保 didChange 通知携带正确版本
  • 内容去重lastSyncedText Map 缓存上次同步文本,避免无变化时发送冗余通知
  • 双重诊断源:先尝试 pull 模式(textDocument/diagnostic),失败回退到 push 模式(diagnosticsStore
  • 服务器自动管理server-config-loader.ts 自动发现,server-installation.ts 自动安装

这比纯文本 grep 强太多了——AI 可以精确地找到一个函数的所有调用者,而不是搜索字符串碰运气。

AST-grep 智能提示:基于 ast-grep 实现结构化代码搜索,与 LSP 互补——LSP 擅长精确的符号级操作,AST-grep 擅长模式匹配(如”找到所有 console.log 调用”)。支持 25 语言、元变量模式($VAR 单节点、$$$ 多节点)、二进制自动下载。getEmptyResultHint() 在空结果时给出修正建议——AI agent 经常写出不完整的 AST 模式(如只写函数名不写参数),智能提示大幅降低了工具调用失败率。

4.4 4.4 delegate-task 任务委派中枢

createDelegateTask()src/tools/delegate-task/tools.ts,220+ 行)是最复杂的工具,支持:

  • category 路由:指定 category → 自动使用 Sisyphus-Junior agent + category 对应的模型配置
  • subagent 直接调用:指定 subagent_type → 直接使用该 agent
  • session 续写:通过 session_id 继续已有 session,保持完整上下文
  • 同步/异步执行run_in_background=true 返回 task_id,false 等待结果
  • Skill 注入load_skills 参数加载 Skill 内容注入到 agent system prompt
  • 不稳定 agent 处理isUnstableAgent 标记的 category 使用特殊执行路径

tool-execute-before.ts 中的 agent 路由逻辑:

1 2 3 4 5 6 7 8if (input.tool === "task") { if (category) { argsObject.subagent_type = "sisyphus-junior" } else if (!subagentType && sessionId) { const resolvedAgent = await resolveSessionAgent(ctx.client, sessionId) argsObject.subagent_type = resolvedAgent ?? "continue" } }

resolveSessionAgent()src/plugin/session-agent-resolver.ts)通过查询会话的消息历史,找到第一条包含 agent 信息的消息,从而确定该会话使用的 agent。

4.5 4.5 MCP 集成策略

三个内置 MCP 服务器(全部 remote HTTP/SSE 连接):

MCP服务地址用途认证
websearchmcp.exa.ai(默认)/ mcp.tavily.com通用网络搜索API key
context7mcp.context7.com库文档查询可选 API key
grep_appmcp.grep.app跨开源仓库代码搜索无需认证

三个 MCP 覆盖了 AI 编程助手的三个核心外部信息需求:最新信息(websearch)、API 用法(context7)、实现参考(grep_app)。createBuiltinMcps()src/mcp/index.ts)统一注册,全部使用 remote MCP 避免本地进程管理复杂性,支持通过 disabled_mcps 配置禁用。


5 五、后台 Agent 并发模型

这是 OMO 的第二大创新——让 AI agent 能像人类开发者一样”开多个终端窗口并行干活”。由两个核心模块协作:src/features/background-agent/(逻辑层,负责并发控制、任务生命周期、完成检测)和 src/features/tmux-subagent/(可视化层,负责 tmux pane 管理、布局规划)。

5.1 架构时序图

后台 Agent 并发模型时序流程

5.2 5.1 ConcurrencyManager:三级并发控制 + settled-flag

ConcurrencyManagersrc/features/background-agent/concurrency.ts)实现三级粒度并发控制:

  1. 模型级限制modelConcurrency["anthropic/claude-sonnet-4-5"] = 3
  2. Provider 级限制providerConcurrency["anthropic"] = 5
  3. 全局默认defaultConcurrency = 5

查找顺序是 model → provider → default。不同模型的 rate limit 不同,Claude Haiku 可以开 10 个并发,Opus 可能只能开 2 个。

并发槽通过 Promise 队列实现等待:acquire() 在槽满时返回 pending Promise,release() 时将槽交给队列中的下一个等待者。

settled-flag 防 double-resolutionconcurrency.ts:8-13):这是一个容易被忽略但很重要的细节——当 cancelWaiters()release() 同时操作同一个 queue entry 时,没有这个 flag 就会出现 Promise 被 resolve 又被 reject 的问题。JavaScript 的单线程模型在大多数情况下保护了这一点,但 settled-flag 提供了额外的安全保障。

5.3 5.2 BackgroundManager 任务生命周期

BackgroundManagersrc/features/background-agent/manager.ts)管理完整的任务生命周期(pending → running → completed/error/cancelled/interrupt)。核心设计:

  • Fire-and-Forget Prompt 模式:任务启动后,prompt 通过 promptWithModelSuggestionRetry() 以 fire-and-forget 方式发送,不等待响应。错误通过 .catch() 异步处理,标记 interrupt、释放并发槽、abort session。
  • 双重完成检测——两条路径互为备份:
    • 事件驱动:监听 session.idle 事件,经过 MIN_IDLE_TIME_MS(5秒)最小运行时间校验
    • 轮询兜底pollRunningTasks() 定期检查所有 session 状态

两条路径通过 tryCompleteTask() 汇聚,用状态检查实现原子性防止重复完成:

1 2 3 4 5 6 7 8 9// src/features/background-agent/manager.ts:1139-1183 private async tryCompleteTask(task: BackgroundTask, source: string): Promise<boolean> { if (task.status !== "running") return false // 防止竞态 task.status = "completed" // 原子标记 // 释放并发槽 BEFORE 任何异步操作,防止槽泄漏 if (task.concurrencyKey) { this.concurrencyManager.release(task.concurrencyKey) } }
  • 输出验证防止误完成validateSessionHasOutput() 在标记完成前验证 session 确实有 assistant 输出(检查 text/reasoning/tool/tool_result 多种 part 类型),防止 session.idle 在 agent 还没响应时就触发完成。
  • 批量通知机制pendingByParent Map 追踪每个父 session 的待完成任务。单个完成 → 静默通知(noReply: true);全部完成 → 汇总通知并触发父 session 响应。notificationQueueByParent 确保同一父 session 的通知串行发送,避免消息乱序。
  • 过期清理与僵尸防护
    • pruneStaleTasksAndNotifications():30 分钟 TTL(TASK_TTL_MS)自动清理
    • checkAndInterruptStaleTasks():检测无活动的 running 任务并中断
    • 进程退出时 shutdown() abort 所有 running session,registerProcessCleanup() 注册 SIGINT/SIGTERM/beforeExit 信号处理

5.4 5.3 TmuxSessionManager 与两层协作

TmuxSessionManagersrc/features/tmux-subagent/manager.ts)将后台 agent 映射到 tmux pane,实现可视化的并行执行。架构遵循 Query-Decide-Execute-Update 模式:

1 2 3 41. QUERY: queryWindowState() → 获取 tmux 实际 pane 状态(唯一真实来源) 2. DECIDE: decideSpawnActions() → 纯函数决定操作(spawn/close/replace) 3. EXECUTE: executeActions() → 执行 tmux 操作 4. UPDATE: sessions.set() → 仅在 tmux 确认成功后更新内部缓存

将 tmux 的实际状态作为唯一真实来源,内部 Map 仅作缓存,避免了状态不一致问题。纯函数 decideSpawnActions() 使决策逻辑可测试。

支持网格布局规划(grid-planning.ts 计算终端尺寸)、延迟队列(容量不足时 deferredSessions 等待空间释放后自动附加)、串行化 spawn(enqueueSpawn() 通过 Promise 链确保 spawn 操作串行执行,避免并发 tmux 操作导致的竞态)。三种 pane 操作:spawn(分割新 pane)、close(关闭已完成 pane)、replace(用新 session 替换旧 pane,避免频繁开关)。

BackgroundManagerTmuxSessionManager 通过回调连接:

1 2 3 4 5 6 7// src/features/background-agent/manager.ts:285-298 if (this.onSubagentSessionCreated && this.tmuxEnabled && isInsideTmux()) { await this.onSubagentSessionCreated({ sessionID, parentID: input.parentSessionID, title: input.description, }) await new Promise(r => setTimeout(r, 200)) // 等待 tmux pane 就绪 }

BackgroundManager 创建 session 后通知 TmuxSessionManager 创建对应的 pane。200ms 延迟确保 tmux pane 在 prompt 发送前就绪。这让用户能在 tmux 里实时看到每个后台 agent 在干什么——不是黑盒,而是透明的。

为什么不用 Worker Threads?因为 OMO 不是自己运行 agent,而是通过 OpenCode 的 session API 创建新会话。每个后台 agent 就是一个独立的 OpenCode session,有自己的上下文和工具权限,完全复用了 OpenCode 的基础设施(模型调用、工具执行、权限管理)。


6 六、Ralph Loop 自动续跑

Ralph Loop 是 OMO 最有”性格”的功能——当 agent 完成一轮工作后,如果任务还没完成,自动注入 continuation prompt 让它继续干。名字来源于”像 Ralph 一样不知疲倦地工作”。核心思想:让 AI agent 在循环中反复执行,直到满足”完成承诺”(completion promise)或达到最大迭代次数。

6.1 状态机

Ralph Loop 自动续跑状态机

6.2 6.1 完整工作流

两条启动路径:

  1. Skill 命令路径:用户通过 /ralph-loop/ulw-loop 命令启动 → tool-execute-before 拦截 skill 调用 → 解析参数(prompt、max-iterations、completion-promise)
  2. 消息模板路径chat-message.ts 检测消息文本是否包含 Ralph Loop 模板标记 → 解析 <user-task> 标签中的任务描述 → 提取 --max-iterations--completion-promise 参数

启动后:

  1. loopState.startLoop() 创建循环状态并持久化到 .sisyphus/ralph-loop.local.md
  2. session.idle 事件触发时,ralph-loop-event-handler.ts 检查:
    • 是否在恢复中(跳过)
    • 是否检测到完成承诺(通过 transcript 文件或 session messages API)
    • 是否达到最大迭代次数
  3. 如果未完成,递增迭代计数,注入续写提示(continuation prompt)

关键组件:

  • loop-state-controller.ts:管理循环状态的 CRUD
  • completion-promise-detector.ts:双通道检测完成
  • continuation-prompt-builder.ts:构建带上下文的续写提示
  • ralph-loop-event-handler.ts:事件驱动的循环控制器
  • loop-session-recovery.ts:处理循环中的错误恢复

6.3 6.2 completion_promise 双通道检测

用户指定完成承诺(如 --completion-promise="all tests pass"),Ralph Loop 在 agent 输出中搜索该字符串。检测采用双通道策略:

  1. Transcript 文件扫描(快速、无网络开销):直接读 session 的 transcript 文件,搜索 completion_promise 关键词
  2. Session Messages API(准确但慢):通过 API 查询最近的消息内容

先尝试 transcript 文件,失败再回退到 API。这比简单的”agent 说 done 就停”要可靠得多——agent 可能说”I’m done”但实际上测试还没跑。<promise>DONE</promise> 标签机制让 agent 能够明确表达”任务已完成”,避免无限循环。

6.4 6.3 Ultrawork 变体与续写 prompt

ulw-loop 是 Ralph Loop 的增强版,在续写提示前触发 ultrawork 模型覆盖。

Ultrawork 模型覆盖的实现(src/plugin/chat-message.ts):

  • applyUltraworkModelOverrideOnMessage() 检测消息中是否包含 “ultrawork”/“ulw” 关键词
  • 如果检测到,通过 scheduleDeferredModelOverride() 在 microtask 中修改 SQLite,切换到更强大的模型
  • 巧妙之处:TUI 底栏仍显示原始模型,但 API 调用使用覆盖后的模型——这是一个非常 hack 但有效的方案,利用了 OpenCode 读取模型配置和实际发送 API 请求之间的时间差

续写 prompt 由 continuation-prompt-builder.ts 构建,包含:

  • 当前迭代进度(如 “Iteration 3/10”)
  • 原始用户任务描述
  • 完成承诺格式提醒
  • 上下文信息(之前的工作进展)

这确保了 agent 在每次续写时都能回忆起完整的任务上下文,不会因为上下文压缩而丢失关键信息。


7 七、Hook 系统与消息拦截

OMO 通过 OpenCode 的插件 hook 机制,在 AI 交互的各个阶段注入自定义逻辑。

7.1 Hook 触发点图

Hook 系统触发点与消息拦截链

7.2 7.1 Hook 创建与分发

Hook 创建由 src/create-hooks.ts 统一编排,分为三大类:

1 2 3 4 5 6 7createHooks() ├── createCoreHooks() // src/plugin/hooks/create-core-hooks.ts │ ├── createSessionHooks() // 会话生命周期相关 │ ├── createToolGuardHooks() // 工具执行守卫 │ └── createTransformHooks() // 消息变换 ├── createContinuationHooks() // 续写/自动化相关 └── createSkillHooks() // 技能相关

安全机制:safeCreateHook() 包装器确保单个 hook 的创建失败不会影响整个插件启动。每个 hook 都可以通过 isHookEnabled() 独立启用/禁用。

createEventHandler()src/plugin/event.ts)分发事件到 18 个 hook,按固定顺序执行:

1 2 3 4 5 6autoUpdateChecker → claudeCodeHooks → backgroundNotificationHook → sessionNotification → todoContinuationEnforcer → unstableAgentBabysitter → contextWindowMonitor → directoryAgentsInjector → directoryReadmeInjector → rulesInjector → thinkMode → anthropicContextWindowLimitRecovery → agentUsageReminder → categorySkillReminder → interactiveBashSession → ralphLoop → stopContinuationGuard → compactionTodoPreserver → atlasHook

这个顺序是有意义的:监控类 hook 先执行,然后是内容注入类,最后是控制流类。某些 hook 之间存在隐式依赖(如 stopContinuationGuard 必须在 ralphLoop 之后,确保用户主动停止时不自动恢复)。

7.3 7.2 Synthetic Idle 去重与事件处理

event.ts 实现了一个精巧的去重机制:

1 2 3const recentSyntheticIdles = new Map<string, number>() const recentRealIdles = new Map<string, number>() const DEDUP_WINDOW_MS = 500

问题背景:OpenCode 的 session.status 事件中 status.type === "idle"session.idle 事件可能在短时间内重复触发。normalizeSessionStatusToIdle()session.status(idle) 转换为合成的 session.idle 事件,但这可能与真实的 session.idle 重复。解决方案:在 500ms 窗口内,如果已经处理了真实的 idle,就跳过合成的 idle,反之亦然。

关键 hook 简析:

  • context-window-monitor:跟踪 token 使用量,区分 Anthropic 的”显示限制”(1M)和”实际限制”(200K 或 1M),避免 agent 被虚假的 token 计数误导
  • preemptive-compaction:在上下文快满之前主动触发压缩,保留更多有用的上下文信息
  • tool-output-truncator:根据模型上下文窗口大小动态决定截断阈值
  • session-recovery:检测可恢复错误(如 API 超时),自动发送 “continue” 恢复会话
  • anthropic-context-window-limit-recovery:专门处理 Anthropic API 上下文超限,实现 aggressive-truncation、deduplication-recovery、empty-content-recovery 多种恢复策略
  • session-notification:跨平台通知(macOS AppleScript、Windows PowerShell toast、Linux),智能冲突检测避免与外部通知插件重复

特定事件处理:

  • session.created:设置主会话、标记首消息变体门控、通知 tmux 会话管理器
  • session.deleted:清理会话状态(agent 映射、消息游标、skill MCP 连接、tmux 面板)
  • message.updated:跟踪每个会话当前使用的 agent
  • session.error:检测可恢复错误,自动发送 “continue” 恢复会话

7.4 7.3 消息拦截链

createChatMessageHandler()src/plugin/chat-message.ts)是最复杂的消息拦截器。一条消息进来后,依次经过:

1 2 3variant 解析 → stopContinuationGuard → keywordDetector → claudeCodeHooks → autoSlashCommand → noSisyphusGpt → noHephaestusNonGpt → startWork → ralphLoop → ultraworkModelOverride

Agent Variant 解析

  • 首消息使用 firstMessageVariantGate 控制是否覆盖 variant
  • 后续消息根据 model 和 agent 解析 variant
  • 支持 per-model variant 配置(resolveVariantForModel

每个 hook 都可以修改消息内容或触发副作用。这种混合模式灵活但也增加了调试难度——有些 hook 只读(keywordDetector),有些会修改输出(autoSlashCommand),有些会触发异步副作用(ralphLoop)。Ultrawork 延迟 DB 覆盖(六章已述)在此链末端执行。

7.5 7.4 Context Injector 与 Claude Code Hooks

Context Injectorsrc/features/context-injector/)实现优先级上下文注入系统。

ContextCollectorcollector.ts)按 session 维护待注入条目,支持 4 级优先级:

1 2 3const PRIORITY_ORDER: Record<ContextPriority, number> = { critical: 0, high: 1, normal: 2, low: 3, }

每个条目有 sourceidcontentprioritymetadataconsume() 方法按优先级排序后合并所有条目,然后清空队列。

注入通过两种 hook 实现(injector.ts):

  • chat.message hook:在输出的 text part 前插入上下文
  • experimental.chat.messages.transform hook:在最后一条 user message 中插入 synthetic part(synthetic: true 标记使其在 UI 中隐藏)

这是一个跨 hook 的数据共享机制——keyword-detector 和 claude-code-hooks 在处理消息时收集上下文,然后在 messages.transform 阶段统一注入。synthetic: true 标记既保证了 agent 能看到必要信息,又不污染用户的对话界面。

Claude Code Hooks 兼容层src/hooks/claude-code-hooks/)是一个完整的子系统,提供与 Claude Code 原生 hooks 的兼容:

  • claude-code-hooks-hook.ts:总入口,创建 5 个处理器
    • experimental.session.compacting — 压缩前处理
    • chat.message — 消息拦截
    • tool.execute.before — 工具执行前
    • tool.execute.after — 工具执行后
    • event — 事件处理
  • config-loader.ts / config.ts:加载 Claude Code 的 hooks 配置
  • transcript.ts:管理对话 transcript 文件
  • user-prompt-submit.ts:处理用户提交的 prompt
  • session-hook-state.ts:维护 hook 的会话状态

设计意图:让用户在 Claude Code 中配置的 hooks(如 pre-tool-use、post-tool-use)能够在 OMO 的插件架构中正常工作,实现零成本迁移。


8 八、配置系统与 Model Fallback

8.1 8.1 多层配置合并与容错

配置来源(优先级从高到低):

  1. 项目级:.opencode/oh-my-opencode.json[c]
  2. 用户级:~/.config/opencode/oh-my-opencode.json[c]
  3. 内置默认值

支持 JSONC(带注释的 JSON,基于 jsonc-parser 库),用 Zod 做 schema 验证。detectConfigFile() 自动检测 .jsonc.json 后缀,优先使用 .jsonc

loadConfigFromPath()src/plugin-config.ts)实现两级容错:

  1. 完整验证OhMyOpenCodeConfigSchema.safeParse() 尝试完整解析
  2. 部分加载:验证失败时 parseConfigPartially() 逐字段尝试——对每个顶层 key 单独做 safeParse({ [key]: rawConfig[key] }),有效的保留、无效的跳过并记录错误

这确保了一个配置项的错误不会导致整个配置失效。

配置合并规则(mergeConfigs()):

  • agents / categories / claude_code:使用 deepMerge() 递归合并(带原型链污染防护,过滤 __proto__/constructor/prototype,最大递归 50 层)
  • disabled_* 数组:使用 Set 去重后并集合并
  • 其他字段:简单覆盖(...base, ...override

Schema 设计特点(src/config/schema/oh-my-opencode-config.ts):全字段 optional(支持最小化配置)、模块化子 schema、统一的 disabled_* 模式覆盖 agents/mcps/hooks/commands/skills/tools 六个维度、_migrations 字段记录已应用的迁移。

8.2 8.2 双层 Model Fallback

安装时和运行时存在两套独立的 fallback 机制,这不是冗余而是有意为之——安装时基于用户声明的订阅状态做静态配置,运行时基于实际可用模型做动态降级。两层机制覆盖了”用户知道自己有什么”和”系统发现实际有什么”两种场景。

双层 Model Fallback 机制

安装时静态降级src/cli/model-fallback.ts):

基于 ProviderAvailability 布尔结构体(用户声明的订阅状态),通过 generateModelConfig() 生成静态配置文件。简单、确定性强。

特殊处理:

  • librarian 固定使用 opencode/minimax-m2.5-free(免费模型)
  • explore 有独立的 4 级降级逻辑
  • sisyphus 使用 requiresAnyModel 约束
  • 无任何 provider 时全部使用 ULTIMATE_FALLBACKopencode/big-pickle

运行时动态降级src/shared/model-resolution-pipeline.ts):

基于实际可用的模型列表(从 OpenCode API 或缓存获取),实现四级优先级管道:

1 2 3 4 5type ModelResolutionRequest = { intent?: { uiSelectedModel?; userModel?; categoryDefaultModel? } // 用户意图 constraints: { availableModels: Set<string>; connectedProviders? } // 环境约束 policy?: { fallbackChain?: FallbackEntry[]; systemDefaultModel? } // 降级策略 }

解析流程:

  1. UI 选择 / 用户覆盖:直接返回,不做可用性检查(信任用户意图)
  2. Category 默认:先尝试 fuzzy match 可用模型集;若模型集为空,回退到 connected-providers-cache 检查 provider 是否连接
  3. Fallback Chain:遍历链中每个 entry,对每个 provider 做 fuzzy match;还支持跨 provider 模糊匹配作为最后手段
  4. 系统默认:兜底模型

解析结果携带 provenance 字段标记模型来源(override / category-default / provider-fallback / system-default),便于调试和日志追踪。

Agent 模型需求矩阵src/shared/model-requirements.ts)定义每个 agent 的降级链:

Agent首选模型降级路径特殊约束
sisyphusclaude-opus-4-6 (max)→ kimi-k2p5 → glm-5 → big-picklerequiresAnyModel
hephaestusgpt-5.3-codex (medium)无降级requiresProvider: openai/copilot/opencode
oraclegpt-5.2 (high)→ gemini-3-pro → claude-opus-4-6
prometheusclaude-opus-4-6 (max)→ gpt-5.2 → kimi → gemini-3-pro
librariangemini-3-flash→ minimax-m2.5-free → big-pickle
exploregrok-code-fast-1→ minimax-m2.5-free → claude-haiku → gpt-5-nano

每个 provider 列表中通常包含 github-copilotopencode 作为备选通道,同一个模型可以通过不同的 API 网关访问。

CATEGORY_MODEL_REQUIREMENTS 定义了 8 个语义化 category 的模型偏好:

Category首选模型选择理由
visual-engineeringgemini-3-pro视觉能力
ultrabraingpt-5.3-codex xhigh最强推理
deepgpt-5.3-codex medium深度执行
artistrygemini-3-pro创意生成
quickclaude-haiku-4-5速度优先
unspecified-lowclaude-sonnet-4-6通用低成本
unspecified-highclaude-opus-4-6 max通用高质量
writingkimi-k2p5长文写作

8.3 8.3 fuzzy match 与配置迁移

fuzzyMatchModel()src/shared/model-name-matcher.ts / model-availability.ts)的匹配策略:

  • 大小写不敏感
  • 版本号标准化(claude-opus-4-6claude-opus-4.6
  • 子串匹配
  • 优先级排序:精确匹配 > 精确 model ID 匹配 > 最短匹配

connected-providers-cache.ts 实现两级缓存:connected-providers.json(已连接 provider ID 列表)和 provider-models.json(每个 provider 的可用模型列表),通过 updateConnectedProvidersCache() 从 OpenCode SDK 刷新。

配置迁移系统src/shared/migration/config-migration.ts)编排四种迁移:

  1. Agent 名称omo/OmOsisyphusOmO-Planprometheusorchestrator-sisyphusatlasplan-consultantmetis
  2. Hook 名称anthropic-auto-compactanthropic-context-window-limit-recoverysisyphus-orchestratoratlas
  3. 模型版本openai/gpt-5.2-codexopenai/gpt-5.3-codexanthropic/claude-opus-4-5anthropic/claude-opus-4-6
  4. 字段迁移omo_agentsisyphus_agentexperimental.hashline_edit → 顶层 hashline_edit

安全机制:

  • _migrations 记录防止重复迁移(用户手动回退模型版本后不会被再次自动升级)
  • 迁移前创建带时间戳的 .bak 备份
  • 内存回写确保即使文件写入失败也能生效
  • disabled_agents / disabled_hooks 同步迁移名称

8.4 8.4 Skill 系统六源发现

src/features/opencode-skill-loader/loader.ts 实现六源 Skill 发现,按优先级去重:

1 2 3opencode-project (.opencode/skills/) > opencode-global (~/.config/opencode/skills/) > project-claude (.claude/skills/) > project-agents (.agents/skills/) > user-claude (~/.claude/skills/) > user-agents (~/.agents/skills/)

Skill 加载管线:skill-directory-loader.ts(目录扫描)→ skill-content.ts(解析内容和 frontmatter)→ skill-deduplication.ts(按名称去重,先出现的优先)→ merger/(合并来自不同源的定义)。

内置 5 个技能(src/features/builtin-skills/skills.ts):playwright / playwright-cli / agent-browser(三选一,由 browserProvider 配置决定)、frontend-ui-ux、git-master、dev-browser。

SkillMcpManagersrc/features/skill-mcp-manager/manager.ts)管理 Skill 关联的 MCP 连接:以 sessionID:skillName:serverName 为 key 复用连接,withOperationRetry() 最多重试 3 次,支持 OAuth step-up 认证升级,双传输支持(stdio + HTTP/SSE)。


9 九、Claude Code 兼容层

OMO 能加载 Claude Code 生态的资源(commands、agents、MCP servers、plugins、skills、hooks),让用户从 Claude Code 迁移到 OpenCode + OMO 时零成本复用已有配置。这是一个很有商业头脑的设计——OMO 不只是 OpenCode 的插件,它还能加载 Claude Code 生态的资源。

Claude Code 兼容层 - 四个 Loader 架构

四个 Loader 各司其职:

claude-code-plugin-loadersrc/features/claude-code-plugin-loader/loader.ts)是兼容层的顶层入口,discovery.ts 在 node_modules 中扫描符合 Claude Code 插件规范的包,并行加载 commands、skills、agents、mcpServers、hooksConfigs,带 10 秒超时保护防止插件加载阻塞启动。

claude-code-command-loadersrc/features/claude-code-command-loader/loader.ts)从四个位置加载 Markdown 命令文件:

优先级路径作用域
1{cwd}/.opencode/command/opencode 项目级
2~/.config/opencode/command/opencode 全局
3{cwd}/.claude/commands/Claude Code 项目级
4~/.claude/commands/Claude Code 用户级

命令文件使用 frontmatter 格式,支持 descriptionagentmodelsubtaskhandoffs 等元数据。模板中 $ARGUMENTS 占位符在执行时替换为用户输入。

claude-code-agent-loadersrc/features/claude-code-agent-loader/loader.ts)从 ~/.claude/agents/{cwd}/.claude/agents/ 加载 Markdown 格式的 agent 定义,Markdown body 作为 agent prompt,frontmatter 中的 tools 字段转换为工具权限配置。

claude-code-mcp-loadersrc/features/claude-code-mcp-loader/loader.ts)从四个位置加载 .mcp.json 配置(~/.claude.json~/.claude/.mcp.json{cwd}/.mcp.json{cwd}/.claude/.mcp.json),transformer.ts 将 Claude Code 格式转换为 OpenCode 兼容格式,env-expander.ts 处理环境变量展开。

资源类型Claude Code 路径OpenCode 路径优先级
命令~/.claude/commands/~/.config/opencode/command/OpenCode > Claude Code
命令(项目){cwd}/.claude/commands/{cwd}/.opencode/command/OpenCode > Claude Code
Agent~/.claude/agents/ / {cwd}/.claude/agents/直接加载
MCP~/.claude.json / ~/.claude/.mcp.json / {cwd}/.mcp.json直接加载
Skill~/.claude/skills/ / {cwd}/.claude/skills/~/.config/opencode/skills/ / {cwd}/.opencode/skills/OpenCode > Claude Code

10 十、创新亮点深度解析

Oh My OpenCode 8 大创新亮点
  1. AgentPromptMetadata 自描述系统:多 agent 系统中主编排 agent 需要知道所有可用 agent 的能力,传统做法是在主 agent 的 prompt 中硬编码。OMO 让每个 agent 通过 AgentPromptMetadata 声明式描述自己,dynamic-agent-prompt-builder.ts 自动聚合生成 Delegation Table 等段落。添加新 agent 不需要修改 Sisyphus 的代码,第三方插件注册的 agent 也能通过 buildCustomAgentMetadata() 自动融入,实现了真正的开放-封闭原则。
  2. Hashline Edit 防幻觉编辑:AI 基于过时文件内容生成编辑指令时,传统精确文本匹配会静默失败。Hashline Edit 用 2 字符 CID 哈希(16^2 = 256 种组合)标记每行,哈希不匹配则拒绝编辑并提示重新读取,将”文件是否过时”的检测前置到工具层。2 字符哈希在 token 开销和碰撞率之间取得了平衡——对于单个文件的行数来说碰撞概率极低。
  3. Ralph Loop completion_promise:AI agent 单次对话可能无法完成复杂任务(上下文窗口限制、任务复杂度),且”agent 说 done 就停”不可靠——agent 可能说”I’m done”但实际上测试还没跑。用户指定 completion_promise 将”完成”的定义权交给用户,双通道检测(transcript 文件扫描 + Session Messages API 回退)在速度和准确性之间取得平衡。
  4. 双轨主 Agent(Sisyphus vs Hephaestus):不同任务需要不同行为模式——有些适合快速委派(“帮我查一下这个 API”),有些适合深度自主执行(“重构整个认证模块”)。Sisyphus 委派优先适合协调型任务,Hephaestus 自主优先适合深度执行。Prompt 工程实践表明,行为模式切换比参数微调更可靠——LLM 对”你是管理者”和”你是执行者”的响应差异远大于”autonomy=0.7 vs 0.3″。
  5. 三级并发控制 + settled-flag:不同模型 rate limit 不同,简单全局限制要么浪费 Haiku 高并发能力,要么触发 Opus rate limit。三级粒度(模型 > Provider > 全局)允许精细控制(如 Opus 并发 1,Haiku 并发 10),同时提供合理的默认值。settled-flag 是对 Promise 语义的防御性编程——虽然 JS 单线程模型在大多数情况下保护了这一点,但显式标志消除了所有边界情况。
  6. TmuxSessionManager QDEU 架构:tmux 状态管理容易出现内部缓存与实际 pane 不一致,尤其在并发操作和异常恢复场景下。Query-Decide-Execute-Update 四步架构将 tmux 实际状态作为唯一真实来源,内部 Map 仅作缓存,纯函数 decideSpawnActions() 使决策逻辑可测试。
  7. Prometheus 三段式质量链:AI 生成的计划可能遗漏关键步骤、引用不存在的文件、或包含不可执行指令。Metis(前置 gap 分析)→ Prometheus(计划生成)→ Momus(后置审查)使用不同 agent 和视角,避免”自己审查自己”的盲点。Momus 的 APPROVAL BIAS 是务实的——过度严格的审查会导致无限修改循环,浪费 token。
  8. Context Injector Synthetic Part:hook 系统需要向 agent 注入上下文(如 keyword 检测结果、Claude Code hooks 输出)但不应出现在用户界面。通过 synthetic: true 标记的 part 利用 OpenCode 的 UI 渲染机制实现”agent 可见、用户不可见”的信息注入,不污染对话历史,也不占用 system prompt 空间。

11 十一、问题与改进建议

11.1 11.1 复杂度热点

模块问题建议
delegate-task/tools.ts220+ 行,承担参数验证/Skill 解析/模型选择/category 路由等多重职责进一步拆分为独立函数
agent-config-handler.ts226 行处理迁移/发现/创建/合并/排序拆分为 agent-migrator、agent-discoverer、agent-merger
tool-execute-before承担 hook 分发/task 路由/ralph-loop 解析/stop-continuation按职责拆分
Sisyphus prompt约 500 行,随 agent/category/skill 增加持续膨胀引入 prompt 分层加载或压缩
chat-message.tsRalph Loop 检测重复存在于此和 tool-execute-before.ts统一入口,避免状态不一致

11.2 11.2 硬编码与魔数

位置魔数风险
lsp-client.ts:37setTimeout(r, 1000) openFile 后等待不同 LSP 服务器可能不够或过长
lsp-client.ts:97setTimeout(r, 500) diagnostics 前等待同上
manager.ts:295setTimeout(r, 200) tmux callback 后等待高负载下可能不足
event.tsDEDUP_WINDOW_MS = 500 synthetic idle 去重缺乏自适应能力

更好的方案是等待特定的 LSP 通知(如 textDocument/publishDiagnostics)或 tmux pane 就绪信号,而非硬编码等待时间。

11.3 11.3 代码重复与一致性

问题位置建议
fuzzyMatchModel() 重复实现model-name-matcher.ts + model-availability.ts合并为单一实现
Ralph Loop 启动逻辑重复chat-message.ts + tool-execute-before.ts统一入口
安装时 librarian 硬编码 minimax-m2.5-free,运行时首选 gemini-3-flashCLI vs shared统一模型选择逻辑
disabled_* 并集合并项目级无法”取消”用户级禁用项支持显式启用覆盖
配置迁移 JSON.stringify 写回丢失 JSONC 注释使用保留注释的序列化
自定义 Agent 元数据过于简化统一 category: "specialist", cost: "CHEAP"允许外部 agent 声明真实成本

11.4 11.4 可靠性风险

  • BackgroundManager 的 tasks Map 在高并发场景下有内存泄漏风险(依赖定时器清理,notifyParentSession() 持续失败时任务可能在 completionTimers 中积累)
  • MCP 全部依赖远程服务,网络不可用时完全不可用,缺乏本地 fallback
  • 全局状态(getMainSessionID()subagentSessions 等)在多模块间共享,增加测试难度和并发风险
  • 18 个 hook 的调用顺序硬编码且存在隐式依赖,顺序被意外修改可能导致难以调试的问题
  • Plugin Components 加载的 10 秒超时对网络环境差的情况可能不够,但对快速启动又太长,缺乏重试机制
  • 多处使用 .catch(() => {}) 静默吞掉错误(如 toast 通知、session prompt),虽然防止了崩溃,但可能掩盖真实问题

12 十二、总体评价

12.1 亮点

  1. Agent 编排设计成熟:不是简单的”多个 agent 轮流说话”,而是有明确的职责分工、成本意识、工具权限隔离和动态 prompt 构建。AgentPromptMetadata 自描述系统实现了真正的开放-封闭原则。这是我见过的开源项目中最完善的 multi-agent 编排方案之一。
  2. 工程质量高:测试覆盖充分(256 个测试文件,67k 行测试代码——几乎等于实现代码量),类型安全(Zod schema + TypeScript),错误处理完善(settled-flag 防 double-resolution、session recovery、error classifier、渐进式容错配置加载),日志系统完整。
  3. 用户体验考虑周到:tmux 可视化让后台 agent 不再是黑盒,Toast 通知让用户知道发生了什么,Ralph Loop 的 completion_promise 让自动化可控,Hashline Edit 防止 AI 编辑过时内容。
  4. 生态兼容性强:Claude Code 兼容层覆盖了全部扩展点(commands、agents、MCP servers、plugins、skills、hooks),路径兼容让用户零成本迁移。
  5. 配置灵活但有默认值:开箱即用,但几乎所有行为都可以通过配置调整。双层 Model Fallback(安装时静态 + 运行时动态)确保总能找到可用模型。渐进式容错确保单个配置项错误不影响全局。

12.2 最终判断

Oh My OpenCode 是一个工程质量很高、设计理念先进的项目。它不是一个简单的配置文件集合,而是一个真正的 multi-agent 编排框架,恰好以 OpenCode 插件的形式存在。

作者(YeonGyu Kim)显然对 AI agent 的实际使用有深入理解——从 Sisyphus prompt 中”不要 shotgun debug”、“Oracle 的价值在你觉得不需要它的时候最高”这些细节就能看出来。这不是纸上谈兵,而是大量实际使用经验的结晶。

如果你在用 OpenCode,OMO 值得一试。如果你在研究 multi-agent 编排,OMO 的 agent 体系和 prompt 工程值得深入学习。

Agents 模型
Agent Model Variant
sisyphus (主 agent) minimax/MiniMax-M2.5-MLX-8bit medium
hephaestus minimax/MiniMax-M2.5-MLX-8bit medium
oracle minimax-cn-coding-plan/MiniMax-M2.7 high
explore minimax/MiniMax-M2.5-MLX-8bit medium
multimodal-looker minimax/MiniMax-M2.5-MLX-8bit medium
prometheus minimax-cn-coding-plan/MiniMax-M2.7 high
metis minimax/MiniMax-M2.5-MLX-8bit high
momus minimax/MiniMax-M2.5-MLX-8bit xhigh
atlas minimax/MiniMax-M2.5-MLX-8bit medium
sisyphus-junior minimax/MiniMax-M2.5-MLX-8bit medium
librarian minimax/MiniMax-M2.5-MLX-8bit medium
Categories 模型
Category Model Variant
visual-engineering minimax/MiniMax-M2.5-MLX-8bit high
ultrabrain minimax/MiniMax-M2.5-MLX-8bit xhigh
deep minimax/MiniMax-M2.5-MLX-8bit medium
quick minimax/MiniMax-M2.5-MLX-8bit (default)
unspecified-low minimax/MiniMax-M2.5-MLX-8bit medium
unspecified-high minimax/MiniMax-M2.5-MLX-8bit medium
writing minimax/MiniMax-M2.5-MLX-8bit medium

artistry minimax/MiniMax-M2.5-MLX-8bit xhigh

总结

  • 主力模型: minimax/MiniMax-M2.5-MLX-8bit — 大部分 agent/category 使用
  • 高级模型: minimax-cn-coding-plan/MiniMax-M2.7 — 仅 oracle 和 prometheus 使用
  • Variant 级别: default < medium < high < xhigh (最高)

最佳实践

在软件开发领域,我们一般都会遵守设计先行的原则。没有设计就蒙头进行开发,是非常莽撞且极具风险的行为。一般来说,开发阶段我们会经历「设计 -> 开发 -> 代码审查-> **测试」**这四个步骤,那这四个步骤对应到 oh-my-opencode 中:

  • **Prometheus-设计:**站在产品或者架构师的角度,通过多轮对话的形式把你的模糊需求转为详细的设计文档。
  • **Sisyphus – 开发,或者在 Prometheus 设计之后输入 /start-work 启动 Atlas:**在指令中增加 ultrawork (或简写为 ulw),可以激活 Agent 的最大强度模式,它会自动启动并行代理、后台任务、深度探索等功能,直到任务完成。
  • **Oracle – 审查:**这一步需要手动通过 @oracle 唤起 Oracle Agent,让它 review 刚才的改动,看看产物是否符合预期以及是否带来了新的问题。
  • 测试:如果你的项目中已经有测试基础设施,那在设计阶段,Prometheus 会询问你是否开启 TDD,建议开启,可以大大提高你的项目功能稳定性。如果没有,你可以在指令中加入需要测试任务的要求。

这种 Plan -> TODO 的模式,是目前比较常用且高效的开发方式。接下来三金会通过一个 demo 来进行演示。

首先我们创建一个新目录并在该目录中启动 OpenCode;Agent 切换到 Prometheus 上,输入:我想要做一个五子棋的游戏,你帮我出一个完整的设计;如下图,Prometheus 会通过对话的方式跟我们确认细节。包括支持的平台、功能、技术展、UI、难度等等;

确认好需求之后,会调用 Metis 检查计划是否有遗漏的地方。这个耗时会比较长,但确实有用;
待 AI 产出设计文档之后,如果你不放心该设计,还可以进行高精度审查;
审查通过以后,我们就可以通过提示运行 /start-work 开始 AI Coding 了;
在开发过程中,AI 还会自动调用 Playwright MCP 来进行调试,非常地 nice~,就是这个过程会有些长(对于从0到1的项目而言)

DeepSeek模型推理部署考虑所需显存的大小,主要考虑模型加载显存和推理过程显存,考虑因素包括模型参数量、模型精度、并发路数、输入输出长度等。

一、模型加载显存计算

DeepSeek R1各版本模型参数大小:

模型版本参数量特点
DeepSeek-R1-Distill-Qwen-1.5B1.5B轻量级模型,参数量少,模型规模小
DeepSeek-R1-Distill-Qwen-7B7B平衡型模型,性能较好,硬件需求适中
DeepSeek-R1-Distill-Llama-8B8B性能略强于7B模型,适合更高精度需求
DeepSeek-R1-Distill-Qwen-14B14B擅长复杂的任务,如数学推理、代码生成
DeepSeek-R1-Distill-Qwen-32B32B性能强大,适合高精度任务
DeepSeek-R1-Distill-Llama-70B70B适合大规模计算和高复杂任务
DeepSeek-R1-671B(满血版)671B超大规模模型,性能卓越,推理速度快

模型参数常见精度有FP32、FP16、FP8或INT8,以B(billion)为单位,代表十亿:

精度精度系数(1参数Bytes数)1B参数内存大小
FP3244GB
FP1622GB
INT8/FP811GB
INT40.50.5GB

因而:加载DeepSeek R1 671B FP8需要671G显存。

二、推理过程显存估算

推理过程显存 = (KV Cache + 激活中间值)x并发数

KV Cache显存计算:

MoE 层和非 MoE 层的 KV cache 计算公式不一样:

非MoE层,KV Cache 的计算公式为:

=2(key\value矩阵)×Batch Size×Sequence Length×Hidden Size×精度×层数

MoE层:

=2×Batch Size×Sequence Length×激活专家×压缩维度×精度×层数

激活中间值

激活值存储Transformer计算过程中中间结果,用于反向传播(训练时)或前向计算(推理时)。主要包括 Self-Attention 计算中间变量、前馈网络(FFN)计算结果等。

激活中间值显存计算:

MoE层和非MoE层的KV cache计算公式不一样:

非MoE:

=Batch Size×Sequence Length×Hidden Size×精度×层数

MoE层:

=Batch Size×Sequence Length×激活专家×压缩维度×精度×层数

三、DeepSeek V3 671B FP8部署为例:

模型网络总共 61 层(MoE层58,非MoE层3)

Sequence Length = (2048 + 2048)

Hidden Size= 7168

激活专家数量= 8

压缩维度= 512

假设batch size=1,显存需求:

非MOE层:(2+1)×1×(2048+2048)×8×512×3

+

MOE层: (2+1)×1×(2048+2048)×7168×58

= 4.9G

DeepSeek-V3 671B 推理部署,128并发显存估算= 671 + 4.9×128 = 1051G。

以上是主要部分的估算过程,其他条件是做理想假设(比如假设模型推理的上下文长度对KV Cache的显存占用影响不大),最准确的显存需求以实测为主。

附录:DeepSeek在NVIDIA H20上推理部署的性能测试数据

DeepSeek H20 GPU实测数据

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注