内容
<div align="center">
# omux
**无人值守、并行、按需运行你的 CLI 编程代理。**
omux 是一个元代理,可以控制你选择的 CLI 编程代理 — Claude Code、Codex 或其他 — 通过 tmux。它可以启动多个实例,处理状态和确认,记住会话,并让你离开。
[](https://www.npmjs.com/package/@happenmass/omux)
[](./LICENSE)
[](https://nodejs.org)
[演示视频](#demo) · [工作原理](#工作原理) · [安装](#安装) · [常见问题](#常见问题)
</div>
---
## 问题
Claude Code 和 Codex 在编写代码方面非常出色。但在编写代码周围的部分,它们并不出色:
- 你不能离开。它们在每个破坏性操作时暂停,要求你确认,要求你在两个方法之间选择。
- 你一次只能运行一个任务。如果要一个代理在后端,另一个在前端? 你需要打开两个终端并同时监护它们。
- 它们不协调。完成任务、运行测试、提交 PR、在 Slack 上发布 — 这是你的工作,又是手动的。
- 它们不会在会话之间学习。每次运行都从头开始。
- 每个代理都看到每个工具。 一旦你安装了 6 个 MCP,每个代理 — 甚至是编写文档的代理 — 都需要支付系统提示的开销,并且存在工具名称冲突的风险。
我尝试使用 Anthropic SDK 和 bash 脚本解决这个问题。但它没有起作用。CLI 代理具有丰富的 TUI — 分步推理、交互式确认、实时进度 — 而包装 API 会抛弃所有这些。
所以我构建了 omux。
## 什么是 omux
omux 是一个聊天驱动的元代理,为你运行你选择的 CLI 编程代理。
你可以通过 `omux config` 配置你选择的工具:Claude Code、Codex 等 — 任何具有 tmux 友好型 CLI 的工具。**编排机制** 不关心哪个工具位于它们后面:MainAgent 对通用代理合同进行操作 — 生成、发送、确认、等待 — 由每个工具作为一个薄适配器实现(几百行代码)。
当你分配工作时,omux 在 tmux 窗格中启动一个或多个你配置的工具实例。它像人类一样读取这些窗格 — 识别加载器、确认提示、错误消息、完成标记。它发送按键。当一个窗格空闲时,它会评估结果并决定下一步。
**启用多个代理,MainAgent 会根据适应性进行路由。** 它看到你启用的所有适配器及其优势,然后将每个任务分配给最适合它的代理 — **Codex** 用于复杂的单点推理和深度调试,**Claude Code** 用于广泛的多文件编辑→测试→重新运行循环 — 并将差异交给**其他** 代理进行独立审查。你不需要为每个任务选择代理;你描述工作并让循环选择,始终在你启用的工具集内(它永远不会使用你未启用的代理)。角色不是硬编码的 — 任意代理都可以实现,任意代理都可以审查。
这就是整个想法。切换工具是配置更改。添加对新工具的支持是一个适配器文件。编排层永远不会改变。
这种分层设计的另一个好处:**你和 MainAgent 可以用一种语言交流,而编码代理可以用另一种语言获得简报。** omux 从头到尾都是区域感知的(聊天界面、MainAgent 回复、它的管理提示),而 MainAgent 编写的简报给 Claude Code 或 Codex — 是它自己的文字 — 所以像“一路简报子代理用英语”这样的单行指令可以将该通道固定在你想要的任何语言上。 你阅读的语言与代理推理的语言是解耦的。
## omux 是一个循环,而不是一个提示框
今年编码代理发生转变的一个名称 — **循环工程**,由谷歌的 Addy Osmani 结构化,之后是 [Boris Cherny](https://addyosmani.com/blog/loop-engineering/)(他创建了 Claude Code)和 Peter Steinberger(OpenClaw)不断重复同样的事情:
> “我不再提示 Claude。我有运行 Claude 并找出要做的事情的循环。我的工作是编写循环。”
> — **Boris Cherny**,*Acquired Unplugged*,2026 年 6 月
> “你不应该再提示编码代理。你应该设计提示你的代理的循环。”
> — **Peter Steinberger**
想法:停止手动提示代理一步一步。建立一个系统,为你提示它,迭代直到目标**可验证** 实现,并只有在它真正需要你时才回复。人类从提示者变为**循环设计者**。
**omux 的 MainAgent 就是那个通用循环,已经预先构建好了。** 你用日常语言与它交流;它为 Claude Code / Codex 编写提示,读取它们的窗格,决定下一步,并继续直到满足成功条件。你不需要在 bash 中编写循环 — omux **就是** 循环。
Osmani 命名了循环工程设置需要的六个基本元素。omux 直接提供了四个,并近似实现了另外两个:
| 循环工程基本元素 | omux |
|---|---|
| **子代理** — 制造者 ≠ 检查者 | ✓ Claude Code 实现,**Codex 独立审查差异** — 不同供应商,不同模型,在一个会话中 |
| **状态/内存** — 外部,持久 | ✓ 两层混合内存(全局 + 项目)+ 共享的 `tasks.txt` / `progress.txt` 用于跨代理交接 |
| **技能** — 编纂知识 | ✓ SKILL.md 前言,条件激活 |
| **连接器** — MCP | ✓ 并且 *每个代理范围*,不是工具汤 |
| **并行隔离** — 工作树 | ~ 在单独的 tmux 窗格/工作目录中的并行代理(进程级,而不是 git 工作树级) |
| **自动化** — 调度分类 | ~ 自我继续,一旦启动(如下);暂无 cron 分类 |
使循环变得真实的三个部分:
- **自动继续门(`/autocontinue`)。** 在每个自然停止点,门模型会询问*目标是否实际满足,还是有下一轮?* — 并继续运行循环或交回给你,限定它不会失控。
- **循环形系统。** MainAgent 提示符是围绕 TDD 循环编写的,其中失败的测试是*继续* 信号,而不是停止,并且独立工作会扩展到并行子代理而不是阻塞一个。
- **推送式等待。** 当子代理努力工作时,MainAgent 会停车 — 零 LLM 调用,零令牌 — 直到窗格稳定并且回调唤醒它。 没有循环在你离开时安静地烧钱。
诚实地面对边缘:omux 为你提供了一个通用的循环(MainAgent),而不是要求你为特定任务编写循环,其并行隔离是窗格和工作目录,而不是 git 工作树。 但核心赌注 — **你与提示编码代理的循环进行交流,而不是自己提示它们** — 正是 Cherny 描述的转变。
## 演示
[](https://github.com/Happenmass/omux/raw/main/assets/cliclaw_demo.mp4)
> 点击缩略图播放演示(约 70 MB MP4)。
## omux 如何工作
这是诚实的景观。omux 不是这个领域中唯一的东西。
| | omux | Claude Code 子代理 | OpenHands | Cursor Composer |
|---|---|---|---|---|
| 运行多个代理并行 | ✓ | 有限 | ✓ | 部分 |
| 工具无关(Claude Code,Codex,aider,本地…) | ✓ | 仅 Claude | 自己的运行时 | 自己的运行时 |
| 使用代理的原生 TUI(实时查看其推理) | ✓ | ✓ | ✗ | ✗ |
| 驱动确认提示/交互流程 | ✓ | 不适用(进程内) | — | — |
| 远程友好(SSH,tmux 断开,重现) | ✓ | ✓ | ✓ | ✗ |
| 持久内存 + 技能系统 | ✓ | ✓ | ✓ | 部分 |
| 每个代理的 MCP 范围(无工具汤膨胀) | ✓ | ✗ | ✗ | ✗ |
<sub>截至 2026 年中旬的景观快照 — 这些工具发展迅速;欢迎更正。</sub>
如果你已经在使用 CLI 编程代理,你想一次运行多个实例,并且不想通过包装代理在 API 中放弃丰富的 TUI 输出,那么 omux 就是为你准备的。
## 工作原理
```
┌───────────────────────────────────────────────────────┐
│ Web 聊天界面 ⇄ WebSocket ⇄ MainAgent ⇄ LLM │
└───────────────────────────────────────────────────────┘
│
▼
tmux 会话
┌────────┬────────┐
│ 窗格 A │ 窗格 B │ ← 编程代理在这里运行
│ Claude │ Codex │ (Claude Code,Codex,…)
│ Code │ │
└────────┴────────┘
│
▼
┌─────────────────────┐
│ 状态检测器 │ ← 读取窗格输出,分类为
│ 活动/等待/完成/错误 │ 活动/等待/完成/错误(每个代理的正则表达式,LLM 用于模糊性)
└─────────────────────┘
```
值得讨论的部分:
**通过窗格抓取进行状态检测。** 每个代理适配器声明四个正则表达式模式 — 等待输入、活动工作、完成、错误。状态检测器以适度的速率轮询 tmux 窗格,分类它看到的内容,并发出 MainAgent 订阅的事件。当正则表达式不明确时 — 引用了仍然在工作的记录中的错误,不熟悉的提示 — 一个廉价的 LLM 分类传递会解决它,偏向于“仍然工作”,以便忙碌的代理不会因假“完成”而中断。 没有 API 钩子。 没有 SDK。 代理不知道 omux 的存在。
**适配器抽象。** 添加对新 CLI 代理的支持是一个薄适配器(几百行代码):四个正则表达式模式、启动命令、确认/中止按键。`src/agents/adapter.ts` 是合同。
**混合内存,两层。** 基于 SQLite 的存储,带有两个索引 — `sqlite-vec` 用于密集检索,`FTS5` 用于 BM25,可配置的加权组合。包括一个用于完全离线操作的本地 `node-llama-cpp` 路径(Qwen3-Embedding)的五个嵌入提供程序。内存生活在两个层中,它们被索引和搜索在一起:一个**全局** 存储(你的编码风格,你的语气,你的团队成员,不会因切换仓库而改变)和一个**每个项目** 存储(该代码库的约定,其架构决策,其开放待办事项)。相同的编辑、搜索和 `/tidy` 机制适用于两者。 Markdown 文件是事实来源;数据库是索引。 终止的子代理会留下恢复 ID(持久到内存),因此后续会话可以通过 `claude --resume` / `codex resume` 恢复其完整对话,而不是从冷启动开始。
**技能系统。** 带有前言的 Markdown 文件,从两个地方发现:每个适配器捆绑的技能和项目特定的 `.omux/skills/`。根据描述,技能按需加载,通过条件激活 — MainAgent 决定何时技能相关,然后读取完整指令。项目本地技能**按设计选择加入** (配置中的 `skills.trustedWorkspaceDirs`,默认拒绝),因此克隆仓库永远不会在不经通知的情况下将指令注入到你的编排器中。仿照 Claude 的技能。
**每个代理的能力范围。** 每个子代理都有自己的 MCP 名单(即将推出每个代理的技能范围)。不要将你曾经安装的每个工具加载到每个代理中 — 只给每个代理它需要的工具。后端代理获取数据库 MCP;文档代理不需要。结果:更小的系统提示,无工具名称冲突,以及 LLM 不会被它永远不会调用的工具分散注意力。这是为现有代理堆栈重新设计而付出的困难问题之一 — omux 的适配器抽象使其变得便宜。
**令牌成本工程。** MainAgent 自己的账单故意保持薄。上下文压缩依赖于与常规回合相同的提示缓存,而不是为单独的完整价格摘要调用付费;系统的可变部分放在末尾,因此压缩永远不会使缓存的前缀失效;提示内的内存快照故意不热加载会话中间,以达到相同目的。详细信息见 [docs/prompt-cache-design-spec.md](docs/prompt-cache-design-spec.md)。
**学习会话**(实验性,默认关闭)。当子代理被终止时,omux 捕获它实际更改的内容 — 对启动时间基准的 git 差异,包括脏工作树 — 并生成结构化摘要:更改内容、原因、关键文件、设计决策。每个条目都有一个隔离的聊天,以便您可以询问更改,可以刷新到长期内存。启用配置中的 `learning.enabled`。
代码布局:
```
src/
├── core/ MainAgent,工作队列,上下文管理器,内置工具处理程序,
│ 学习管道(提示跟踪器 + 更改跟踪器 + 总结器)
├── agents/ 适配器接口 + Claude Code / Codex 实现
├── tmux/ 桥(连接到 tmux CLI),状态检测器
├── llm/ 提供者无关的客户端(12 个提供者,3 个线路协议)
├── memory/ sqlite-vec + FTS5 混合搜索,嵌入器,切分器
├── skills/ 解析器,注册表,注入器,过滤器
├── tui/ 仪表板 + 代理预览(自定义差异渲染器)
├── server/ Express + WebSocket + 身份验证
└── persistence/ 代理和对话存储(SQLite)
```
## 安装
需要 **Node 20+** 和 **tmux**。
```bash
# macOS
brew install tmux
# Ubuntu/Debian
sudo apt install tmux
```
安装 omux:
```bash
npm install -g @happenmass/omux
omux # 前台运行,打印 URL
# → 打开 http://localhost:3120
```
或作为守护进程运行:
```bash
omux start # 后台
omux stop
omux restart
```
日志:`~/.omux/logs/server.log` · 配置:`~/.omux/config.json` · 状态:`~/.omux/server-state.json`。(早期版本中现有的 `~/.cliclaw` 主目录仍然有效 — omux 会自动拾取它,无需迁移。)
## 配置
最低配置:
```json
{
"defaultAgent": "claude-code",
"llm": {
"provider": "anthropic",
"model": "claude-sonnet-4-6",
"apiKey": "sk-..."
}
}
```
或运行 `omux config` 以获取交互式 TUI。环境变量(`ANTHROPIC_API_KEY`,`OPENAI_API_KEY`,...)作为回退读取。要并排运行 Claude Code 和 Codex,请添加 `"enabledAgents": ["claude-code", "codex"]` — MainAgent 仅在该列表中启动适配器。
支持的 LLM 提供商:OpenAI、Anthropic、OpenRouter、DeepSeek、Gemini、Groq、Mistral、xAI(Grok)、Together、Moonshot(Kimi)、MiniMax、Ollama。
## 安全性和网络暴露
默认情况下,omux 绑定到 `0.0.0.0` 并通过 mDNS/Bonjour 广播,因此您可以在同一网络上的手机或笔记本电脑上打开 UI。身份验证是一个配对令牌:启动 URL 带有一次性 `?token=`,设置会话 cookie;令牌在每次重启时旋转,从未包含在 mDNS 广播中。在依赖它之前,有两件事需要注意:
- **传输是纯 HTTP。** 在共享或不受信任的网络上,配对 URL 和 cookie 是可嗅探的。对于远程使用,更喜欢使用 SSH 隧道(`ssh -L 3120:localhost:3120 <host>`)而不是暴露端口。
- **本地进程是受信任的。** 来自本地的连接完全跳过令牌 — 任何在同一台机器上运行的东西都可以访问 API。
要锁定:`omux --host 127.0.0.1 --no-mdns` 绑定到仅回环地址,无发现广播(绑定到 `127.0.0.1` 已禁用 mDNS 广播)。并将运行 omux 的机器视为受信任的基础设施 — MainAgent 可以按设计读取文件和驱动终端。
## 聊天命令
| 命令 | 效果 |
|---|---|
| `/stop` | 中断当前任务(继续由自动恢复模型处理) |
| `/autocontinue` | 切换自动继续 — 循环在停止点自行继续,直到目标实现(上限) |
| `/clear` · `/reset` | 清除对话(重置还会重新加载提示/技能) |
| `/compact` | 强制压缩对话历史 |
| `/context` | 显示当前上下文的令牌使用情况 |
| `/tidy` | 让 LLM 审查内存文件,存档过时条目 |
## 状态和路线图
**今天(v4.0.0):** 对我来说每天都有效,与 Claude Code 和 Codex 一起使用。跨供应商 **执行-然后-审查**(Claude 实现,Codex 审查),**自动继续循环** 和循环形 MainAgent 提示在 v3.0 中落地;v3.1- v3.2 加强了执行循环(修复了竞争问题,提取了工具处理程序)并使提示与代码重新对齐。 内存 + 技能 + 混合搜索已发货。 网络聊天界面是主要界面(仍然运行旧的 TUI 仪表板)。尚未针对生产团队工作流进行战斗测试。
**下一步:**
- [ ] 每个代理的技能范围(已发货的 MCP 范围)
- [ ] 更多代理适配器(aider,gemini-cli,open-interpreter)
- [ ] Slack / Discord 桥(在手机上驱动 omux)
- [ ] 多用户模式(团队共享单个 omux 服务器)
- [ ] 更丰富的执行证据(显示测试结果、差异、PR 链接在聊天中)
- [ ] 预算/速率限制强制执行跨代理
如果您有特定的需求,请提出问题 — 这仍然是一个个人项目,优先级是灵活的。
## 常见问题
**omux 是否会为任务选择要使用的 CLI 代理?**
在您启用的适配器中,是的。 MainAgent 会查看所有活跃的适配器及其特性(在提示中列在“代理能力”下),并根据适合度为每个任务选择适配器 — 对于复杂的单点推理和深度调试,优先使用 **Codex**,对于广泛的多文件工作和紧密的编辑→测试→重新运行循环,使用 **Claude Code**,然后让另一个适配器进行审查(参见下面的执行后审查常见问题)。如果您只启用了一个适配器,就没有什么可供选择 — 它直接运行该适配器。菜单始终是您启用的适配器:它不会悄悄地引入您未启用的工具。角色不是硬编码的 — 任意适配器都可以实施,任意适配器都可以审查;实施/审查的划分是一种启发式方法,而不是固定的劳动分工。
**我可以同时运行 Claude Code 和 Codex 吗?**
可以 — 从 v3.0.0 开始,这是一个主要功能。启用两个适配器,omux 在单个会话中运行一个 **执行后审查循环**:Claude Code 实施,然后一个单独的 Codex 代理独立审查差异 — 正确性、边缘情况、回归 — 并将修复路由回去。它们保持为不同的代理,您可以单独调用它们,并且角色是可互换的:任意适配器都可以实施,任意适配器都可以审查。默认启发式方法是 Claude 实施 / Codex 审查;您可以按任务覆盖。(想要两个完全独立的会话?在不同的端口上运行两个 omux 实例。)
**为什么按代理限定 MCP 而不是全局限定?**
因为工具混杂会造成混乱。您加载的每个 MCP 都将其工具描述注入到启用它的每个代理的系统中。文档代理不需要您的 Postgres MCP,而 LLM 会被它永远不会调用的工具分散注意力。omux 允许您为每个代理提供一个专注的工具集 — 更小的提示、更快的决策、无名称冲突。按代理限定技能范围即将推出。
**为什么使用两层内存(全局 + 项目)?**
您教给代理的一些东西是关于 *您* 的 — 您的编码风格、您的语气、您的同事的名字。每次您进入新仓库时重新教导这些知识是浪费的。其他一些东西是关于 *此代码库* 的 — 其约定、其开放的待办事项、其架构上的怪癖 — 不应该延伸到无关项目中。omux 将内存分成两个层,并一起搜索它们。两个层都运行在相同的混合搜索索引和相同的编辑工具上,因此在任一层上的体验都是相同的。
**我可以更改上下文窗口大小吗?**
您通常不必这样做 — omux 根据模型 ID 推导出窗口(claude → 200k,gemini / gpt-4.1 → 1M,无法识别的模型的 500k 备用)。要覆盖:启动时使用 `--context-window`,或在 `~/.omux/config.json` 中使用 `context.contextWindowLimit`。omux 监视使用情况,并在您超过阈值时自动压缩(或刷新到内存),因此您可以将窗口与模型和预算匹配,而不必亲自管理。
**为什么使用 tmux 而不是 Anthropic SDK / OpenAI Assistants API?**
因为 Claude Code 或 Codex 的体验不在其 API 中 — 而是在其终端用户界面(TUI)中。交互式确认、逐步推理、“我即将执行的操作”预览 — 所有这些都是 TUI 输出。包装 API 会剥夺这些功能。驱动 TUI 可以保留这些功能,并且作为奖励,您可以与任何 CLI 代理兼容。
**不同代理在更新其 UI 时如何跨代理检测状态?**
每个适配器都声明其自己的正则表达式模式。当 Claude Code 2026.04 更改其提示格式时,您只需编辑一个文件。核心编排器不知道也不关心这些变化。
**omux 是否需要自己的 API 密钥?**
需要 — 一个用于 MainAgent 的推理。编码代理使用它们已经使用的密钥。您支付的令牌数量是两倍,但 MainAgent 的流量比编码代理小得多。
**我可以在一个语言中聊天,而代理在另一个语言中工作吗?**
可以。omux 自动检测您的本地语言(或您可以在 `~/.omux/config.json` 中设置 `locale` — 目前支持 `zh-CN` 和 `en-US`),并将其用于聊天界面和 MainAgent 对您的回复。MainAgent 编写的 **进入** 编码代理的简报是一个单独的、可控制的通道:告诉它一次用英语向子代理简报,它就会这样做 — 因此,您可以用中文读写,而 Claude Code 或 Codex 会用英语(或任何组合)获取简报。如果您认为在母语中思考速度更快,但希望编码代理的推理轨迹保持在其训练数据最密集的语言中,这很有用。
**我可以在远程服务器上运行此程序吗?**
可以。tmux 设计用于 detached 会话。SSH 登录,启动 omux,分离,数小时后回来,从您离开的地方继续。这实际上是我使用它的主要模式。
**代理正在运行时,我可以接管控制权吗?**
可以。任何代理窗格都可以通过 Web UI 取得控制:您获得实时终端,您的按键直接输入,MainAgent 在您释放代理控制权之前不会干预该代理。对于较轻的操作,`/stop` 命令在各轮之间停止 MainAgent — 它也可以在子代理偏离轨道时中断它。
**如果 omux 服务器在任务中途崩溃,会发生什么?**
不必太担心。子代理存在于 tmux 中,不在服务器进程中 — 它们在服务器崩溃或重启时继续工作。启动时,omux 重新采用正在运行的 `omux-*` (和旧的 `cliclaw-*` )会话,从 SQLite 恢复对话,并修复任何在飞行中中断的工具调用。
**为什么叫“omux”?**
**o**rchestrate × **tmux** — 在您的代理生存的地方生活的编排器。(omux 是 cliclaw 的新名称。)
## 致谢与许可
由 [@happenmass](https://github.com/Happenmass) 构建。遵循 MIT 许可。
架构上感谢 Claude Code 团队为设定标准而做出的努力,使 omux 值得被构建。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器