1. openrig 到底是个什么东西
第一次看到 openrig 这个名字,很多人会以为是某个硬件外设或者机械臂项目,毕竟 rig 这个词在工程领域通常指“装配、支架、机架”。但结合 claude code、codex、yaml、node.js 这几个热搜词一起看,方向就很清楚了:这是一个围绕 AI 编程助手做本地配置编排的工具,核心工作是把 Claude Code、Codex 这类命令行 AI 编码代理的接入参数、模型端点、代理转发规则统一用 YAML 描述出来,再由 Node.js 运行时去加载和执行。
说白了,openrig 解决的是一个很具体的痛点。现在用 AI 编程助手的人越来越多,但每个人手里的模型来源五花八门:有人用官方订阅,有人接第三方兼容端点,有人本地跑 LM Studio 或者 Ollama,还有人要在 DeepSeek、Qwen、GLM 之间来回切换。每换一次模型,就要改一次环境变量、改一次配置文件、重启一次终端,时间全耗在配置上了。openrig 的思路就是把这些零散的配置收敛到一个 YAML 文件里,用一套结构化的 schema 管理多个 provider、多个模型、多个 profile,切换的时候只改一行引用就行。
它适合谁?三类人最需要。第一类是同时用 Claude Code 和 Codex 的开发者,两边配置格式不一样,来回切换很烦;第二类是在公司内网或者受限网络环境下工作的人,需要把请求指向自建网关或者本地模型服务;第三类是喜欢折腾、想把 AI 编码工具链做成可版本化管理的人,配置进 Git,换电脑一键还原。如果你只是偶尔用一下网页版对话,那 openrig 对你意义不大;但如果你每天有大量时间泡在终端里让 AI 帮你写代码、改 bug、跑测试,那这套东西值得花半小时搭起来。
需要先说明一点:openrig 目前并不是一个官方统一发布的标准工具,社区里存在多个同名或近似的实现,有的叫 openrig,有的叫 cc-rig、codex-rig。它们的设计思路高度相似,都是“YAML 描述 + Node.js 执行 + 多 provider 适配”。下面我讲的这套方案,是基于这类工具最常见的实践形态来展开的,具体字段名可能和你手上的版本有出入,但核心逻辑是通用的。
2. 整体设计思路与方案选型
2.1 为什么用 YAML 而不是 JSON 或 TOML
配置格式的选择看着是小事,实际影响很大。JSON 的问题是没法写注释,你过两个月回来看"base_url": "http://127.0.0.1:1234/v1"这行,根本想不起来这个端口对应的是哪个本地服务。TOML 表达嵌套结构比较别扭,尤其是当你要描述“多个 provider,每个 provider 下有多个 model,每个 model 又有自己的参数覆盖”这种三层结构时,TOML 的[provider.model.param]写法会变得很长很啰嗦。
YAML 的优势在于三点。第一是支持注释,这对配置文件来说是刚需,你可以在每个 provider 旁边写清楚“这是公司网关,仅内网可用”“这是本地 LM Studio,需要先启动服务”。第二是缩进表达层级,三层嵌套读起来依然清晰。第三是它对多行字符串友好,写系统提示词、写自定义 header 的时候不用转义换行符。
当然 YAML 也有坑,最大的坑就是缩进必须用空格不能用 Tab,而且缩进层级错了不会报错,只会静默解析成别的结构。这个后面排查章节会详细讲。
2.2 为什么用 Node.js 做运行时
Claude Code 和 Codex 本身都是 Node.js 生态里的 CLI 工具,通过 npm 全局安装。openrig 选择 Node.js 作为运行时,最大的好处是零额外依赖——你机器上为了跑 AI 助手本来就已经装了 Node,不需要再装 Python 或者 Go。其次 Node.js 的child_process模块可以很方便地 spawn 子进程,把配置注入环境变量后启动 claude 或 codex 命令,进程管理很自然。
另外一个考虑是跨平台。Node.js 在 Windows、macOS、Linux 上的行为基本一致,路径处理用path模块、环境变量用process.env,写一套逻辑三个平台都能跑。相比之下如果用 shell 脚本写,Windows 上就得再维护一套 PowerShell 版本,维护成本翻倍。
2.3 多 provider 抽象层的设计
openrig 最核心的设计是 provider 抽象。不管你是官方端点、第三方兼容服务、本地模型,在配置里都统一成一个 provider 对象,包含base_url、api_key、model这几个必备字段,再加上可选的headers、timeout、max_tokens等覆盖项。
这样做的好处是,Claude Code 和 Codex 虽然底层协议不同(一个走 Anthropic 的 messages 格式,一个走 OpenAI 的 responses 格式),但在 openrig 这一层可以统一描述。启动的时候,openrig 根据目标工具类型,把统一的 provider 配置翻译成对应工具认识的环境变量。比如给 Claude Code 就设置ANTHROPIC_BASE_URL和ANTHROPIC_API_KEY,给 Codex 就设置OPENAI_BASE_URL和OPENAI_API_KEY。
这个翻译层是整个工具的价值所在。没有它,你就得记住两套完全不同的环境变量命名规则,还得记住哪些工具读哪个变量。有了它,你只关心“我要用哪个 provider”,剩下的映射交给 openrig。
2.4 profile 机制解决切换问题
provider 解决了“连哪里”的问题,profile 解决的是“用哪套组合”的问题。一个 profile 可以理解为一份预设:用哪个 provider、用哪个模型、带哪些额外参数、注入哪些环境变量。
举个实际场景。我白天在公司用内网网关,晚上回家用本地 LM Studio,周末偶尔切到第三方兼容服务测新模型。这三个场景就是三个 profile:work、local、cloud。切换的时候只需要openrig use local,然后正常启动 claude 或 codex 就行,不用手动改任何环境变量。
profile 还支持继承。比如work-fast和work-quality都继承自work,只是覆盖了 model 字段。这样公共配置只写一份,差异部分单独声明,维护起来清爽很多。
3. 核心配置细节与实操要点
3.1 目录结构与文件布局
openrig 的配置默认放在用户主目录下的.openrig文件夹里,结构大概是这样:
~/.openrig/ ├── config.yaml # 主配置,定义 provider 和 profile ├── profiles/ # 可选,profile 拆分文件 │ ├── work.yaml │ └── local.yaml └── logs/ # 运行日志 └── openrig.log主配置和拆分文件的关系是:主配置里可以用include引入 profiles 目录下的文件,也可以全部写在一个 config.yaml 里。我个人的习惯是 provider 定义写在主配置,因为 provider 数量相对固定;profile 按场景拆成独立文件,因为场景会经常增删。
提示:
.openrig目录建议加入版本控制,但logs目录要加进.gitignore。config.yaml 里如果写了 api_key,要么用环境变量引用,要么确保仓库是私有的。
3.2 provider 字段详解
一个典型的 provider 定义长这样:
providers: local-lmstudio: type: openai-compatible base_url: http://127.0.0.1:1234/v1 api_key: ${LMSTUDIO_KEY:-not-needed} model: qwen2.5-coder-7b-instruct timeout: 120000 headers: X-Custom-Header: openrig逐字段说明。type决定协议适配器,常见值有anthropic、openai-compatible、openai-responses。base_url是端点根地址,注意本地服务通常要带/v1后缀,而有些网关不带,这个要看你实际服务的文档。api_key支持${VAR}语法引用环境变量,:-后面是默认值,本地服务不需要鉴权的时候写not-needed占位就行。
model是默认模型名,profile 里可以覆盖。timeout单位是毫秒,本地小模型推理慢,建议给到 120000 也就是两分钟,云端服务 30000 就够了。headers是自定义请求头,有些网关需要额外的鉴权头或者路由头,在这里加。
注意:
base_url结尾不要多加斜杠。http://127.0.0.1:1234/v1和http://127.0.0.1:1234/v1/在部分实现里会被拼成//v1//chat/completions,导致 404。这个坑我踩过不止一次。
3.3 profile 字段详解
profile 定义示例:
profiles: local: provider: local-lmstudio model: qwen2.5-coder-7b-instruct env: OPENRIG_PROFILE: local args: - --max-tokens - "8192" work: provider: company-gateway model: gpt-5.6-sol env: NO_PROXY: "127.0.0.1,localhost"provider字段引用上面定义的 provider 名。model覆盖 provider 的默认模型。env是额外注入的环境变量,比如有些工具需要NO_PROXY来跳过本地地址。args是透传给 CLI 的额外参数,注意这里要用字符串形式,数字也要加引号,否则 YAML 会解析成数字类型,某些 CLI 会报参数类型错误。
profile 继承写法:
profiles: work: provider: company-gateway model: gpt-5.6-sol work-fast: extends: work model: gpt-5.6-sol-miniextends指向父 profile,子 profile 只需声明差异字段。解析的时候 openrig 会做深合并,env和headers这类字典是合并而不是替换,这点设计得比较合理。
3.4 环境变量注入的时机
这是整个流程里最容易出问题的地方。openrig 注入环境变量的时机是在 spawn 子进程之前,通过child_process.spawn的env选项传入。这意味着两件事。
第一,注入的环境变量只对 openrig 启动的那个子进程生效,不会污染你当前 shell 的环境。你在这个终端里手动敲echo $ANTHROPIC_BASE_URL是看不到的,这是正常的,不要以为没生效。
第二,如果 Claude Code 或 Codex 内部又 spawn 了子进程(比如调用 git、调用测试命令),这些孙进程会继承环境变量。所以如果你在 profile 里设置了NO_PROXY,它会影响 AI 助手执行的所有命令,这个要心里有数。
实操心得:想验证环境变量到底注入了没有,可以在 profile 的 args 里临时加一个打印环境变量的命令,或者直接看 openrig 的 debug 日志。日志里会记录实际 spawn 的完整命令和环境变量快照,排查问题全靠它。
4. 完整实操流程与关键环节
4.1 环境准备:Node.js 安装与版本选择
openrig 要求 Node.js 18 以上,推荐 20 LTS 或 22 LTS。安装方式按平台分。
Windows 用户直接去 Node.js 官网下载 LTS 版本的 msi 安装包,一路下一步就行。安装完打开 PowerShell 敲node -v,能输出版本号就成功了。注意不要用太新的奇数版本,比如 23.x,有些原生模块还没适配,容易出NODE_MODULE_VERSION不匹配的报错。
macOS 用户推荐用 nvm 管理版本:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash source ~/.zshrc nvm install 20 nvm use 20Ubuntu 用户同样推荐 nvm,不要用apt install nodejs,系统源里的版本通常太老。如果遇到error installing 24.21.0: node.js v24.21.0 is not yet released这类报错,说明你指定的版本号不存在,去 Node.js 官网确认一下当前 LTS 的实际版本号。
装完 Node 之后,npm 会一起装上。国内网络环境下建议配一下镜像源加速:
npm config set registry https://registry.npmmirror.com4.2 安装 Claude Code 和 Codex
两个工具都是 npm 全局包:
npm install -g @anthropic-ai/claude-code npm install -g @openai/codex安装完分别敲claude --version和codex --version验证。如果提示命令找不到,检查 npm 全局 bin 目录有没有加到 PATH 里。用 nvm 的话一般自动配好了,用系统包管理器装的可能要手动加。
注意:Claude Code 和 Codex 的包名会随版本更新变化,如果上面命令报 404,去官方文档确认最新的包名。安装过程中如果卡在 postinstall 脚本,多半是网络问题,配好镜像源重试。
4.3 安装 openrig 本体
假设 openrig 以 npm 包形式分发:
npm install -g openrig openrig initopenrig init会在~/.openrig下生成一份带注释的示例配置,里面预置了几个常见 provider 模板。第一次跑的时候它会检测你机器上装了哪些 AI 助手,自动生成对应的 profile 骨架。
如果 openrig 是以源码形式分发的,流程是:
git clone <repo-url> openrig cd openrig npm install npm linknpm link会把当前目录链接到全局 bin,这样你就能在任何地方敲openrig命令了。开发模式下改代码不用重新安装,改完直接生效。
4.4 配置第一个 provider
打开~/.openrig/config.yaml,先配一个本地 LM Studio 的 provider 做测试,因为本地服务不依赖外部网络,排查问题最简单。
providers: local-lmstudio: type: openai-compatible base_url: http://127.0.0.1:1234/v1 api_key: not-needed model: qwen2.5-coder-7b-instruct timeout: 120000启动 LM Studio,加载一个模型,确认服务在 1234 端口监听。然后配 profile:
profiles: local: provider: local-lmstudio保存后执行:
openrig use local openrig doctoropenrig doctor是自检命令,它会依次检查:配置文件语法、provider 连通性、目标 CLI 是否安装、环境变量映射是否正确。这一步能过,基本就成功了一大半。
4.5 启动与验证
自检通过后,用 openrig 启动 Claude Code:
openrig run claude或者启动 Codex:
openrig run codexopenrig 会读取当前激活的 profile,翻译成对应工具的环境变量,然后 spawn 子进程。你看到的界面和直接敲claude是一样的,但底层已经连到你配置的 provider 了。
验证是否真的走了自定义端点,最简单的办法是看 LM Studio 的日志窗口,有没有收到请求。如果 LM Studio 那边有请求进来,说明链路通了。如果 Claude Code 报错说连不上,先看 openrig 的 debug 日志,里面会打印实际使用的 base_url。
4.6 多 provider 切换实战
配好本地之后,再加一个云端 provider:
providers: cloud-gateway: type: openai-compatible base_url: https://your-gateway.example.com/v1 api_key: ${CLOUD_API_KEY} model: gpt-5.6-sol timeout: 60000 profiles: cloud: provider: cloud-gateway cloud-fast: extends: cloud model: gpt-5.6-sol-miniCLOUD_API_KEY通过环境变量传入,不要硬编码在配置文件里。在 shell 的 rc 文件里加一行export CLOUD_API_KEY=xxx,或者用系统的密钥管理工具。
切换的时候:
openrig use cloud openrig run claude想切回来:
openrig use local openrig run claudeopenrig use会把当前 profile 名写到一个状态文件里,下次openrig run自动读取。也可以用openrig run --profile cloud claude临时指定,不改变全局状态。
5. 常见问题与排查技巧实录
5.1 YAML 解析类问题
YAML 最坑的地方是缩进错误不报错。比如你把model字段多缩进了一级,它可能被解析成上一个字段的子属性,而不是报语法错误。表现就是配置看起来没问题,但启动后模型名是空的。
排查方法:用openrig config show打印解析后的最终配置,对比你写的 YAML,看结构对不对。或者用在线 YAML 校验工具先过一遍。
另一个常见问题是特殊字符。api_key里如果有:或者#,必须加引号,否则会被当成键值分隔符或者注释起始符。稳妥做法是所有字符串值都加双引号。
5.2 连接类问题速查表
| 现象 | 可能原因 | 排查动作 |
|---|---|---|
| 连接被拒绝 | 本地服务没启动 | 检查 LM Studio 是否在运行,端口是否一致 |
| 404 Not Found | base_url 路径错误 | 确认是否要带 /v1,结尾不要多斜杠 |
| 401 Unauthorized | api_key 未注入 | 检查环境变量是否 export,${VAR}语法是否正确 |
| 超时 | timeout 太短或模型太慢 | 本地模型调到 120000,云端 30000 |
| 模型不存在 | model 名拼写错误 | 用服务端的模型列表接口确认准确名称 |
| 请求发到了官方端点 | 环境变量没生效 | 看 openrig debug 日志里的 env 快照 |
5.3 Claude Code 特有的坑
Claude Code 对ANTHROPIC_BASE_URL的处理有个细节:它会在 base_url 后面自动拼/v1/messages。所以你的 base_url 应该写到域名或者网关根路径,不要自己带/v1。这点和 Codex 不一样,Codex 是拼/v1/responses,base_url 通常要带/v1。openrig 的适配层会根据工具类型自动处理这个差异,但如果你手动改环境变量,一定要记住这个区别。
还有一个报错your organization has disabled claude subscription access for claude code,这个和 openrig 无关,是账号层面的订阅权限问题,需要去账号设置里确认订阅状态。
5.4 Codex 特有的坑
Codex 报the 'gpt-5.6-sol' model is not supported when using codex with a...这类错误,通常是模型名和 Codex 的协议不匹配。Codex 走的是 responses 格式,不是所有兼容 OpenAI 的服务都实现了这个格式。遇到这种情况,要么换一个支持 responses 格式的 provider,要么在 openrig 里把 type 改成openai-compatible让它走 chat completions 格式做转换。
Codex 还有个无法加载组织设置的报错,一般是登录态问题。先codex logout再codex login重新走一遍认证流程。
5.5 环境变量污染问题
前面提过,openrig 注入的环境变量会被 AI 助手 spawn 的所有子进程继承。如果你在 profile 里设置了HTTP_PROXY之类的变量,AI 助手执行npm install的时候也会走这个代理,可能导致内网包拉不下来。
解决办法是在 profile 的 env 里显式设置NO_PROXY,把本地地址和内网域名排除掉:
env: NO_PROXY: "127.0.0.1,localhost,.internal.example.com"实操心得:我习惯给每个 profile 都加一个
OPENRIG_PROFILE环境变量,值就是 profile 名。这样在 AI 助手执行的脚本里可以通过这个变量判断当前处于哪个环境,做一些条件逻辑。这个技巧在写自动化脚本的时候特别有用。
5.6 日志与调试
openrig 的日志默认在~/.openrig/logs/openrig.log。想看实时日志:
tail -f ~/.openrig/logs/openrig.log日志级别可以在配置里调:
log_level: debugdebug 级别会打印完整的 spawn 命令、环境变量快照、provider 解析结果。排查问题的时候先开 debug,问题定位了再调回 info,不然日志文件涨得很快。
如果日志里看不到有用信息,可以在启动命令前加DEBUG=openrig:*:
DEBUG=openrig:* openrig run claude这会把调试信息直接打到终端,比翻日志文件快。
6. 进阶玩法与扩展思路
6.1 配置进 Git 做版本管理
把~/.openrig/config.yaml和profiles/目录纳入 Git 管理,换电脑的时候 clone 下来就能用。api_key 这类敏感信息用环境变量引用,不写进文件。可以建一个config.example.yaml作为模板提交,实际的config.yaml加进.gitignore。
团队协作的时候,可以把公共的 provider 定义放在一个共享仓库里,每个人用自己的 profile 覆盖个人偏好。openrig 的include机制支持从多个路径加载配置,合并顺序按声明顺序来,后面的覆盖前面的。
6.2 结合本地模型做离线开发
本地跑 LM Studio 或者 Ollama 的最大好处是断网也能用,而且数据不出本机。对于处理敏感代码的场景,这个价值很大。openrig 的 provider 抽象让本地模型和云端模型在使用体验上完全一致,切换只需要改一行 profile 引用。
本地模型的选型上,代码场景推荐 Qwen2.5-Coder 系列或者 DeepSeek-Coder 系列,7B 起步,有条件上 14B 或 32B。显存不够的话用 4bit 量化版本,质量损失在可接受范围内。
6.3 多模型并行对比
openrig 支持同时配多个 provider,你可以开两个终端,一个跑openrig run --profile local claude,另一个跑openrig run --profile cloud claude,同一个问题分别问本地模型和云端模型,对比输出质量。这个用法在评估“本地模型够不够用”的时候特别直观。
6.4 自动化脚本集成
openrig 的命令行接口设计得比较适合脚本调用。比如你想在 CI 里跑 AI 代码审查,可以这样写:
openrig use ci-profile openrig run claude -- --print "review the diff in this PR" > review.txt--后面的参数会透传给 Claude Code。这样就能把 AI 审查集成到流水线里,每次 PR 自动跑一遍。
注意:CI 环境里没有交互式终端,Claude Code 和 Codex 的某些功能可能受限。建议在 CI 里只用非交互模式,并且设置合理的超时,避免流水线卡死。
6.5 配置校验与 schema
openrig 支持 JSON Schema 校验配置文件。在 config.yaml 顶部加一行:
# yaml-language-server: $schema=https://example.com/openrig-schema.json这样在 VS Code 里编辑的时候会有自动补全和错误提示,能提前发现字段名拼写错误、类型不匹配等问题。schema 文件地址以你实际使用的 openrig 版本为准。
7. 我踩过的几个坑和对应解法
第一个坑是 YAML 的 Tab 缩进。我用 VS Code 编辑的时候,有时候不小心按了 Tab,文件看起来对齐了,但解析出来结构全乱。后来在 VS Code 设置里把editor.insertSpaces设为 true,editor.tabSize设为 2,并且打开renderWhitespace,让空格和 Tab 可视化,这个问题就再没出现过。
第二个坑是环境变量默认值的语法。${VAR:-default}这个写法在 shell 里很常见,但 openrig 的解析器不一定完全兼容。我遇到过:-后面的默认值带空格导致解析失败的情况。稳妥做法是默认值不要带空格,或者干脆不用默认值,确保变量一定被设置。
第三个坑是 profile 继承的合并顺序。我一开始以为子 profile 的env会完全替换父 profile 的env,结果发现是深合并。这导致我父 profile 里设的一个环境变量一直生效,覆盖不掉。后来改成在子 profile 里把那个变量显式设为空字符串才解决。用继承的时候一定要清楚合并规则。
第四个坑是本地模型的超时。我一开始按云端习惯设了 30 秒,结果本地 7B 模型处理长上下文的时候经常超时。后来统一改成 120 秒,并且把max_tokens调小到 4096,稳定性好了很多。本地模型的能力边界要心里有数,不要指望它处理超长文件。
第五个坑是端口冲突。LM Studio 默认 1234,Ollama 默认 11434,有时候两个都开着,配置里写错了端口,请求发到了另一个服务上,返回的模型列表对不上,排查了半天。现在我的习惯是每个本地服务用固定端口,并且在 provider 的注释里写清楚端口对应哪个服务。
这套东西搭起来之后,我每天的工作流变成了:早上到公司openrig use work,晚上回家openrig use local,周末测新模型openrig use cloud。配置全部在 Git 里,换电脑五分钟还原。如果你也在多个模型和多个工具之间来回切换,花点时间把 openrig 配起来,长期看省下的时间很可观。