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 跑在一个 windowCodex 跑在另一个 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需要多版本切换生态成熟资料多启动脚本拖慢 shellWindows 支持差fnm追求速度和跨平台Rust 写的启动快Windows 友好相对新部分老教程不适用Volta团队统一版本自动按项目切版本对冷门工具链支持一般我个人的选择是fnm主要原因是它在 Windows 上的体验比 nvm 好太多而且 shell 启动速度明显更快。安装完之后用fnm install --lts装一个 LTS 版本再用fnm use lts-latest切过去。这里有个细节一定要在 shell 配置文件里加上 fnm 的初始化脚本否则新开的终端里 node 命令会找不到。bash 用户加在~/.bashrczsh 用户加在~/.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 tmuxUbuntu/Debian 用sudo apt install tmux。Windows 用户建议在 WSL2 里操作原生 Windows 下 tmux 基本没法用这是硬伤。提示Windows 上如果坚持不用 WSL那 tmux 这一环可以跳过改用 Windows Terminal 的多标签页 后台任务来近似替代但会话保持能力会打折扣。4.2 第二步安装并锁定 Node 版本用 fnm 的话流程是这样的# 安装 fnmmacOS/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 SESSIONopenrig # 如果会话已存在直接 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参数根据机器内存设一个合理上限比如 40964GB。文件描述符方面如果同时开很多 tmux 窗口和日志管道可能会碰到系统上限用ulimit -n查看必要时调高。另外不要把 tmux 会话开得太多。我见过有人给每个项目开一个会话最后几十个会话挂着机器负载很高。openrig的思路是一个会话管所有工具用窗口区分这样资源占用可控管理也简单。6. 关于多助手协作的一点个人体会搭好这套环境之后我最大的感受不是“效率提升了多少”而是心态变了。以前切换工具要折腾环境潜意识里就会抗拒尝试新东西总是守着顺手的那个用。现在环境是脚本化的、隔离的、可复现的想试一个新 CLI无非是往package.json里加一行依赖、写一个启动脚本的事试错成本极低。这种“低摩擦”带来的直接结果是我会更愿意让不同的助手干不同的事Claude Code 负责需要大量上下文理解的业务逻辑改动Codex 负责边界清晰的批量重构和测试补齐两者在 tmux 的不同窗口里各跑各的互不打扰。日志文件则成了我的“操作审计”事后回看 AI 到底改了哪些文件、跑了哪些命令一目了然。如果你也在同时用多个 AI 编程 CLI我强烈建议花一个下午把类似openrig的骨架搭起来。它不会让你的模型变聪明但会让你的工作流变得干净、可预测、可迁移——而这三样东西恰恰是长期高频使用 AI 工具时最容易被忽视、又最影响体验的部分。
阅读完成 · 觉得有帮助?