openrig:统一编排Claude Code与Codex的AI编程工具机架

发布时间:2026/10/4 8:04:05
openrig:统一编排Claude Code与Codex的AI编程工具机架 1. 从“openrig”这个名字说起它到底想解决什么问题第一次看到“openrig”这个词我脑子里蹦出来的画面是矿机机架、服务器机柜或者某种硬件测试台。但结合热搜词里那一串 Claude Code、Codex、YAML、Node.js 来看这明显不是一个硬件项目而是一个围绕 AI 编程助手做“装备架”的工具——把 Claude Code、Codex 这类命令行 AI 编程工具以及它们背后要接的各种模型服务统一编排、统一配置、统一管理。说白了openrig要干的事情就是给 AI 编程工具搭一个“开放式的机架”。你手里可能同时有 Claude Code、Codex CLI可能还想接本地模型、接第三方 API配置散落在各个角落环境变量、YAML 文件、代理设置、模型名映射改一处忘一处。openrig的思路就是把这些东西收拢到一个可维护的结构里让你换模型、换工具、换机器的时候不用从头再折腾一遍。我为什么对这个方向感兴趣因为过去大半年我自己的开发机上就同时装着 Claude Code 和 Codex还接过本地跑的模型做对比测试。每次换一台机器光是让这些工具正常跑起来就要花掉小半天。openrig这类项目瞄准的正是这个痛点配置即代码工具即插件模型即资源。这篇文章适合谁看如果你是那种“工具装了一堆、配置全靠记忆、换机就重来”的开发者或者你正在研究怎么把 Claude Code、Codex 这类 CLI 工具接入自己的模型服务那这篇内容会对你有用。我会从整体设计思路讲到具体落地包括 YAML 怎么写、Node.js 环境怎么搭、常见报错怎么排查尽量让你看完就能动手。需要先说明一点openrig这个标题本身信息量有限下面涉及的具体目录结构、配置字段、命令名称有一部分是基于这类工具常见实践的合理推演我会在关键处标注清楚哪些是通用做法、哪些需要你按自己项目的实际文档去核对。核心逻辑和踩坑经验是通用的换任何同类工具都适用。2. 整体设计思路为什么是“机架”而不是“脚本”2.1 从散装脚本到统一编排的必然性大部分人接触 Claude Code 或 Codex 的路径都差不多先照着教程装 Node.js然后npm install -g装 CLI接着配环境变量把 API Key 塞进去跑起来发现模型名不对再改配置。单个工具这么搞没问题但当你同时用两三个工具、还要在本地模型和云端模型之间切换时问题就来了。我踩过最典型的一个坑Claude Code 和 Codex 对“模型标识”的写法要求不一样。同一个模型服务在 A 工具里叫一个名字在 B 工具里要换另一种写法甚至同一个工具在不同版本里字段名都变过。你如果靠手改配置文件改着改着就乱了最后自己也说不清哪个文件对应哪个工具。openrig这类项目的设计哲学本质上是把“工具”“模型”“凭据”“运行参数”这四样东西解耦工具层Claude Code、Codex 各自是一个可执行入口互不干扰。模型层模型服务本地或远端作为独立资源注册带自己的地址、密钥、模型名。绑定层通过 YAML 描述“哪个工具用哪个模型、带什么参数”。运行层一条命令拉起指定组合环境变量在运行时注入不污染全局。这么设计的好处很直接换模型不用动工具配置换工具不用重配模型加一个新工具只是多写一段 YAML。这就是“机架”的含义——工具插上去就能用拔下来不影响别的。2.2 为什么选 YAML 作为配置载体热搜词里“yaml文件”“yolov10 yaml文件怎么创建”“rstudio的yaml在哪里”这些词扎堆出现说明 YAML 是很多人又爱又恨的东西。openrig选 YAML 而不是 JSON 或 TOML我认为有几个现实理由。第一YAML 支持注释。配置文件里写一句# 这个模型用于日常补全别删三个月后你自己看得懂。JSON 不支持注释TOML 虽然支持但嵌套结构写起来啰嗦。第二YAML 对多行字符串和嵌套列表的表达更自然。模型配置里经常要写系统提示词、额外的请求头这些用 YAML 的块标量写起来很清爽。第三生态惯性。Claude Code、Codex 以及大量 CI/CD 工具都用 YAML用户不需要再学一套语法。但 YAML 的坑也是真多后面我会专门用一节讲缩进、类型推断、锚点引用这些容易翻车的地方。这里先记住一个原则YAML 里所有字符串能加引号就加引号尤其是版本号、模型名这种看起来像数字或布尔值的东西不加引号迟早出事。2.3 Node.js 在这套体系里的角色openrig相关的工具链几乎都跑在 Node.js 上Claude Code 和 Codex 的 CLI 都是 Node 包。所以 Node.js 不是可选项是地基。热搜里“node.js安装”“node.js官网下载”“node.js lts下载”“安装node.js”反复出现说明环境搭建是新手第一道坎。我的建议很明确用 LTS 版本别追最新版。热搜里有一条error installing 24.21.0: node.js v24.21.0 is not yet released or is not ava这就是典型的版本号写错或者源里没有对应版本导致的。Node.js 的版本管理我强烈推荐用nvmNode Version Manager而不是直接装系统级 Node。原因很简单不同项目对 Node 版本要求不同系统级只能有一个版本nvm 可以随时切换。# 安装 nvm以常见 shell 为例 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash # 重新加载 shell 配置后安装并使用 LTS nvm install --lts nvm use --lts node -v npm -v装完之后node -v能打印出版本号说明地基打好了。这一步看着简单但后面 Claude Code 装不上、Codex 报错十有八九是 Node 版本或 npm 全局路径的问题。3. 核心细节解析配置结构、字段含义与实操要点3.1 一份典型的 openrig 配置长什么样基于这类工具的通用设计openrig的配置大概率是一个主 YAML 文件里面分几个顶层区块。我按最常见的结构给你拆一遍你对照自己项目的实际字段调整。# openrig.yaml version: 1 # 模型服务注册区 providers: local-llm: type: openai-compatible base_url: http://127.0.0.1:1234/v1 api_key: not-needed models: - qwen2.5-coder-7b - deepseek-coder-v2 cloud-api: type: openai-compatible base_url: https://api.example.com/v1 api_key: ${CLOUD_API_KEY} models: - gpt-5.6-sol # 工具定义区 tools: claude-code: command: claude provider: cloud-api model: gpt-5.6-sol env: ANTHROPIC_BASE_URL: ${provider.base_url} ANTHROPIC_API_KEY: ${provider.api_key} codex: command: codex provider: local-llm model: qwen2.5-coder-7b env: OPENAI_BASE_URL: ${provider.base_url} OPENAI_API_KEY: ${provider.api_key}这份配置里几个关键点值得展开说。version字段是给配置格式做版本管理的。工具升级后配置结构可能变有版本号就能做兼容或迁移提示。别小看这个字段很多项目后期加迁移逻辑全靠它。providers区块把模型服务抽象成“提供者”每个提供者有类型、地址、密钥、可用模型列表。type: openai-compatible是现在最通用的约定因为大量本地推理服务和第三方服务都兼容 OpenAI 的接口格式。这意味着你只要有一个兼容接口就能接进来。${CLOUD_API_KEY}这种写法是环境变量插值。密钥绝对不能明文写在 YAML 里然后提交到仓库这是安全底线。运行时从环境变量读取YAML 里只留占位符。tools区块把 CLI 工具和 provider 绑定。注意env里的${provider.base_url}是引用上面 provider 的字段这样改一处地址所有引用它的工具都跟着变。这就是解耦的价值。3.2 模型名映射最容易翻车的地方热搜里有一条特别扎眼{detail:the gpt-5.6-sol model is not supported when using codex with a。这类报错的本质是模型名不匹配。工具发出去的模型名服务端不认识或者服务端认识的模型名和工具里写的不一样。我处理这个问题的经验是永远以服务端/v1/models接口返回的名称为准。你可以先用 curl 探一下curl -s http://127.0.0.1:1234/v1/models | python -m json.tool返回的data[].id才是真实可用的模型名。工具配置里写的名字必须和它完全一致大小写、连字符、版本后缀都不能差。如果服务端返回的名字和工具默认期望的不一样有两种解法。一种是在 provider 配置里做映射providers: local-llm: type: openai-compatible base_url: http://127.0.0.1:1234/v1 model_map: gpt-5.6-sol: qwen2.5-coder-7b另一种是直接在工具配置里写服务端认识的名字。前者适合多个工具共用一套映射后者适合临时调试。我个人倾向用映射因为工具侧的配置可以保持稳定换后端模型时只改映射表。注意模型名映射不要做“模糊匹配”或“前缀匹配”必须精确。我见过有人写了个通配规则结果请求被路由到错误的模型排查了半天才发现是映射规则太宽松。3.3 环境变量注入的时机与隔离openrig这类工具的核心动作之一是在启动子进程时注入环境变量。这里有个细节很多人忽略注入的时机和隔离范围。如果你在 shell 里export ANTHROPIC_API_KEYxxx那这个变量对当前 shell 所有子进程都可见。多个工具同时跑可能互相污染。openrig的做法应该是在 spawn 子进程时把计算好的环境变量作为env参数传进去而不是改全局环境。// 伪代码示意启动工具时注入独立环境 const { spawn } require(child_process); const childEnv { ...process.env, ...resolvedToolEnv, // 从 YAML 解析并插值后的变量 }; const child spawn(tool.command, args, { env: childEnv, stdio: inherit, });这样做的好处是每个工具进程有自己的一套变量互不干扰。你可以在同一个终端里一个窗口跑接本地模型的 Codex另一个窗口跑接云端模型的 Claude Code两边配置完全不同但不会打架。实操心得调试环境变量问题时在工具启动前打印一份脱敏后的childEnv确认关键变量base_url、api_key 的前几位、model符合预期。密钥只打印前 4 位和后 4 位中间用星号代替避免日志泄露。4. 实操过程从零把 openrig 跑起来4.1 环境准备与依赖安装假设你在一台干净的机器上从零开始。第一步是 Node.js前面说了用 nvm 装 LTS。装完之后验证node -v # 应输出 v20.x 或 v22.x 这类 LTS 版本 npm -v # 应输出对应 npm 版本第二步是拿到openrig本身。如果它是 npm 包安装方式大概是npm install -g openrig openrig --version如果它是源码仓库那就是 clone 下来、装依赖、linkgit clone repo-url openrig cd openrig npm install npm link # 让 openrig 命令全局可用这里有个常见坑npm install -g报权限错误。在 Linux 或 macOS 上如果你没配好 npm 全局目录会提示EACCES。解法是配置用户级全局目录而不是用 sudomkdir -p ~/.npm-global npm config set prefix ~/.npm-global # 然后把 ~/.npm-global/bin 加入 PATH export PATH~/.npm-global/bin:$PATHWindows 上则是另一套逻辑npm 全局包默认装在用户目录下一般不会有权限问题但要注意 PATH 是否包含 npm 的全局 bin 目录。4.2 编写第一份配置文件环境好了接下来写配置。我建议从最小可用配置开始别一上来就写全。先只配一个 provider、一个 tool跑通了再扩展。version: 1 providers: local: type: openai-compatible base_url: http://127.0.0.1:1234/v1 api_key: local models: - qwen2.5-coder-7b tools: codex: command: codex provider: local model: qwen2.5-coder-7b保存为openrig.yaml放在项目根目录或用户配置目录具体路径看项目文档常见的是~/.config/openrig/openrig.yaml。然后启动本地模型服务。这里假设你用的是一个兼容 OpenAI 接口的本地推理服务监听在 1234 端口。启动后先用 curl 确认接口通curl -s http://127.0.0.1:1234/v1/models能返回模型列表说明服务端没问题。接着用 openrig 拉起 codexopenrig run codex如果一切正常codex 会带着注入好的环境变量启动直接连上本地模型。4.3 参数计算与选择超时、重试、并发配置里除了地址和模型名还有一类参数容易被忽略但很关键超时、重试、并发。本地模型首次加载可能很慢如果工具默认超时是 30 秒第一次请求大概率超时失败。这时候需要在 provider 或 tool 层面调大超时providers: local: type: openai-compatible base_url: http://127.0.0.1:1234/v1 timeout_ms: 120000 # 2 分钟给模型加载留足时间 max_retries: 2超时时间怎么定我的经验是本地模型冷启动按 60 到 120 秒算热请求按 30 秒算。如果你不确定先设大一点跑通后再往下调。重试次数别设太多2 到 3 次足够设多了遇到持续故障会一直卡着。并发方面本地模型通常只有一个推理实例并发请求会排队。如果你同时开多个工具窗口建议在 provider 层面加一个并发上限避免把本地服务打爆providers: local: max_concurrency: 1这个值设成 1 意味着请求串行化虽然慢一点但稳定。云端 API 可以设高一些比如 4 到 8取决于你的配额。4.4 多工具切换的实操记录我实际测试的场景是这样的一个终端窗口跑 Claude Code 接云端模型写业务代码另一个窗口跑 Codex 接本地模型做代码审查。两份配置共用同一个openrig.yaml通过不同的 tool 定义区分。启动命令分别是openrig run claude-code openrig run codex两个进程各自拿到自己的环境变量互不干扰。我特意验证过在 Claude Code 窗口里改配置、重启不影响 Codex 窗口反过来也一样。这就是前面说的“进程级环境隔离”带来的好处。有一次我图省事直接在 shell 里 export 了云端 API 的 base_url结果本地 Codex 也读到了这个变量请求被发到云端去了。排查的时候看日志才发现工具读的是全局环境变量而不是 openrig 注入的。这个坑提醒我用 openrig 启动工具时确保 shell 里没有残留的同名环境变量否则可能覆盖注入值。可以在启动脚本里先 unset 相关变量或者用env -i开一个干净环境。5. 常见问题与排查技巧实录5.1 启动类问题速查表现象可能原因排查动作command not found: openrig全局 bin 目录不在 PATH检查 npm prefix 和 PATH 配置Cannot find module依赖没装全或 Node 版本不符重跑npm install确认 Node 为 LTS工具启动后立即退出配置解析失败或必填字段缺失加--verbose看详细日志连接被拒绝本地模型服务没启动或端口不对curl 测/v1/models401/403API Key 没注入或值错误打印脱敏后的环境变量核对模型不支持模型名与服务端不一致查/v1/models返回的真实名称这张表是我自己遇到问题后整理的基本覆盖了八成以上的启动故障。遇到问题先对号入座能省很多时间。5.2 YAML 解析报错的三类典型原因YAML 报错信息往往很模糊比如did not find expected key或者mapping values are not allowed here。我总结了三类最常见的原因。第一类是缩进问题。YAML 用空格缩进不能用 Tab。而且同一层级缩进必须完全一致。我见过有人从网页复制配置混进了 Tab 和全角空格肉眼看不出来解析器直接报错。解法是用编辑器的“显示空白字符”功能检查或者用yamllint过一遍。第二类是类型推断。YAML 会把yes、no、on、off、true、false当成布尔值把1.0当成浮点数。如果你写version: 1.0解析出来是数字 1.0不是字符串 1.0。模型名里如果有这类词必须加引号。第三类是特殊字符。冒号加空格:在 YAML 里是键值分隔符如果你的字符串里有这个组合必须加引号。比如model: gpt:4不加引号就会解析出错。# 错误示范 version: 1.0 model: gpt:4 enabled: yes # 正确示范 version: 1.0 model: gpt:4 enabled: yes提示写完 YAML 后用python -c import yaml,sys; yaml.safe_load(open(openrig.yaml))快速验证语法比等工具报错再排查快得多。5.3 模型连接失败的排查路径模型连不上是最高频的问题。我的排查路径是自底向上一层层确认。先确认网络层curl能不能通到 base_url。如果 curl 都不通那跟 openrig 没关系是服务本身或网络的问题。再确认接口层curl 通到/v1/models能不能返回列表。如果返回 404说明 base_url 路径不对可能少了或多了/v1。然后确认认证层带上 API Key 请求/v1/chat/completions看是否返回 401。如果 401说明密钥不对或没带上。最后确认模型层用真实模型名发一个最小请求看是否返回模型不存在的错误。curl -s http://127.0.0.1:1234/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer local \ -d {model:qwen2.5-coder-7b,messages:[{role:user,content:hi}]}这条命令能返回正常响应说明服务端完全没问题剩下的就是 openrig 配置的事。如果这条命令都失败那问题在服务端别在 openrig 上浪费时间。5.4 独家避坑技巧分享几个我从实际折腾中总结的、文档里不会写的技巧。技巧一配置分层敏感信息单独放。把openrig.yaml提交到仓库但密钥放在openrig.local.yaml或环境变量里用.gitignore排除本地文件。这样团队协作时配置结构共享密钥各自管理。技巧二给每个工具单独开日志文件。多工具同时跑的时候日志混在一起根本没法看。在 tool 配置里加log_file字段把每个工具的 stdout/stderr 重定向到独立文件排查问题时直接看对应文件。技巧三用--dry-run先看解析结果。如果 openrig 支持 dry-run启动前先跑一次把最终解析出的环境变量、命令、参数打印出来。确认无误再真正启动。这个习惯帮我避免了很多“启动了才发现配置错”的情况。技巧四版本锁定。Node 版本、openrig 版本、工具版本都记在文档里。我遇到过升级 Node 大版本后某个工具的原生依赖编译失败的情况。锁定版本升级前先在测试环境验证。技巧五本地模型先预热。本地模型冷启动慢可以在 openrig 启动前先发一个预热请求把模型加载进显存。这样工具第一次请求就不会超时。# 预热请求 curl -s http://127.0.0.1:1234/v1/chat/completions \ -H Content-Type: application/json \ -d {model:qwen2.5-coder-7b,messages:[{role:user,content:warmup}],max_tokens:1} /dev/null这个预热请求只生成 1 个 token很快返回但足以触发模型加载。之后再用 openrig 启动工具体验会顺畅很多。6. 扩展玩法把 openrig 用出更多花样6.1 多环境配置切换开发、测试、生产用不同的模型服务这是很常见的需求。openrig 的配置可以用“基础配置 环境覆盖”的方式组织# openrig.yaml基础 version: 1 providers: default: type: openai-compatible base_url: ${OPENRIG_BASE_URL} api_key: ${OPENRIG_API_KEY}然后通过环境变量切换# 开发环境 export OPENRIG_BASE_URLhttp://127.0.0.1:1234/v1 export OPENRIG_API_KEYlocal openrig run codex # 生产环境 export OPENRIG_BASE_URLhttps://api.example.com/v1 export OPENRIG_API_KEYsk-xxxx openrig run codex这样一份配置文件适配所有环境切换只改环境变量。配合 direnv 这类工具进入不同目录自动加载对应环境变量体验更丝滑。6.2 接入第三方 API 的注意事项热搜里“第三方api使用技巧”“codex接入deepseek”“claude code 调用lmstudio的本地模型”这些词说明大家很关心怎么接非官方服务。接第三方 API 有几个点要注意。接口兼容性。不是所有第三方服务都完整兼容 OpenAI 接口。有的缺/v1/models有的流式响应格式有差异有的不支持某些参数。接入前先用 curl 把常用接口测一遍确认兼容性。模型名差异。第三方服务的模型名往往和官方不一样必须用它们文档里给的名字。前面说的模型名映射在这里就派上用场了。速率限制。第三方 API 通常有更严格的速率限制配置里要把max_concurrency调低max_retries配合退避策略避免触发限流被封。计费与配额。接第三方 API 前确认计费方式有些按 token 计费有些按请求次数。配置里可以加一个用量统计心里有数。6.3 与编辑器集成的思路热搜里“vscode配置claude code”“vscode接入claude code”“claude code for vs code”出现多次说明很多人想在编辑器里用这些工具。openrig 作为命令行编排层和编辑器集成有两种思路。一种是编辑器调用 openrig 命令。比如 VS Code 的任务配置里把启动命令写成openrig run claude-code这样编辑器里触发任务时走的是 openrig 的配置。另一种是 openrig 生成编辑器需要的配置文件。比如根据 openrig.yaml 里的 provider 信息生成 VS Code 插件需要的 settings.json 片段。这样配置只有一份源头编辑器配置自动派生。两种思路各有适用场景。前者适合命令行重度用户后者适合编辑器重度用户。我个人的做法是前者因为命令行调试更方便编辑器只当编辑器用。7. 我个人的一些体会折腾 openrig 这类工具的过程中我最大的感受是配置管理的价值在工具数量超过一个之后才真正显现。只有一个工具的时候手改配置最快有两个以上工具、还要频繁切换模型的时候没有统一编排就是灾难。另一个体会是关于“抽象层次”的把握。openrig 把 provider、tool、binding 分层这个抽象层次我觉得刚刚好。再往上抽象比如搞一套图形界面反而增加了维护成本再往下比如直接写 shell 脚本又回到了散装状态。YAML 加命令行这个组合对开发者来说学习成本低、可控性强。最后分享一个小习惯我会给每个配置变更写一行注释记录“为什么改”。比如# 2024-06 本地模型换成 qwen2.5因为 deepseek 在这个任务上不稳定。三个月后回头看这行注释比配置本身还有价值。配置会过时但决策的上下文不会。