
1. 从零认识 openrig它到底解决什么问题第一次看到 openrig 这个名字很多人会以为是某个硬件支架项目毕竟 rig 在英文里有“装配、支架”的意思。但如果你最近在折腾 Claude Code、Codex 这类命令行 AI 编程工具就会明白它其实是一个多 AI 编码代理的统一编排层。简单说openrig 做的事情就是把你机器上散落各处的 AI 编程助手Claude Code、Codex CLI 等用一个统一的配置文件和一套会话管理机制串起来让它们共享上下文、共享工作目录、共享终端会话而不是每开一个工具就要重新配置一遍环境、重新解释一遍项目背景。我最初接触这类需求是因为同时用 Claude Code 写业务逻辑、用 Codex 做代码审查两边都要各自维护一份项目说明和 API 配置切换一次就要重新交代一遍“这个项目用的是什么框架、哪些目录不要动、测试怎么跑”。这种重复劳动在真实项目里非常消耗精力。openrig 的核心价值就在于把这些重复配置收敛到一份 YAML 里再配合 tmux 做会话持久化让多个代理在同一个工作区里协同。它适合谁如果你已经在用或者准备用 Claude Code、Codex 这类工具做日常开发并且遇到过“配置散乱、会话丢失、多工具上下文不同步”的问题那 openrig 就是为你准备的。哪怕你只是刚装好 Claude Code 的新手理解 openrig 的设计思路也能帮你把工具链整理清楚。下面我会从整体设计、核心配置、实操流程到问题排查完整拆一遍。2. openrig 的整体设计与思路拆解2.1 为什么需要一层“编排”而不是直接用原生工具Claude Code 和 Codex CLI 各自都能独立工作官方也提供了配置文件。但问题在于它们是各自为政的。Claude Code 读自己的配置Codex 读自己的配置两者的会话状态、工作目录、环境变量互不相通。当你想让两个代理协作时要么手动复制粘贴上下文要么写一堆 shell 脚本去桥接。openrig 的思路是把“代理怎么启动、读什么配置、在哪个会话里跑”抽象成声明式配置。你不再关心每个工具的具体启动参数而是描述“我要一个跑 Claude Code 的会话工作目录是 X注入这些环境变量”openrig 负责把它翻译成实际的启动命令并挂到 tmux 会话上。这种声明式的好处是可复现换一台机器把 YAML 拷过去一条命令就能恢复整套环境。这里有个关键的设计取舍openrig 没有选择自己实现一个全新的代理运行时而是复用现有 CLI 工具 tmux。这个选择非常务实。因为 Claude Code、Codex 的模型能力和工具调用逻辑是它们自己的核心竞争力重新实现一遍既没必要也不现实。openrig 只做编排层把复杂度控制在配置管理和会话调度上这样即使上游工具升级openrig 也只需要适配启动参数不会伤筋动骨。2.2 tmux 在其中的角色不只是“后台运行”很多人以为 tmux 只是让程序在后台跑关掉终端也不中断。但在 openrig 的架构里tmux 承担的是会话状态容器的角色。每个 AI 代理跑在一个独立的 tmux window 或 pane 里这意味着会话可以随时 attach 回去看历史输出不会因为网络断开或终端关闭而丢失上下文多个代理可以在同一个 tmux session 的不同 window 里并行工作互不干扰通过 tmux 的 send-keys 机制openrig 可以向指定会话注入命令实现代理之间的消息传递。我实测下来tmux 的send-keys配合capture-pane是做代理间通信最轻量的方案。不需要额外的消息队列或 socket 服务直接操作终端缓冲区就行。当然这也有代价就是输出解析依赖文本匹配不如结构化 API 稳定。但对于个人开发场景这个取舍是划算的。2.3 YAML 配置驱动的核心逻辑openrig 用 YAML 而不是 JSON 或 TOML原因很直接YAML 支持注释、支持多行字符串、层级表达清晰适合写“给人看也给人改”的配置。一个典型的 openrig 配置大概长这样version: 1 workspace: ~/projects/myapp agents: claude: tool: claude-code args: - --model - claude-sonnet-4-5 env: ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY} session: rig-claude codex: tool: codex args: - --profile - review env: OPENAI_API_KEY: ${OPENAI_API_KEY} session: rig-codex这份配置里workspace定义了共享工作目录agents下面每个条目描述一个代理。tool指定用哪个 CLIargs是透传给该工具的启动参数env是环境变量注入session是 tmux 会话名。openrig 读取这份配置后会为每个 agent 创建对应的 tmux 会话并启动工具。注意环境变量建议用${VAR}形式引用系统环境变量不要把密钥明文写进 YAML。我见过有人直接把 API key 写进配置文件然后提交到 Git这是非常危险的操作。2.4 与 Claude Code、Codex 的适配层设计openrig 对每个工具做了一层薄适配。因为 Claude Code 和 Codex 的启动方式、配置路径、会话恢复机制都不一样。Claude Code 有自己的~/.claude配置目录Codex 有~/.codex两者的认证方式也不同。openrig 的适配层负责检查工具是否已安装通过which或版本命令按配置组装启动命令处理工具特有的初始化逻辑比如 Codex 需要先登录、Claude Code 需要确认订阅状态把工具输出重定向到 tmux 会话。这层适配是 openrig 最需要维护的部分因为上游工具更新频繁。但好在适配逻辑集中在少数几个文件里改动可控。3. 核心细节解析与实操要点3.1 环境准备先把基础工具装齐在碰 openrig 之前你得先确保底层工具都在。这一步很多人会跳过结果后面报错找不到原因。我按顺序列一下需要的东西tmux会话管理的基础。Ubuntu 下sudo apt install tmuxmacOS 下brew install tmux。装完用tmux -V确认版本建议 3.0 以上。Claude Code官方安装方式是通过 npmnpm install -g anthropic-ai/claude-code。装完运行claude会引导你完成认证。如果你在 Windows 上建议用 WSL原生 Windows 支持一直不太稳定。Codex CLI同样通过 npm 安装npm install -g openai/codex。装完codex login完成认证。Node.js 18上面两个工具都依赖 Node版本太低会直接报错。YAML 解析库如果你要自己写脚本处理配置Python 用pyyamlNode 用js-yaml。提示安装 Claude Code 时如果遇到 “your organization has disabled claude subscription access” 这类提示通常是账号订阅类型的问题需要确认你的账号是否有对应的访问权限。这不是 openrig 的问题是上游工具的认证限制。3.2 YAML 配置文件的字段详解openrig 的配置文件字段设计得不复杂但每个字段都有讲究。我把关键字段拆开讲字段类型必填说明versionint是配置格式版本目前是 1workspacestring是所有代理共享的工作目录支持~展开agentsmap是代理定义集合key 是代理名agents.*.toolstring是工具标识如claude-code、codexagents.*.argslist否透传给工具的启动参数agents.*.envmap否环境变量注入agents.*.sessionstring是tmux 会话名需全局唯一agents.*.auto_startbool否是否在 openrig 启动时自动拉起默认 trueworkspace字段特别重要因为它决定了代理看到的文件系统范围。我建议把它设成具体项目目录而不是用户主目录避免代理误操作无关文件。session命名也要有规律比如统一加rig-前缀方便用tmux ls过滤。3.3 会话隔离与共享的边界openrig 里有个容易混淆的点哪些东西是共享的哪些是隔离的。我整理成一张表资源是否共享说明工作目录共享所有代理看到同一个 workspace文件系统共享同上代理可以读写同一批文件环境变量隔离每个代理有独立的 env 注入tmux 会话隔离每个代理独立会话互不干扰终端历史隔离各自会话的 scrollback 独立API 凭证隔离各自读各自的密钥这个设计的好处是文件层面协作、进程层面隔离。两个代理可以改同一个文件当然要小心冲突但一个代理崩溃不会影响另一个。我在实际使用中会让 Claude Code 负责写代码Codex 负责审查两者共享工作目录但独立会话配合起来很顺。3.4 启动流程的时序细节openrig 启动时的执行顺序是有讲究的理解这个顺序能帮你排查很多问题读取并校验 YAML 配置检查必填字段展开workspace路径确认目录存在对每个 agent检查tool对应的 CLI 是否在 PATH 里检查session是否已存在存在则跳过创建幂等创建 tmux 会话设置工作目录注入环境变量启动工具命令记录会话映射到状态文件供后续操作查询。第 4 步的幂等设计很关键。这意味着你可以反复运行 openrig 启动命令不会重复创建会话。我经常在调试配置时反复跑启动命令这个特性省了很多手动清理的麻烦。4. 实操过程与核心环节实现4.1 从零搭建一个双代理工作区假设你有一个项目在~/projects/demo想让 Claude Code 和 Codex 同时在这个项目上工作。完整流程如下。第一步创建配置文件~/.openrig/demo.yamlversion: 1 workspace: ~/projects/demo agents: claude: tool: claude-code args: - --model - claude-sonnet-4-5 env: ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY} session: rig-demo-claude codex: tool: codex args: - --profile - default env: OPENAI_API_KEY: ${OPENAI_API_KEY} session: rig-demo-codex第二步确认环境变量已经导出。在~/.bashrc或~/.zshrc里加上export ANTHROPIC_API_KEY你的密钥 export OPENAI_API_KEY你的密钥改完记得source ~/.bashrc让配置生效。可以用echo $ANTHROPIC_API_KEY确认。第三步运行 openrig 启动命令。具体命令取决于你的 openrig 安装方式假设是openrig up -c ~/.openrig/demo.yaml。执行后你会看到类似输出[openrig] loading config: /home/user/.openrig/demo.yaml [openrig] workspace: /home/user/projects/demo [openrig] agent claude - session rig-demo-claude [created] [openrig] agent codex - session rig-demo-codex [created] [openrig] 2 agents running第四步验证会话。运行tmux ls应该能看到两个会话rig-demo-claude: 1 windows (created ...) rig-demo-codex: 1 windows (created ...)第五步attach 到某个会话看输出比如tmux attach -t rig-demo-claude。你会看到 Claude Code 的交互界面已经在工作目录里启动了。4.2 参数选择背后的计算与考量配置里有几个参数值得展开说。--model选哪个模型直接关系到成本和效果。以 Claude 为例Sonnet 系列在代码任务上性价比高Opus 系列更强但贵。我的经验是日常写代码用 Sonnet遇到复杂重构或架构设计再切 Opus。这个切换可以通过改 YAML 里的args实现改完重启对应会话即可。Codex 的--profile参数对应~/.codex/config.toml里的配置档。你可以定义多个 profile比如一个用强模型做审查一个用快模型做补全。openrig 的args透传机制让你不用改 openrig 本身就能切换这些行为。环境变量注入这块有个细节openrig 注入的 env 会覆盖系统已有的同名变量。这意味着你可以在 YAML 里为不同代理指定不同的密钥或端点。比如你想让 Codex 走某个兼容端点就在它的 env 里设OPENAI_BASE_URL不影响 Claude Code。4.3 代理间协作的实操模式两个代理跑起来后怎么让它们协作我常用的模式是“生产者-审查者”Claude Code 会话里让它实现一个功能模块实现完成后通过 tmux send-keys 把改动摘要发给 Codex 会话Codex 审查代码输出问题列表把问题列表发回 Claude Code 会话让它修复。第 2 步的 send-keys 命令大概是这样tmux send-keys -t rig-demo-codex 请审查 src/auth.py 的改动重点关注边界条件 Enter第 3 步读取 Codex 输出tmux capture-pane -t rig-demo-codex -p | tail -50这套流程我实测下来很顺关键是消息要简短明确。不要一次性发一大堆上下文代理的上下文窗口有限塞太多反而降低质量。我一般控制在 200 字以内的指令。4.4 会话持久化与恢复tmux 会话默认在机器重启后会丢失。如果你希望重启后还能恢复需要配合 tmux 的插件或者自己写恢复脚本。我的做法是维护一个状态文件记录每个会话的工作目录和启动命令重启后读这个文件重新拉起。openrig 本身如果实现了状态持久化会把这个逻辑封装掉。如果没有你可以用tmux-resurrect插件做基础恢复再手动补上环境变量注入。这里要注意API 密钥不会自动恢复因为插件只保存会话结构不保存环境变量。所以重启后还是要确保 shell 里导出了密钥。5. 常见问题与排查技巧实录5.1 启动失败类问题速查这类问题最让人头疼因为报错信息往往不直接指向根因。我整理了一张速查表现象可能原因排查方法提示 tool not foundCLI 未安装或不在 PATHwhich claude/which codex会话创建后立即退出工具启动参数错误手动跑一次启动命令看报错环境变量为空shell 未导出或 YAML 引用错误echo $VAR确认工作目录不存在workspace 路径写错ls确认路径认证失败密钥无效或订阅限制单独跑工具确认认证状态会话名冲突已有同名会话tmux ls检查并清理我踩过最坑的一次是workspace用了相对路径结果 openrig 在不同目录下启动时解析到了不同位置代理看到的文件完全不对。后来统一改成绝对路径或~开头的路径问题就没了。5.2 代理输出异常的处理有时候代理会话看起来在跑但输出卡住或者乱码。常见原因有几个终端尺寸问题tmux 会话的默认尺寸可能和工具预期不符导致界面渲染错乱。解决方法是创建会话时指定尺寸或者在 attach 后手动 resize。编码问题如果工具输出包含特殊字符capture-pane 抓取时可能乱码。建议在 tmux 配置里设set -g default-terminal screen-256color。缓冲未刷新工具输出有缓冲capture-pane 抓到的可能是旧内容。可以加个短暂 sleep 再抓或者用-S -参数抓完整 scrollback。提示capture-pane 抓取的是渲染后的文本不是原始输出流。如果工具用了复杂的 TUI 界面抓取结果可能包含大量控制字符需要额外清洗。5.3 多代理并发冲突的规避两个代理同时改同一个文件冲突几乎必然发生。我的规避策略是按目录划分职责Claude Code 负责src/Codex 负责tests/各自不越界。如果确实需要改同一个文件就串行化——先让一个改完并提交再让另一个基于最新版本工作。另一个冲突点是 API 速率限制。如果两个代理同时高频调用同一个 API可能触发限流。解决办法是给不同代理配不同的密钥或者错开它们的活跃时间。我在配置里会给每个代理设一个rate_limit提示虽然 openrig 不一定强制但至少提醒自己注意。5.4 配置热更新的注意事项改完 YAML 后openrig 通常需要重启对应会话才能生效。直接改文件不会自动重载。重启单个会话的命令大概是tmux kill-session -t rig-demo-claude openrig up -c ~/.openrig/demo.yaml --only claude--only参数如果支持可以只重启指定代理不影响其他会话。如果没有这个参数就得全部重启。重启前记得保存代理会话里的重要输出因为 kill-session 会清掉 scrollback。6. 我个人的实操心得与扩展思路用了一段时间 openrig 这套模式后我最大的体会是编排层的价值不在于功能多而在于把重复劳动收敛掉。以前每开一个新项目就要重新配一遍工具现在复制一份 YAML 改几个字段就行。这种效率提升在长期项目里累积起来非常可观。几个我踩过坑之后总结的小技巧第一YAML 里所有路径都用绝对路径或~开头别用相对路径第二会话名统一加前缀方便批量操作第三环境变量永远走 shell 导出不写进配置文件第四定期清理僵尸会话tmux ls看到不认识的会话先确认再杀。这个模式后续还能往几个方向扩展。一是加一层健康检查定期 ping 每个代理会话挂了自动重启二是把代理间的消息传递从 tmux send-keys 升级成结构化协议减少文本解析的脆弱性三是把配置拆成基础配置和项目配置两层基础配置放通用设置项目配置只写差异部分。这些扩展都不需要改动上游工具纯粹在编排层做文章风险可控。