mihneaptu/opencode-fusion
GitHub: mihneaptu/opencode-fusion
为 opencode 实现多模型分工协作框架,通过权限层强制主 agent 只规划不编辑、由廉价助手执行修改,从而降低成本并附带跨厂商代码审查。
Stars: 112 | Forks: 7
# opencode-fusion
[](https://opensource.org/licenses/MIT)
一个为 [opencode](https://opencode.ai) 设计的极简、可用的多模型团队:一个负责规划和审查但**无法编辑文件**的**主 agent**,将所有更改委托给一个更便宜、更快的**助手**。灵感来自 Cognition 的 [Devin Fusion "助手"模式](https://cognition.com/blog/devin-fusion)。
主 agent 的文件编辑权限在机制上被严格拒绝。它更改文件的唯一方式是将规范说明交给助手。这使得尖端智能专注于重要的决策(规划、对歧义的解释、审查),而由廉价模型执行机械化的工作。Cognition 报告称,在他们自己的 FrontierCode 基准测试中,该模式在保持顶尖质量的同时,成本降低了约 **35%**;在 2026 年 7 月的后续测试中,由 Fable 5 主导的配置成本比**纯 Fable 5 低 54%**,且质量几乎一致:尽管 Fable 的每 token 价格高出 2 倍,但其绝对美元成本低于由 Opus 4.8 主导的配置。
这对主力组合由只读助手(**explore**、**research**)和可选的专家(**design**、**reviewer**、**vision**)支持,每个角色都可以使用你选择的模型。请参阅[完整团队](#how-it-works)。
[快速开始](#quick-start) • [工作原理](#how-it-works) • [设置](#setup) • [自定义](#customize) • [常见问题](#faq) • [故障排除](#troubleshooting)
## 演示
https://github.com/user-attachments/assets/6d9e96e2-654a-4bc4-82af-3c3f1a8bde91
38秒内的一个完整委托周期:主 agent 进行规划,将规范说明交给助手,审查返回的 diff,并验证结果,而无需亲自触碰任何文件。
## 快速开始
全局安装设置技能,然后让 opencode 以对话方式完成所有配置:
```
npx skills add mihneaptu/opencode-fusion --skill fusion-setup -g -a opencode -y
```
```
set up fusion
```
安装程序需要 **Node 20.12 或更高版本**。在较旧的 Node(包括 Ubuntu 的 apt 默认版本)上,它会因 `styleText` 错误而崩溃;[故障排除](#troubleshooting) 提供了三种解决方法。该技能会引导你为每个角色选择模型,编写全局配置,安装 agent 提示词,并告诉你何时需要重启。如果你使用的是订阅服务(OpenCode Go/Zen、ChatGPT 或 GitHub Copilot)?只需说出名称,该技能就会从预制的[配置文件](#subscription-profiles)开始,而无需逐一询问角色。手动设置和 provider 示例位于[设置](#setup)中。
## 为什么有效
摘自 [Cognition 的博客文章](https://cognition.com/blog/devin-fusion):
本仓库将其转化为一个硬性约束:主 agent 的 edit、search 和自由形式的 bash 工具在权限层被拒绝,因此委托给助手是它更改文件的唯一途径。这种分离带来了两个好处:
**更低的成本。** 实现细节占据了会话的大部分 token。较便宜的助手以几乎同等的质量处理这些工作,而昂贵的主模型仅将其 token 花费在判断上:规划、规范说明、审查。主 agent 的提示词强制执行了这一原则:输出判断而非篇幅,保持上下文精简,推理一次然后交出。Cognition 的[后续研究](https://cognition.com/blog/making-fable-cheaper-than-opus) 证实了这一点:在 81% 由 Fable 主导的 Fusion 运行中,主模型没有进行过一次代码编辑。这种行为正是本仓库通过机制强制执行的,而非仅仅作为建议。
**免费的跨厂商审查。** 当主 agent 和助手属于不同的模型家族(例如 Opus 审查 Grok)时,每个 diff 在落地前都会获得一个独立的跨家族二次阅读。来自同一家族的模型存在共同的盲区;来自不同血统的审查者能够发现同家族审查遗漏的问题。你只需选择来自不同供应商的主 agent 和助手即可获得这种优势。
## 工作原理

该图展示了一个委托周期:主 agent 委托探索任务,根据返回的结果进行规划,向助手提交规范说明,审查返回的 diff,循环直到通过,然后交付结果。
| Agent | 角色 | 配置键 | 必需 | 建议模型 (2026) |
|-------|------|------------|----------|------------------------|
| `build` | 主力:规划、委托、审查 | `agent.build.model` | 核心 | `claude-opus-5` |
| `plan` | 计划模式:与 build 相同的大脑,只规划不执行 | `agent/plan.md` (文件) | 核心 | 复用主模型 |
| `sidekick` | 执行编辑和命令 | `agent.sidekick.model` | 核心 | `grok-4.5` |
| `explore` | 快速只读探索(opencode 内置 agent;无提示词文件) | `agent.explore.model` | 核心 | `grok-4.5` |
| `research` | 只读外部研究(网络、文档) | `agent.research.model` | 可选 | `claude-sonnet-5` |
| `design` | 前端/UI 实现 | `agent.design.model` | 可选 | `kimi-k3` |
| `reviewer` | 在实现前审查计划;在提交前审计 diff | `agent.reviewer.model` | 可选 | `gpt-5.6-sol` |
| `vision` | 转录主模型无法查看的图像 | `agent.vision.model` | 可选 | `gemini-3.6-flash` |
模型更新换代很快。请将这些视为 2026 年的起点,而非硬性要求。你可以使用任何喜欢的 provider;在配置中,每个模型都写为 `provider/model-id`(例如 `openai/gpt-5.6-sol`),并且助手应保持比主 agent 更便宜、更快速。上述组合有意跨越了多个供应商,因此主 agent 对每个助手 diff 的审查都是跨厂商的。如果订阅涵盖了你的模型,[配置文件](#subscription-profiles) 会为你自动填充此表。
## 强制执行与建议
该模式的保证存在于两个不同的层面,准确区分它们可以回答大多数“如果模型忽略了指令怎么办?”的问题。
**强制执行:权限层。** opencode 会在每次工具调用时检查这些规则,无论模型读取了什么、记住了什么或打算做什么:
- 主 agent 的 `edit`、`grep`、`glob` 和 `list` 被拒绝。被拒绝的工具会从模型的工具 schema 中完全移除;它根本没有 edit 工具可以拒绝使用。
- 它的 bash 默认被拒绝,仅允许简短的验证和 git 白名单,因此写入文件的命令会被阻止。`git commit` 和 `git push` 还需要针对每个命令进行用户批准;常见的强制/镜像/删除/清理形式的推送会被后续规则拒绝。
- 对 sidekick 和 design agent 直接拒绝调用 `git commit` 和 `git push` 以及常见的 Git 包装器形式,使得“先审查后提交”成为常态的强制执行路径。
- 委托受限于明确的 `task` 白名单:主 agent 只能联系其指定的专家,而 sidekick 只能生成只读搜索器。
如果主 agent “不进行委托”,结果将是可见的不作为:磁盘上的内容不会发生任何改变。其失败模式绝不会是静默绕过。
**建议:提示词层。** 规范说明的精确度、diff 审查的严谨性、成本纪律、并行化和技能使用都是 agent 提示词中的指令。opencode 根据模型自身的判断加载技能(没有什么能强制 agent 阅读或应用技能),这也正是为什么这里的任何保证都不依赖于它们的原因;本仓库中的技能仅仅是安装程序。如果模型在这一层敷衍了事,代价是质量下降或 token 浪费,绝不会导致未经授权的编辑。
**不保证:威胁模型。** 权限层限制了每个 agent 可以调用的工具。它不是一个沙盒,明确它不保护的内容是有必要的:
- `.env` 中针对执行者的拒绝规则阻止的是常见的意外读取(例如 `cat .env` 导致密钥出现在记录中),而不是蓄意读取。拥有广泛 bash 权限的 agent 有许多等效的方法来读取文件或进程环境,因此请将这些规则视为防止意外泄漏的手段,而非密钥隔离。`{env:VAR}` 配置语法将密钥排除在明文配置和聊天之外;但它并不能向运行 agent 的环境隐藏它们。
- Git 命令规则匹配的是命令文本,属于纵深防御,而非 shell 沙盒:当执行者拥有广泛的 bash 权限时,包装器、备用可执行文件或混淆手段都可以绕过有限的模式列表。它们保护的是防止常见的意外提交和破坏性推送,而不是防范恶意的进程。编辑文件是 sidekick 的工作,而发现错误编辑正是主 agent 的 diff 审查(以及可选的 reviewer)的职责所在。
- design agent 的路径感知 opencode 工具被限制在工作区内(`external_directory: deny`),但通过广泛的 bash 启动的进程不受该规则的操作系统级沙盒限制。sidekick 对项目外的路径保留 opencode 默认的 `ask`(询问)权限,因为设置和重新配置需要合理地写入全局配置。请注意,`--auto` 模式会自动批准 `ask` 规则,因此如果执行者绝对不能离开仓库,请同时使用外部沙盒。
**可审计:验证而不是信任。** 可选的 [`fusion-audit` 插件](#slash-commands-and-optional-plugins) 会记录委托树,并且 opencode 的会话数据库会记录每个 agent 的实际工具调用(`opencode db path` 会打印其位置,通常为 `~/.local/share/opencode/opencode.db`)。“它真的委托了吗?”是可核查的真相,而不是凭感觉。
## 设置
Fusion 完全存在于你的**全局** opencode 配置中,路径为 `~/.config/opencode/`(Windows: `%USERPROFILE%\.config\opencode\`)。没有构建步骤,也不需要将任何内容克隆到你的项目中。
### 推荐:让 opencode 进行设置
本仓库附带了一个 `fusion-setup` 技能,可以以对话方式完成所有配置。全局安装它(需要 Node 20.12+):
```
npx skills add mihneaptu/opencode-fusion --skill fusion-setup -g -a opencode -y
```
或者将本仓库 `.opencode/skills/` 中的 `fusion-setup` 文件夹复制到 `~/.config/opencode/skills/` 中。技能是按需发现的;无需重启即可加载。然后输入:
```
set up fusion
```
它会询问你希望为每个角色使用哪个模型和 provider,写入 `~/.config/opencode/opencode.json`,将 agent 提示词安装到 `~/.config/opencode/agent/` 下,并提示你重启。机械步骤(带时间戳的备份、配置合并、原子写入、文件复制、验证和撤销)通过随该技能捆绑的一个小型确定性脚本运行,因此设置的敏感部分不依赖于模型的遵从性。以后要更改模型,请说“reconfigure fusion”或直接编辑配置(参见[自定义](#customize));“undo fusion”会恢复记录的备份,并仅删除已安装的内容。
### 订阅配置文件
如果你的模型来自订阅,可以跳过逐个角色的访谈:在设置过程中说明订阅名称(或运行 `/fusion-setup opencode-go`),该技能将应用一个捆绑的配置文件:这是一个预制的角色到模型的映射,安装程序会像对待任何其他配置片段一样将其合并。直接运行:`node /scripts/install.js apply --profile --extras commands,plugin`。
| 配置文件 | 订阅服务 | 主力 / 助手 | 核心角色之外 |
|---------|--------------|-----------------|-----------------------|
| `opencode-go` | [OpenCode Go](https://opencode.ai/go) | Kimi K3 / DeepSeek V4 Flash | research, design, reviewer |
| `opencode-zen` | [OpenCode Zen](https://opencode.ai/docs/zen/) 按量付费 | Claude Opus 5 / GPT-5.6 Luna | research, design, reviewer |
| `opencode-zen-free` | OpenCode Zen 免费层级模型 | Big Pickle / MiMo V2.5 Free | vision |
| `chatgpt` | ChatGPT Plus 或 Pro | GPT-5.6 Sol / GPT-5.6 Luna | reviewer |
| `github-copilot` | GitHub Copilot | Claude Sonnet 5 / GPT-5.6 Luna | research, reviewer |
身份验证保持在带外:通过 `opencode auth login`(或在 opencode 中使用 `/connect`)连接一次 provider 即可。配置文件不包含任何密钥、适配器或端点(opencode 原生支持这些 provider),并且技能绝不会在聊天中索要密钥。要调整选择,请保留该配置文件并添加一个小的覆盖片段(`--profile --config `;发生冲突时以你的片段为准)。
五点说明。`opencode-zen-free` 包含 `vision` 角色,因为其主模型无法读取图像;其他配置文件使用的模型可以直接读取图像。`opencode-zen-free` 运行在免费时期的模型上(Big Pickle 是一个隐蔽模型)。OpenCode 的政策允许在模型免费时将提示用于训练,因此请不要在此配置文件上处理敏感代码。单一供应商的 `chatgpt` 配置文件将所有角色保持在同一个供应商——其 reviewer 运行的是与主 agent 不同的模型(GPT-5.6 Terra),但如果用户有第二个 provider,仍然可以通过跨供应商覆盖 reviewer 来获得更强的检查;`github-copilot` 为了控制点数消耗,默认使用 Claude Sonnet 5 作为主力;如果你想获得最高质量并能接受这种消耗速度,可以将 `agent.build.model` 覆盖为 `github-copilot/claude-opus-5`。`opencode-go` 以 Kimi K3 为主,这是该阵容中最严密的模型:Go 按美元计量,因此 K3 在额度中的份额折合大约为每 5 小时 110 次请求,而 GLM 5.2 为 880 次——如果你达到了限制,可以将 `agent.build.model` 指向 `opencode-go/glm-5.2`。没有 Claude Pro/Max 的 provider 配置文件:Claude 订阅的登录信息无法放入 `opencode.json` 或作为 `agent.build.model` 公开。下面的可选桥接插件可以请求官方的 Claude Code CLI 进行受限的计划审查。订阅阵容会轮换;`npm run check-profiles` 会根据 [models.dev](https://models.dev) 验证每个提供的 ID,并且 CI 会在每次推送时运行此检查。
### 可选的 Claude Pro/Max 计划审查
`claude` 安装程序附加组件添加了一个小型 OpenCode 插件,可调用官方的 Claude Code CLI。它为 Fusion 的 build 和 plan agent 提供了两个自定义工具:`fusion_claude_status` 和 `fusion_claude_review`。Claude 仅接收 Fusion 发送的自包含计划数据包。它无法检查工作区、使用工具、编辑文件、继续会话或成为主模型。
1. [安装 Claude Code](https://code.claude.com/docs/en/setup) 并使用 Pro 或 Max 账户自行运行 `claude auth login`。在 Windows 上,请使用原生构建版本(安装程序脚本或 `claude install`):该桥接插件会在没有 shell 的情况下启动 `claude`,而 npm 的 `claude.cmd` 垫片不支持这种方式。
2. 使用你常用的 OpenCode 配置文件或配置运行 Fusion 安装程序,并添加该附加组件:`--extras commands,plugin,claude`。
3. 完全退出并重启 OpenCode。要求 Fusion 检查 `fusion_claude_status`,或者说:“在实施之前让 Claude 审查一下计划。”
该插件绝不会读取或复制 Claude 存储的 OAuth token。在每次审查之前,它会检查是否存在第一方 Pro/Max 登录,从 Claude 进程中移除 API 密钥和备用 provider 路由,默认在高努力程度下使用 `claude-opus-5`(审查工具接受可选的完整 `claude-*` 模型 ID 以及每次调用指定 low/medium/high/xhigh/max 的努力程度),使用 [Claude Code 打印模式](https://code.claude.com/docs/en/cli-usage),禁用工具和自定义项,并关闭会话持久性。审查从中立的临时目录而不是你的工作区运行,并且这些工具在运行时会拒绝除 build 和 plan agent 之外的任何调用者,因此即使是手动复制的没有安装程序的全局拒绝权限的插件,也无法为其他 agent 服务。OpenCode 全局拒绝这些工具,并仅通过[自定义工具权限](https://opencode.ai/docs/agents/)将它们授予 build 和 plan agent。
这仍然是一个可选的第三方集成。[Anthropic 表示](https://support.claude.com/en/articles/13189465-log-in-to-your-claude-account) 订阅使用是为其原生应用程序(包括 Claude Code)设计的,并且某些第三方工具访问可能由其自行决定允许或计入使用点数。该桥接插件不会伪造身份或将 OAuth 转换为 API 凭据,但这并不保证订阅访问或计费行为永远不会改变。
/",
"provider": {
"": {}
},
"agent": {
"build": { "model": "/" },
"explore": { "model": "/" },
"sidekick": { "model": "/" }
}
}
```
这些专家是可选的,可按需添加。要添加一个专家,请在 `agent` 块中与 `explore`/`sidekick` 一起为其添加一个 model 条目,例如 `"reviewer": { "model": "/" }`,并安装其提示词文件。它们的提示词和权限位于技能包中:`.opencode/skills/fusion-setup/agent/` 包含 `research.md`、`design.md`、`reviewer.md` 和 `vision.md`。仅当你的主模型无法读取图像时才添加 `vision`。计划模式使用 `agent/plan.md` 并复用主模型。`explore` 是唯一没有提示词文件的角色:它是 opencode 内置的只读子 agent,因此它在 JSON 中获得一个 model 条目,仅此而已;本仓库中刻意没有提供 `agent/explore.md`。
然后安装 agent 文件。opencode 会自动将 `~/.config/opencode/agent/` 中的每个 markdown 文件作为 agent 定义加载。Frontmatter 包含了角色的模式和权限(这是在机制上强制执行拒绝编辑的地方),而正文是其提示词:
```
mkdir -p ~/.config/opencode/agent
cp .opencode/skills/fusion-setup/agent/{build,plan,sidekick}.md ~/.config/opencode/agent/
```
模型引用始终为 `provider-id/model-id`。如果模型使用了 opencode 尚不识别的 provider,请为其添加一个 `provider` 块(参见 `fusion-setup` 技能中的 OpenAI 兼容模板)。
## 验证其有效性
打开一个带有一些 lint 错误的项目,并询问:
```
fix the lint errors in this project
```
你应该会看到主 agent 委托探索任务,接收调查结果,制定计划,然后通过 `task` 工具将执行委托给 sidekick。sidekick 进行编辑,主 agent 在报告之前会自行运行 `npm run lint` 来验证结果。
## 自定义
### 替换模型
所有 agent 模型都集中在一个地方:`~/.config/opencode/opencode.json` 的 `agent` 下,每个 agent 对应一个 `model` 值(键和建议的模型位于[上表](#how-it-works)中)。
更改该值,如果模型使用了新的 provider 则添加一个 `provider` 块,然后重启 opencode。要设置持久的主模型默认值,还需要更新顶层的 `model` 字段。只要可能,sidekick 应保持比主 agent 更便宜和更快速。
手动编辑此文件完全没有问题,也不会丢失任何内容,但安装程序会记录其写入内容的哈希值,因此下次重新应用时会拒绝一次以使不匹配变得可见。使用 `--adopt-config` 重新运行它,以接受你编辑后的文件作为新基准;配置片段仍然会合并到你当前的文件中而不是替换它,并且 `undo` 仍然会恢复到真正的 Fusion 安装前状态。改用“reconfigure fusion”则可以保持清单的准确性,而无需额外步骤。
### 调整 bash 白名单
主 agent 的 bash 被列入验证和 git 命令的白名单(`npm run lint`、`npm test`、`git diff`、`git status`、`git log`、`git show`、`git add`);`git commit` 和 `git push` 会提示逐个命令批准,并且强制/镜像/删除引用的推送被拒绝。编辑已安装的 `~/.config/opencode/agent/build.md`,在 `permission.bash` 部分添加或删除允许的命令。将 `"*": "deny"` 保持在首位,以便未列出的命令默认被阻止,并将特定的推送拒绝项保留在 `"git push*"` *之后*;opencode 通过最后匹配项优先的原则来解决重叠模式。请注意,白名单会单独匹配每个命令:不要使用 `&&`、`||`、`;` 或 `|` 链接命令,因为该命令链不会匹配任何单个模式,从而会被阻止。
/"`(顶层):opencode 在小型模型上运行后台任务,如会话标题生成;如果你不设置此项,它可能会回退到远程默认设置。将其固定为你自己的廉价本地模型之一,以将所有内容保留在你的 provider 上。
- `"enabled_providers": ["..."]`(顶层):将 opencode 加载的 provider 列入白名单,这样其他地方的多余凭证就无法将模型添加到选择器中。
- `"compaction": { "prune": true }`(顶层):在压缩时丢弃过期的工具输出,从而减少在繁重委托流程中主 agent 的 token 成本。
- `"limit": { "context": , "output": }`(在自定义模型块内):允许 opencode 为未在 models.dev 上的模型(例如本地网关)跟踪剩余上下文。使用模型的真实窗口大小;不要猜测。
- Sidekick bash 黑名单:sidekick 拥有广泛的 `bash` 权限,但其提示词 frontmatter 会拒绝直接使用 `git commit`/`git push` 以及常见的包装器形式(提交是主 agent 在审查后的工作),阻止常见的 `.env` 读取操作,并在执行 `git reset --hard`、`git clean` 和 `rm -rf`(及其 PowerShell/cmd 等效命令:`Remove-Item -Recurse`/`-Force`、`rd /s`、`del /s`)之前进行询问。这些是纵深防御的命令守卫,而不是进程隔离。
## 卸载
输入 `undo fusion`,或直接运行捆绑的安装程序:
```
node /scripts/install.js undo
```
它会将 `opencode.json` 恢复到安装前的确切字节,仅删除 Fusion 创建的文件,恢复其替换过的任何文件,并保留所有备份。如果你在此之后手动编辑了已安装的提示词或配置,它会拒绝执行并指出冲突,而不是覆盖你的工作。完成后重启 opencode。
撤销是全有或全无的——没有可以在某个会话中暂停 Fusion 的开关。而且由于 `build` 和 `plan` 替换了 opencode 内置的主要角色,开箱即用时也没有不受限制的主要角色可以作为后备。
### 逃生舱口
如果你想要一个,请创建 `~/.config/opencode/agent/normal.md`:
```
---
description: Unrestricted primary - plain opencode, no Fusion permissions
mode: primary
---
You are a standard opencode agent with no delegation requirements.
```
重启一次,然后 `Tab` 键即可在会话中循环切换主要 agent。省略 `model` 键,它将遵循你的顶层默认设置。安装程序从不管理此文件,因此 `undo` 和重新应用都不会影响它。
这并不会削弱这种分离:切换主要角色是你按键执行的快捷方式,而不是主 agent 可以调用的工具。有两个注意事项:
- **完全没有护栏**,而不仅仅是不能委托。它继承了 opencode 的默认设置,因此 sidekick 会询问的破坏性 shell 命令将不加提示地运行。
- **对话记录在主要 agent 之间共享。** 切换后,新的 agent 会将之前的轮次作为自己的轮次来读取——预计 `build` 会为逃生舱口所做的直接编辑而道歉。如果这很重要,请启动一个全新的会话。
## 局限性
- **无动态会话中途路由。** Devin Fusion 的第二种技术,即在上下文压缩期间中途替换活动模型,需要 Devin 的封闭产品界面,在 opencode 中无法实现。本仓库仅实现了 sidekick 模式;模型分配在启动时按角色。这是一个明确的非目标,而不是缺失的功能。
- **配置在启动时加载。** opencode 在启动时读取一次配置。对 `opencode.json` 或 agent 提示词的任何更改都需要完全重启才能生效。
- **循环保护分为两层。** `subagent_depth: 2` 将 Fusion 限制在所需的主力 -> 执行者 -> 只读助手链条内。`task` 权限图独立控制每个角色可以启动哪些指定的 agent,因此允许第二层级并不会暴露任意的子 agent。
- **面向 opencode 1.x。** 这些文件是基于 opencode 稳定的 1.x 配置 schema 编写的(在 1.18.x 上验证过)。opencode v2 测试版(`opencode2`)使用不同的 schema(复数的 `agents`、基于数组的 `permissions`),本仓库暂不支持。
## 常见问题
## 故障排除
## 斜杠命令和可选插件
## 文件
` 应用的指定逐角色模型预设 |
| `commands/` | 可选的 `/fusion-setup`(启动设置)和 `/fusion-status`(健康检查)斜杠命令 |
| `plugins/fusion-audit.js` | 可选的只读插件,记录委托树和每个会话中每个 agent 的 token 使用情况以供审计 |
| `plugins/fusion-claude.js` | 可选的 Claude Code Pro/Max 桥接插件,用于无状态、只读的计划审查 |
| `scripts/install.js` | 技能驱动的确定性安装程序:备份、合并、原子写入、清单、撤销 |
本仓库的其余部分为其提供支持:
| 文件 | 用途 |
|------|---------|
| `scripts/check-profiles.js` | 实时检查配置文件的模型 ID 是否仍存在于 models.dev (`npm run check-profiles`) |
| `test/integration/` | 实时强制执行测试:针对虚假 provider 的真实 opencode 二进制文件 (`npm run test:integration`) |
| `opencode.json` | 参考配置(被 gitignore):Opus 主力,Grok 4.5 助手与 explore |
| `flow-diagram.png` | 架构图(主 agent 与 Sidekick 泳道图) |
| `LICENSE` | MIT 许可证 |
## 使用 opencode-fusion 构建
本仓库是使用 Fusion 模式自身进行配置的。主 agent 规划了结构,审查了每一次更改,并根据真实的命令输出进行了验证。Sidekick 编写了文件并了命令。每一次更改都经过了上述流程。
## 免责声明
本项目未隶属于、未受认可,也不是由 opencode 团队构建的。[opencode](https://opencode.ai) 是 [Anomaly](https://anoma.ly) 的一个独立项目。本仓库提供了可与 opencode 配合使用的配置,但并不是其组成部分。
## 致谢
灵感来自 [Cognition](https://cognition.com) 的 [Devin Fusion](https://cognition.com/blog/devin-fusion):“sidekick(助手)”的框架,“主 agent 应采取最少行动”的原则,以及本 README 中引用的基准测试数据都是他们的,来源于发布文章以及 2026 年 7 月的后续文章 [“让 Fable 比 Opus 更便宜”](
手动设置(手动配置 JSON)
自己编写 `~/.config/opencode/opencode.json`。选择你自己的模型;结构才是最重要的。JSON 只是为每个角色分配了模型。Fusion 的机械核心(build agent 的 `edit: deny` 和 bash 白名单)存在于你接下来安装的 agent 文件中,并且绝不能放宽。 ``` { "$schema": "https://opencode.ai/config.json", "subagent_depth": 2, "model": "Provider 示例:通过 progrok 将 Grok 作为助手
任何 provider 都可以使用,但如果你想使用 xAI 的 Grok Composer 作为快速助手模型,[progrok](https://github.com/lidge-jun/progrok) 可以将 SuperGrok OAuth 会话转换为本地兼容 OpenAI 的端点: ``` npm install -g progrok progrok login # browser OAuth with your xAI account progrok proxy # leave this running in a terminal ``` 该代理服务于 `http://127.0.0.1:18645/v1`。将一个 provider 块指向该 baseURL,并使用任意占位符 apiKey;progrok 会在转发给 xAI 之前注入你真实的 OAuth token。深度要求及可选的强化措施
当 sidekick 将只读查找委托给 explore 或 research 时,需要(在顶层设置)`"subagent_depth": 2`。OpenCode 1.18.2+ 默认为 `1`,这允许主 agent 启动 sidekick,但会阻止该嵌套的辅助调用。Fusion 安装程序会将其最小值设为 `2`,并保留更大的现有值。 剩余的已记录键使本地 Fusion 设置更便宜、更隐私且更确定性。它们是可选的: - `"small_model": "当助手无法满足规范说明时会发生什么?
主 agent 的提示词包含明确的升级阶梯,因此重试循环总是会终止: 1. **第一次失败:** 重新委托,并给出指出具体问题的反馈。 2. **第二次失败:** 停止描述,开始口述。主 agent 自己编写确切的补丁(文件、行范围、逐字代码)并将其交给助手应用。应用逐字补丁不需要任何判断,因此这就结束了能力问题的争议:sidekick 纯粹变成了执行工具。你会损失那一次任务的成本节省,但你不会陷入死锁。 3. **口述的补丁仍然未通过验证:** 说明计划错了,而不是 sidekick 的错,主 agent 会修改计划。仅当验证由于代码之外的原因(环境损坏、测试不稳定)而失败时,它才会报告阻碍,并附上真实的命令输出。 机械阻断在于主 agent 的*工具*,而不是其规范说明的内容。口述确切的 diff 始终在规则范围内;提示词使其成为一个明确的步骤,而不是一种涌现的发现。 该阶梯假设 sidekick *会做出响应*。如果其 provider 宕机或配额用尽,任何阶梯都无济于事:主 agent 完全没有通往磁盘的路径,结果只能是报告阻碍。重新指向 `agent.sidekick.model` 并重启,或者使用[逃生舱口](#escape-hatch) 以在该会话中继续工作。如果 agent 忽略提示词,或者从不加载技能怎么办?
你损失的是质量,而不是保证;请参阅[强制执行与建议](#enforced-vs-advised)。委托并不是主 agent 可以选择的行为:它的编辑和搜索工具在权限层已从其工具 schema 中移除,因此将工作交给 sidekick 是唯一存在的途径。在任何框架中,技能都是建议性的(opencode 根据模型的判断加载它们),这就是为什么没有任何核心功能依赖于它们的原因。而且你可以验证而不是盲目信任:`fusion-audit` 插件和 opencode 的会话数据库记录了每个 agent 实际做了什么。这与 superpowers 或其他编排方法有什么不同?
处于不同的层。像 [superpowers](https://github.com/obra/superpowers) 这样的技能库教会 agent *如何工作*:作为技能和钩子交付的过程知识(TDD、调试、规划)。该指导很有价值,但钩子注入的是文本,模型仍然可以不遵从。Fusion 配置的是 *agent 能做什么*:在权限层移除功能,因此即使模型表现不佳,该模式也能成立。第二个区别是该模式的核心:为了节约成本而进行的逐角色模型路由(昂贵的判断,廉价的执行),其副作用是实现了跨厂商审查,这是技能库做不到的。与 LangGraph 或 CrewAI 等代码级框架相比:这里没有框架,也没有代码;这是在正常交互会话上的配置。这些方法可以组合使用:superpowers 支持 opencode,因此其技能可以在 Fusion 设置中运行。常见问题
如果你安装了可选命令,请首先运行 `/fusion-status`;它会一次性检查通常的可疑点:正在运行的会话中的实时强制执行、磁盘上的配置以及已安装的 agent 文件。 ### `npx skills add ...` 因 `styleText` SyntaxError 崩溃 ``` SyntaxError: The requested module 'node:util' does not provide an export named 'styleText' ``` 你的 Node 版本对于安装程序来说太旧了。该安装命令运行 Vercel 的 [`skills`](https://github.com/vercel-labs/skills) CLI,并且自 `skills@1.5.16` 起,其捆绑包使用 `util.styleText`,该功能仅存在于 **Node 20.12+** 中,即使该软件包仍声明支持 Node 18([vercel-labs/skills#1672](https://github.com/vercel-labs/skills/issues/1672))。Node 18(Ubuntu 的 apt 默认版本,自 2025 年 4 月起已停止维护)在启动时因上述错误而崩溃。以下任一修复方法都有效: - **升级 Node**(推荐;反正 Node 18 已停止维护):通过 [nvm](https://github.com/nvm-sh/nvm) 或 [NodeSource](https://github.com/nodesource/distributions) 安装 Node 22,然后重新运行该命令。 - **固定到最后一个兼容的安装程序**:`npx skills@1.5.15 add mihneaptu/opencode-fusion --skill fusion-setup -g -a opencode -y`;1.5.15 是最后一个没有 `styleText` 导入的版本,并且它安装的技能是完全相同的。 - **完全跳过 npx**:克隆本仓库并将 `.opencode/skills/fusion-setup/` 复制到 `~/.config/opencode/skills/` 中;该技能本身只是普通的 markdown,没有 Node 依赖项。 ### 主 agent 直接编辑文件 配置未加载。完全退出并重启 opencode;它在启动时加载配置,而不是在会话中途。然后确认已安装的 `~/.config/opencode/agent/build.md` frontmatter 中是否设置了 `edit: deny`。 ### 未调用 Sidekick 检查 `~/.config/opencode/agent/build.md` 中 build agent 的 `permission.task` 图:它必须首先通过 `"*": "deny"` 广泛拒绝,然后允许 `"sidekick": allow`(以及其他指定的专家)。不要使用单纯的 `task: allow`,这会暴露每个子 agent,包括内置的 `general`。 ### 模型返回 404 或 400 模型 ID 可能错误或已更改。确认具体的 `provider-id/model-id` 是否与你的 provider 相符,以及 provider 块的 `baseURL`/`apiKey` 是否正确。如果密钥使用 `{env:VAR}` 替换,请检查该变量是否确实在 opencode 启动的环境中设置了;未设置的变量会静默变为空字符串。对于 progrok 的 Grok 模型,composer 编码模型是可调用的,但有意未在 `/v1/models` 中列出,因此那里缺少条目并不意味着 ID 错误。 ### bash 命令意外被阻止 首先检查该阻止是否符合预期:白名单之外的命令(如 `git ls-files` 之类的搜索、文件写入、`git checkout`)是*旨在*被拒绝的,并且 agent 会通过读取或委托来恢复;请参阅[验证其有效性](#verify-it-works)。 如果*已列入白名单的*命令被阻止,通常的原因是链接:白名单将整个命令与固定模式进行匹配,因此 `&&`、`||`、`;`、`|` 或包装在 `echo` 中都会破坏匹配并阻止该行。将每个允许的命令作为单独的调用运行。 ### 搜索报告现有内容为“零匹配” 搜索工具运行具有标准忽略规则的 ripgrep,因此委托的搜索会静默跳过任何与 `.gitignore` 匹配的内容。被 gitignore 的路径(本地测试固件、生成的代码)即使在文本完全正确的情况下也会产生肯定的“未找到匹配项”报告,主 agent 会将其作为事实转述。如果 agent 需要搜索被 gitignore 的目录,请添加一个将其列入白名单的根 `.ignore` 文件(例如 `!fixtures/`):ripgrep 读取 `.ignore` 的优先级高于 `.gitignore`,而 git 不会关注它。请注意,`git diff` 也有相同的盲点:对被 gitignore 的文件的更改从不会出现在其中,因此主 agent 通过直接读取文件来审查这些更改。四个可选组件
该技能附带了四个可选组件: - **`/fusion-setup` 命令** (`commands/fusion-setup.md`):一个可发现并启动设置流程的斜杠命令。运行 `/fusion-setup` 进行完整访谈,或传递参数如 `/fusion-setup reconfigure sidekick` 直接跳转到定向更改。将其安装到 `~/.config/opencode/commands/`。 - **`/fusion-status` 命令** (`commands/fusion-status.md`):一个健康检查,用于验证安装是否已安装、加载并强制执行:实时工具 schema(被拒绝的工具确实不在运行中的 agent 内)、磁盘上的配置、已安装的 agent 文件以及可选的 Claude 桥接。它只报告;不更改任何内容。将其安装到 `~/.config/opencode/commands/`。 - **`fusion-audit` 插件** (`plugins/fusion-audit.js`):通过 opencode 的记录器记录委托树(子 agent 生成和 edit/write/apply_patch/task 工具调用),并聚合每个会话中每个 agent 的 token 使用情况,因此你可以审计主 agent 是进行了委托而不是编辑,并查看每个会话的 token 去向:“Fusion 真的省钱了吗?”背后的原始数据。它仅用于观察:opencode 的工具钩子不暴露调用 agent,因此强制执行仍然由权限层负责;该插件仅使委托过程可见。将其安装到 `~/.config/opencode/plugins/`。 - **`fusion-claude` 插件** (`plugins/fusion-claude.js`):可选的 Claude Code Pro/Max 计划审查器。它公开了一个净化的状态检查工具和无状态的审查工具,仅调用官方的 `claude` CLI,并将 OAuth 凭据保留在 Claude Code 内部。使用 `claude` 附加组件安装它,而不是单独复制它,因为安装程序还会添加全局权限拒绝。在不包含 `claude` 附加组件的情况下重新运行安装程序会保留已安装的桥接插件;使用 `install.js undo` 将其删除。所有文件
Fusion 安装的所有内容都集中在一个地方,即位于 `.opencode/skills/fusion-setup/` 的技能包: | 文件(在技能包内) | 用途 | |------|---------| | `SKILL.md` | 技能运行的对话式设置流程 | | `agent/build.md` | 主 agent:拒绝 edit,拒绝 search,bash 白名单,允许 task,探索 + 并行化规则 | | `agent/plan.md` | 计划模式 agent:只读检查加上委托,无法执行或提交 | | `agent/sidekick.md` | Sidekick 提示词(在 `opencode.json` 中设置模型) | | `agent/research.md` | 可选研究专家:只读、网络 + 文档 | | `agent/design.md` | 可选设计专家:前端/UI,加载设计技能 | | `agent/reviewer.md` | 可选审查专家:审查计划和审计 diff,只读加上 lint/test | | `agent/vision.md` | 可选视觉专家:在主模型没有图像输入时转录图像 | | `profiles/` | 捆绑的订阅配置文件:通过 `install.js apply --profile标签:AI代理, AI编程助手, MITM代理, OpenCode, SOC Prime, 多智能体协作, 开发工具, 自定义脚本, 降本增效