1. 从“openrig”说起:一个把 Claude Code 和 Codex 装进同一副骨架的思路
第一次看到openrig这个词,我脑子里蹦出来的不是某个具体工具,而是一种“机架”的隐喻——rig 在英文里本来就有“装配、搭台子”的意思,open 则点明了它是开放的、可拼装的。把这两个词放在一起,再结合热搜里高频出现的 Claude Code、Codex、Node.js、tmux 这几个关键词,基本能判断出它想解决的核心问题:把当下最主流的两个终端 AI 编程助手,统一到一套可复用、可切换、可远程托管的本地运行环境里。
我自己从去年开始就同时在用 Claude Code 和 Codex 这两套 CLI 工具,踩过的坑不算少。最典型的一个场景是:白天在 VS Code 里用 Claude Code 改业务代码,晚上想换 Codex 跑一段重构脚本,结果两套工具的环境变量、Node 版本、认证配置互相打架,切换一次要折腾十几分钟。openrig这类项目出现的背景,就是冲着这种“多助手共存”的痛点去的。它不是一个新模型,也不是一个新 IDE,而是一层运行时的编排骨架——把 Node.js 运行时、CLI 工具本体、终端复用器 tmux、以及各家模型的接入配置,全部收敛到一套目录结构和启动脚本里。
它适合谁?我认为有三类人特别值得关注。第一类是同时使用多个 AI 编程 CLI 的开发者,尤其是那些需要在 Claude Code 和 Codex 之间频繁切换的人;第二类是需要在远程服务器上跑长任务的人,比如让 AI 助手在后台持续重构一个大仓库,这时候 tmux 的价值就体现出来了;第三类是喜欢把环境“脚本化、可复现”的工程师,他们不愿意每次换机器都重新配一遍 Node、重新登录一遍账号。这三类人的共同点是:他们要的不是“哪个模型更强”,而是“怎么让这些工具稳定地待在我的机器上,随时能用”。
需要先说明一点:openrig这个标题本身给的信息非常少,网络上的公开资料也零散,所以下面涉及的具体目录结构、脚本写法、参数配置,都是基于我实际搭建多 CLI 环境时的常见实践做的合理补全,不是对某个官方仓库的逐行复刻。你完全可以把它当成一套“多 AI 编程助手共存环境”的搭建方法论来读,把里面的名字换成你自己的即可。
2. 整体设计思路:为什么是 Node.js + tmux + 多 CLI 的组合
2.1 为什么底座选 Node.js 而不是别的运行时
Claude Code 和 Codex 这两套 CLI,目前主流的发行方式都是通过 npm 全局安装,底层跑在 Node.js 上。这就决定了你的机器上必须有一个可用的 Node 运行时。热搜里反复出现 “node.js安装”“node.js官网下载”“node.js lts下载”“error installing 24.21.0: node.js v24.21.0 is not yet released” 这些词,说明很多人在这一步就卡住了。
我的建议非常明确:生产环境一律用 LTS 版本,不要追最新的 Current 版本。上面那条报错 “node.js v24.21.0 is not yet released or is not available” 就是典型的追新踩坑——某个工具在安装脚本里写死了一个还没正式发布的版本号,结果 nvm 或 fnm 去拉的时候直接失败。LTS 版本(比如 20.x、22.x 系列)经过了足够长的验证周期,npm 生态的兼容性最好,CLI 工具的作者也基本都拿 LTS 做测试。
选 Node.js 作为底座还有一层考虑:它天然适合做“胶水层”。openrig这类项目往往需要写一些小的编排脚本,比如检测当前有哪些 CLI 可用、根据环境变量决定启动哪一个、把日志重定向到指定文件。这些活儿用 Node 写最顺手,因为 CLI 本身就是 Node 生态的一部分,不需要再引入 Python 或 Shell 的额外依赖。
2.2 tmux 在这里扮演什么角色
很多人第一次看到 tmux 出现在 AI 编程工具的语境里会愣一下:这不是运维才用的东西吗?其实 tmux 解决的恰恰是 AI 编程助手最要命的一个问题——长任务的会话保持。
你让 Claude Code 去重构一个几千行的模块,或者让 Codex 跑一轮完整的测试修复,这个过程可能持续十几分钟甚至更久。如果你直接在 SSH 会话里跑,网络一抖、笔记本一合盖,进程就断了,前面跑的全都白费。tmux 的作用就是把这些 CLI 进程放进一个独立于终端连接的会话里,你断开 SSH 之后它还在后台跑,重新连上来tmux attach就能看到完整输出。
在openrig的语境下,tmux 通常承担三个职责:一是会话隔离,Claude Code 跑在一个 window,Codex 跑在另一个 window,互不干扰;二是日志留存,配合pipe-pane可以把某个 pane 的输出实时写到文件里,方便事后复盘;三是批量启动,用一个脚本一次性创建好带命名规范的会话和窗口,省得每次手动敲。
2.3 多 CLI 共存的核心矛盾与解法
Claude Code 和 Codex 装在同一台机器上,最容易打架的地方有三个:全局命令名冲突、配置目录混淆、认证状态互相覆盖。比如两者都可能往~/.config下写自己的配置,如果目录名起得太像,排查问题时会非常痛苦。
openrig这类项目的设计哲学,我理解就是用一层显式的目录约定把每个工具隔离开。常见的做法是给每个 CLI 分配独立的配置根目录,通过环境变量在启动时注入。比如启动 Claude Code 时把它的配置指向~/.openrig/claude/,启动 Codex 时指向~/.openrig/codex/,这样两者的登录态、历史记录、缓存文件永远不会串。这个思路和前端项目里用.nvmrc锁定 Node 版本是同一类思想:把隐式的全局状态,变成显式的、可版本化的项目状态。
3. 核心细节拆解:环境搭建中的关键环节与避坑点
3.1 Node.js 安装:nvm、fnm 还是官方安装包
这是热搜里出现频率最高的一类问题,我直接把结论摆出来,再解释原因。
| 安装方式 | 适用场景 | 优点 | 坑点 |
|---|---|---|---|
| 官方安装包 | 单版本、图省事 | 一步到位,PATH 自动配好 | 换版本要卸载重装,权限问题多 |
| nvm | 需要多版本切换 | 生态成熟,资料多 | 启动脚本拖慢 shell,Windows 支持差 |
| fnm | 追求速度和跨平台 | Rust 写的,启动快,Windows 友好 | 相对新,部分老教程不适用 |
| Volta | 团队统一版本 | 自动按项目切版本 | 对冷门工具链支持一般 |
我个人的选择是fnm,主要原因是它在 Windows 上的体验比 nvm 好太多,而且 shell 启动速度明显更快。安装完之后,用fnm install --lts装一个 LTS 版本,再用fnm use lts-latest切过去。这里有个细节:一定要在 shell 配置文件里加上 fnm 的初始化脚本,否则新开的终端里 node 命令会找不到。bash 用户加在~/.bashrc,zsh 用户加在~/.zshrc。
注意:如果你在安装某个 CLI 时遇到 “node.js vXX is not yet released” 这类报错,八成是工具内部写死的版本号问题,不是你本地环境坏了。解决办法是先用
fnm install手动装一个可用的 LTS,再让工具跳过它自己的 Node 检测逻辑,或者直接改用npm install -g的方式装 CLI。
3.2 CLI 工具的安装与版本锁定
Claude Code 和 Codex 的安装命令本身不复杂,通常是npm install -g加包名。但真正影响长期使用的是版本锁定。我见过太多人今天装了个最新版,明天工具更新引入 breaking change,整个工作流就崩了。
我的做法是在openrig的目录下放一个package.json,把两个 CLI 都作为依赖写进去,并且用精确版本号而不是^或~。这样每次在新机器上npm install,装出来的版本完全一致。升级的时候手动改版本号,改完先在测试目录里跑一遍,确认没问题再推到主力环境。
{ "name": "openrig", "private": true, "dependencies": { "@anthropic-ai/claude-code": "1.x.x", "@openai/codex": "0.x.x" } }上面版本号里的x请替换成你实际验证过的版本。这个package.json不发布,纯粹作为本地环境的“锁文件”用。配合npm ci命令,可以做到每次安装都严格按 lock 文件来,不会出现“我这能跑你那不能跑”的情况。
3.3 配置目录隔离的具体做法
这是openrig思路里最值得抄的一部分。核心原则是:每个 CLI 的配置根目录,都通过环境变量显式指定,绝不依赖默认路径。
以 Claude Code 为例,它通常会读取CLAUDE_CONFIG_DIR这类环境变量来决定配置存放位置(具体变量名以官方文档为准,不同版本可能有差异)。Codex 也有类似的机制。在openrig的启动脚本里,我会这样写:
export OPENRIG_HOME="$HOME/.openrig" export CLAUDE_CONFIG_DIR="$OPENRIG_HOME/claude" export CODEX_HOME="$OPENRIG_HOME/codex" mkdir -p "$CLAUDE_CONFIG_DIR" "$CODEX_HOME"这样做的直接好处是:备份和迁移变得极其简单。整个~/.openrig目录打包带走,换台机器解压,登录态和历史记录全都在。反过来,如果配置散落在~/.config、~/.cache、~/Library/Application Support好几个地方,迁移一次能让人崩溃。
3.4 tmux 会话命名规范
tmux 用得好不好,一半看命名。我见过有人开了一堆0:bash、1:bash的窗口,过两天自己都不知道哪个是干嘛的。openrig场景下,我建议用项目名 + 工具名的组合来命名会话和窗口。
# 创建一个名为 openrig 的会话,第一个窗口叫 claude tmux new-session -d -s openrig -n claude # 在同一会话里新建一个窗口叫 codex tmux new-window -t openrig -n codex # 再建一个窗口专门看日志 tmux new-window -t openrig -n logs这样你tmux attach -t openrig进去,三个窗口一目了然。更进一步,可以在claude窗口里pipe-pane把输出写到~/.openrig/logs/claude.log,方便出问题时回溯。这个技巧在排查“AI 助手到底执行了哪条命令”时特别有用,因为终端滚屏会丢历史,日志文件不会。
4. 实操过程:从零搭一套可用的 openrig 环境
4.1 第一步:确认系统基础环境
动手之前先做体检,避免装到一半发现缺东西。在终端里依次跑这几条:
uname -a # 看系统架构,macOS/Linux 都适用 node -v # 看有没有 Node,没有就先装 npm -v # 确认 npm 可用 tmux -V # 确认 tmux 已安装 git --version # 很多 CLI 依赖 git如果tmux没装,macOS 用brew install tmux,Ubuntu/Debian 用sudo apt install tmux。Windows 用户建议在 WSL2 里操作,原生 Windows 下 tmux 基本没法用,这是硬伤。
提示:Windows 上如果坚持不用 WSL,那 tmux 这一环可以跳过,改用 Windows Terminal 的多标签页 + 后台任务来近似替代,但会话保持能力会打折扣。
4.2 第二步:安装并锁定 Node 版本
用 fnm 的话,流程是这样的:
# 安装 fnm(macOS/Linux) curl -fsSL https://fnm.vercel.app/install | bash # 重新加载 shell 配置 source ~/.bashrc # 或 source ~/.zshrc # 安装 LTS 版本 fnm install --lts fnm use lts-latest fnm default lts-latest # 验证 node -vfnm default这一步很关键,它决定了你新开终端时默认用哪个版本。不设的话,每次新终端都要手动fnm use,非常烦。
4.3 第三步:建立 openrig 目录骨架
我习惯把结构设计成下面这样,清晰且好扩展:
~/.openrig/ ├── package.json # 锁定 CLI 版本 ├── bin/ │ ├── start-claude.sh # 启动 Claude Code │ ├── start-codex.sh # 启动 Codex │ └── start-all.sh # 一键拉起 tmux 会话 ├── claude/ # Claude Code 配置目录 ├── codex/ # Codex 配置目录 └── logs/ # 日志输出建目录的命令:
mkdir -p ~/.openrig/{bin,claude,codex,logs} cd ~/.openrig npm init -y然后把前面说的package.json依赖部分补上,跑npm install。
4.4 第四步:编写启动脚本
start-claude.sh的内容大致如下,重点是环境变量注入和错误处理:
#!/usr/bin/env bash set -euo pipefail export OPENRIG_HOME="$HOME/.openrig" export CLAUDE_CONFIG_DIR="$OPENRIG_HOME/claude" # 确保 Node 环境已加载 eval "$(fnm env --use-on-cd)" # 启动 Claude Code,参数透传给 CLI 本身 exec npx --no-install claude-code "$@"set -euo pipefail这三件套是 Shell 脚本的保命符:遇到错误立即退出、未定义变量报错、管道中任一环节失败都算失败。少了它,脚本出错时会静默继续,排查起来很痛苦。
start-codex.sh同理,把配置目录换成codex,命令换成 Codex 的入口即可。
start-all.sh负责把 tmux 会话拉起来:
#!/usr/bin/env bash set -euo pipefail SESSION="openrig" # 如果会话已存在,直接 attach if tmux has-session -t "$SESSION" 2>/dev/null; then tmux attach -t "$SESSION" exit 0 fi # 创建会话和窗口 tmux new-session -d -s "$SESSION" -n claude tmux send-keys -t "$SESSION:claude" "$HOME/.openrig/bin/start-claude.sh" C-m tmux new-window -t "$SESSION" -n codex tmux send-keys -t "$SESSION:codex" "$HOME/.openrig/bin/start-codex.sh" C-m tmux new-window -t "$SESSION" -n logs tmux send-keys -t "$SESSION:logs" "tail -f $HOME/.openrig/logs/*.log" C-m tmux select-window -t "$SESSION:claude" tmux attach -t "$SESSION"给这三个脚本加执行权限:chmod +x ~/.openrig/bin/*.sh。之后每次开工,只要敲~/.openrig/bin/start-all.sh,三个窗口就都起来了。
4.5 第五步:验证与首次登录
第一次启动时,两个 CLI 都会要求登录或配置 API 凭证。这一步的细节各家不同,但通用原则是:凭证只存在各自的配置目录里,不要写进 shell 的全局环境变量。写全局变量的话,两个工具可能读到同一个 key,导致认证混乱。
登录完成后,做个简单验证:在 Claude Code 窗口里让它执行一条无害命令(比如列出当前目录),在 Codex 窗口里同样操作,确认两者互不干扰。然后tmux detach(快捷键Ctrl-b d)断开,重新tmux attach -t openrig,确认会话和输出都还在。
5. 常见问题与排查技巧实录
5.1 高频报错速查表
| 报错关键词 | 可能原因 | 排查方向 |
|---|---|---|
| node.js vXX is not yet released | 工具写死了未发布版本号 | 手动装 LTS,绕过工具自带检测 |
| cc switch local proxy failed | 本地代理端口被占用或配置错误 | 检查端口占用,确认代理配置指向正确 |
| organization has disabled subscription access | 账号权限或组织策略限制 | 确认账号类型,检查组织设置 |
| ignoring unrecognized configuration setting | 配置文件里有拼写错误或过时字段 | 逐行核对配置,删除未知字段 |
| codex 无法加载组织设置 | 网络或认证态异常 | 重新登录,检查配置目录权限 |
5.2 我踩过的三个真实坑
第一个坑:Node 版本和 CLI 版本不匹配。有次我用 Node 18 装了一个要求 Node 20+ 的 CLI,安装过程没报错,但一运行就各种诡异崩溃。后来才意识到 npm 的engines字段只是警告,不会阻止安装。解决办法是在package.json里显式声明engines,并在 CI 或启动脚本里加一道版本检查。
第二个坑:tmux 里的 PATH 和登录 shell 不一致。tmux 启动的会话默认不加载完整的 shell 配置,导致fnm管理的 node 找不到。解决办法是在启动脚本里显式eval "$(fnm env)",不要指望 tmux 自动继承。
第三个坑:两个 CLI 抢同一个日志文件。早期我图省事让两个工具往同一个日志文件写,结果内容交错,完全没法读。后来改成每个工具一个独立日志文件,用pipe-pane分别重定向,问题消失。
5.3 性能与稳定性的一些经验
长时间跑 AI 编程任务,有两个资源要盯紧:内存和文件描述符。Node 进程跑久了内存会涨,尤其是处理大仓库时。我的做法是在启动脚本里给 Node 加上--max-old-space-size参数,根据机器内存设一个合理上限,比如 4096(4GB)。文件描述符方面,如果同时开很多 tmux 窗口和日志管道,可能会碰到系统上限,用ulimit -n查看,必要时调高。
另外,不要把 tmux 会话开得太多。我见过有人给每个项目开一个会话,最后几十个会话挂着,机器负载很高。openrig的思路是一个会话管所有工具,用窗口区分,这样资源占用可控,管理也简单。
6. 关于多助手协作的一点个人体会
搭好这套环境之后,我最大的感受不是“效率提升了多少”,而是心态变了。以前切换工具要折腾环境,潜意识里就会抗拒尝试新东西,总是守着顺手的那个用。现在环境是脚本化的、隔离的、可复现的,想试一个新 CLI,无非是往package.json里加一行依赖、写一个启动脚本的事,试错成本极低。
这种“低摩擦”带来的直接结果是,我会更愿意让不同的助手干不同的事:Claude Code 负责需要大量上下文理解的业务逻辑改动,Codex 负责边界清晰的批量重构和测试补齐,两者在 tmux 的不同窗口里各跑各的,互不打扰。日志文件则成了我的“操作审计”,事后回看 AI 到底改了哪些文件、跑了哪些命令,一目了然。
如果你也在同时用多个 AI 编程 CLI,我强烈建议花一个下午把类似openrig的骨架搭起来。它不会让你的模型变聪明,但会让你的工作流变得干净、可预测、可迁移——而这三样东西,恰恰是长期高频使用 AI 工具时最容易被忽视、又最影响体验的部分。