1. 从 openrig 这个标题说起:它到底想解决什么问题
第一次看到 openrig 这个词,我脑子里蹦出来的第一反应是“open + rig”,也就是“开放式的设备/工具架”。结合热搜词里那一长串 Claude Code、Codex、YAML、Node.js,基本可以判断:openrig 不是一个单纯的软件包,而更像是一套把本地 AI 编码工具(Claude Code、Codex 这类 CLI Agent)统一编排、统一配置的“脚手架”或者“控制台”。它要解决的核心痛点非常具体——现在每个人电脑上可能同时装了 Claude Code、Codex CLI,甚至还想接本地模型(比如通过 LM Studio 跑本地推理),但每个工具的配置格式、启动方式、模型切换逻辑都不一样,YAML 文件散落各处,Node.js 版本还经常打架。openrig 想做的,就是把这些零散的东西收拢到一个统一的 rig(装备架)上。
我自己的实际场景是这样的:主力用 Claude Code 写业务代码,偶尔用 Codex 处理一些需要长上下文推理的任务,本地还挂着一个 LM Studio 跑的小模型做隐私敏感的小活儿。三套工具三套配置,每次换模型都要改环境变量、改 YAML、重启终端,烦得要命。openrig 这类工具的价值就在于把这些重复劳动抽象掉,用一份声明式的配置描述“我要用哪个模型、走哪个端点、用哪个 CLI”,剩下的交给它去编排。所以这篇文章我不会只讲概念,而是把 openrig 背后涉及的核心技术点——Node.js 运行时、YAML 配置、Claude Code 与 Codex 的接入方式、本地模型端点——全部拆开讲透,让你看完能自己搭一套出来。
适合谁看?如果你已经在用 Claude Code 或者 Codex,但被多工具配置搞得头大;如果你想在 VS Code 里统一管理这些 CLI Agent;如果你想把本地模型也纳入同一套工作流,那这篇就是写给你的。哪怕你只是刚听说 Claude Code 想入门,我也会把安装、配置、踩坑的细节讲清楚,保证不同基础的人都能抄作业。
2. 整体设计思路:为什么是 Node.js + YAML 这套组合
2.1 为什么这类工具几乎都选 Node.js 作为运行时
先说一个很多人忽略的事实:Claude Code 和 Codex CLI 本身都是基于 Node.js 生态分发的。你去看它们的安装方式,基本都是npm install -g或者通过 npx 直接跑。这不是巧合,而是因为 Node.js 在“跨平台 CLI 工具分发”这件事上有天然优势——一套 JavaScript 代码,Windows、macOS、Linux 都能跑,npm 生态又能把依赖管理得明明白白。openrig 如果要做统一编排,最省事的选择就是站在 Node.js 的肩膀上,直接复用这套分发和依赖机制。
但 Node.js 有个绕不开的坑:版本。热搜词里那条error installing 24.21.0: node.js v24.21.0 is not yet released or is not available就是活生生的例子。很多人装 Node.js 时随手apt install nodejs,结果装到的是系统源里那个老掉牙的版本,跑 Claude Code 直接报错。我的建议很明确:永远用 LTS 版本,并且用版本管理器而不是系统包管理器。具体怎么装我在第 3 节会给出完整命令。
2.2 YAML 为什么成了配置的事实标准
再看 YAML。热搜词里yaml安装、yaml文件、yolov10 yaml文件怎么创建这些词混在一起,说明很多人对 YAML 的认知还停留在“某个项目的配置文件格式”。但在 openrig 这类编排工具里,YAML 承担的是“声明式描述整个运行环境”的角色。为什么不用 JSON?因为 JSON 不能写注释,而配置文件里注释极其重要——你得告诉未来的自己“这行是干嘛的”。为什么不用 TOML?TOML 表达嵌套结构时比较啰嗦,而 openrig 要描述“多个工具、多个模型、多个端点”这种多层嵌套,YAML 的缩进式结构读起来更直观。
我举个实际对比。假设你要描述“Claude Code 用 A 模型走 B 端点,Codex 用 C 模型走 D 端点”,用 YAML 大概是这样:
tools: claude-code: model: claude-sonnet endpoint: http://localhost:1234/v1 codex: model: gpt-5.6-sol endpoint: https://api.example.com/v1同样的内容用 JSON 写,光是引号和花括号就能让你看花眼,而且没法加注释。这就是 YAML 在这类场景胜出的根本原因——它是给人读的,不是给机器读的。当然 YAML 也有坑,最大的坑就是缩进。YAML 用空格缩进表示层级,Tab 和空格混用会直接报错,而且报错信息往往指向一个莫名其妙的位置。我踩过最惨的一次是复制粘贴时混进了全角空格,排查了半小时。所以记住第一条铁律:YAML 文件里永远只用空格,永远不用 Tab,缩进统一用 2 个空格。
2.3 openrig 的编排逻辑:声明式优于命令式
理解了 Node.js 和 YAML 的角色,openrig 的整体设计思路就清晰了:用 YAML 声明“我想要什么状态”,用 Node.js 脚本去“达成这个状态”。这是典型的声明式设计,和命令式(一步步敲命令)相比,好处是配置可以版本化、可以复用、可以一键切换。比如你今天想用本地模型,明天想用云端模型,只需要改 YAML 里的一行,然后重新跑一次 openrig 的同步命令,不用手动去改每个工具的环境变量。
这种设计还有一个隐藏好处:可审计。当你的配置全部落在一个 YAML 文件里,你能一眼看出“我到底用了哪些模型、哪些端点”。这在排查问题时价值巨大。热搜词里cc switch local proxy failed while handling codex endpoint /responses这种报错,本质就是端点配置和实际请求路径对不上。如果配置是散落的,你根本不知道去哪找;如果集中在 YAML 里,直接看 endpoint 那一行就定位了。
3. 环境准备:Node.js 与 YAML 工具链的正确安装姿势
3.1 Node.js 安装:别再用系统包管理器了
我见过太多人卡在 Node.js 版本上。ubuntu安装node.js 20+、node.js安装、node.js lts下载这些热搜词背后,全是版本踩坑的血泪。系统自带的 apt 源里的 Node.js 版本通常落后好几个大版本,而 Claude Code、Codex 这些工具对 Node.js 版本有硬性要求(一般要求 18 以上,推荐 20 LTS 或更高)。
正确做法是用 nvm(Node Version Manager)。在 Ubuntu 上:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash source ~/.bashrc nvm install 20 nvm use 20 nvm alias default 20最后那行nvm alias default 20很关键,它保证你新开终端时默认用 20 版本,而不是每次都要手动nvm use。装完验证:
node -v # 应该输出 v20.x.x npm -vWindows 用户直接用 nvm-windows,或者去 Node.js 官网下载 LTS 安装包。这里要提醒一句:热搜词里那个node.js v24.21.0 is not yet released的报错,通常是因为你在某个配置文件里写死了一个不存在的版本号,或者 nvm 的镜像源没同步。解决办法是nvm ls-remote看一下实际可用的版本,别凭记忆写版本号。
注意:如果你之前用 apt 装过 Node.js,先
sudo apt remove nodejs npm卸干净,否则 nvm 和系统版本会打架,出现“明明 nvm 切了 20,node -v还是 12”的诡异现象。
3.2 YAML 工具链:校验比编写更重要
YAML 本身不需要“安装”,它是文本格式。但你需要一个能校验 YAML 的工具,否则写错了只能靠工具报错来猜。我推荐两个:
- yamllint:命令行校验,能查出缩进、重复键、语法错误。安装:
pip install yamllint,用法:yamllint config.yaml。 - VS Code 的 YAML 插件:实时高亮和错误提示,写的时候就能发现缩进问题。
为什么校验这么重要?因为 YAML 的容错性极差。一个缩进错误可能导致整个配置被解析成完全不同的结构,而工具报的错可能指向一个毫不相干的行号。我养成的习惯是:每次改完 YAML,先跑一遍 yamllint,再让 openrig 去加载。这样能把“配置语法错误”和“工具逻辑错误”分开排查,效率高很多。
3.3 Claude Code 与 Codex 的安装前置检查
在装 openrig 之前,建议先把 Claude Code 和 Codex 单独装好、单独跑通。原因很简单:如果单独都跑不起来,套上 openrig 只会让问题更难定位。Claude Code 的安装一般是:
npm install -g @anthropic-ai/claude-codeCodex 类似,通过 npm 全局安装。装完先跑一次claude --version和codex --version确认能执行。热搜词里claude code安装、codex安装教程、codex安装包这些需求,核心就是这一步。如果这一步报权限错误,Linux/macOS 下加sudo,或者更好的是配置 npm 的全局目录到用户目录下,避免权限问题:
npm config set prefix ~/.npm-global export PATH=~/.npm-global/bin:$PATH这样以后npm install -g就不需要 sudo 了,也避免了全局包权限混乱。
4. 核心配置解析:用 YAML 把 Claude Code、Codex 和本地模型串起来
4.1 openrig 配置文件的骨架长什么样
基于这类编排工具的常见实践,openrig 的配置文件(假设叫openrig.yaml)大致会包含几个顶层块:运行时配置、工具定义、模型端点、以及可选的代理/转发设置。我按最可能的结构给你搭一个骨架,你可以直接拿去改:
version: 1 runtime: node: "20" packageManager: npm endpoints: local-lmstudio: baseUrl: "http://localhost:1234/v1" apiKey: "not-needed" cloud-default: baseUrl: "https://api.example.com/v1" apiKey: "${CLOUD_API_KEY}" tools: claude-code: enabled: true endpoint: local-lmstudio model: "local-model-name" extraArgs: - "--verbose" codex: enabled: true endpoint: cloud-default model: "gpt-5.6-sol"这个骨架里几个设计点值得说清楚。第一,apiKey用${CLOUD_API_KEY}这种环境变量占位符,而不是明文写死。这是安全底线,配置文件很可能被提交到 Git,明文密钥泄露是灾难性的。第二,endpoints和tools分离,好处是多个工具可以复用同一个端点,改端点只改一处。第三,extraArgs允许你给每个工具传额外的命令行参数,保留了灵活性。
4.2 端点配置:本地模型和云端模型的差异处理
热搜词里claude code 调用lmstudio的本地模型、codex接入deepseek这些,本质都是“把工具的请求指向一个自定义端点”。这里有个关键技术点:不同工具对端点的路径拼接规则不一样。有的工具会在 baseUrl 后面自动加/chat/completions,有的加/responses,有的什么都不加。热搜词里那个cc switch local proxy failed while handling codex endpoint /responses的报错,就是路径拼接对不上导致的。
我的处理经验是:baseUrl 只写到/v1,不要带后面的具体路径,让工具自己去拼。如果工具拼错了,再通过 openrig 的代理层做路径重写。LM Studio 的本地端点默认是http://localhost:1234/v1,这个/v1必须保留,因为它是 OpenAI 兼容 API 的版本标识。如果你写成了http://localhost:1234,工具请求/v1/chat/completions时就会变成http://localhost:1234/v1/chat/completions——看起来对,但如果工具本身会补/v1,就变成/v1/v1/...了。所以配置完一定要用 curl 手动测一次:
curl http://localhost:1234/v1/models能返回模型列表,说明端点通了。这一步能省掉后面 80% 的“连不上”问题。
4.3 模型名称映射:为什么模型名写错会报“不支持”
热搜词里the 'gpt-5.6-sol' model is not supported when using codex这个报错,典型原因是模型名和端点实际提供的模型名不匹配。每个端点(不管是云端还是本地)都有自己的模型命名规则。LM Studio 里加载的模型名可能是qwen2.5-coder-7b-instruct,但你在配置里写了个qwen-coder,请求发过去端点不认识,就报“不支持”。
解决办法是:先用/v1/models接口列出端点实际支持的模型名,然后原样复制到配置里。别凭记忆写,别简写。我一般会在 YAML 里加一行注释记录这个模型名的来源:
tools: codex: model: "qwen2.5-coder-7b-instruct" # 来自 localhost:1234/v1/models这样下次换模型时,你知道去哪查正确的名字。
4.4 环境变量与密钥管理
前面提到用${VAR}占位符,这里展开讲。openrig 在加载 YAML 时,应该会把${VAR}替换成实际的环境变量值。所以你需要在一个不被提交的地方(比如~/.bashrc或者一个.env文件)设置这些变量:
export CLOUD_API_KEY="your-actual-key" export LOCAL_ENDPOINT="http://localhost:1234/v1"注意:
.env文件一定要加进.gitignore。我见过有人把带密钥的.env提交到公开仓库,结果密钥被扫走,账单直接爆掉。这种事一次就够记一辈子。
5. 实操全流程:从零跑通一套 openrig 编排
5.1 第一步:确认 Node.js 环境干净
node -v npm -v which nodewhich node的输出应该是 nvm 管理的路径(类似~/.nvm/versions/node/v20.x.x/bin/node),而不是/usr/bin/node。如果是后者,说明系统版本还在干扰,回去执行 3.1 的卸载步骤。
5.2 第二步:安装 openrig 与相关 CLI
假设 openrig 通过 npm 分发:
npm install -g openrig openrig --version同时确保 Claude Code 和 Codex 已装:
npm install -g @anthropic-ai/claude-code npm install -g @openai/codex装完分别验证版本。这一步如果报EACCES权限错误,说明 npm 全局目录还是系统目录,回去执行 3.3 的 prefix 配置。
5.3 第三步:编写并校验 openrig.yaml
把 4.1 的骨架复制到~/.openrig/openrig.yaml,按你的实际情况改端点和模型名。改完先校验:
yamllint ~/.openrig/openrig.yaml没有输出就是通过。有输出就按提示改缩进或语法。
5.4 第四步:启动本地模型端点(如果用本地模型)
打开 LM Studio,加载一个模型,启动本地服务器,默认端口 1234。然后:
curl http://localhost:1234/v1/models确认返回 JSON 里有你配置里写的模型名。如果没有,要么模型没加载,要么名字写错了。
5.5 第五步:让 openrig 同步配置并启动工具
openrig sync openrig run claude-codesync的作用是把 YAML 里的配置“翻译”成各个工具能识别的环境变量或配置文件。run则是带着这套配置启动指定工具。如果一切正常,Claude Code 应该会连到你配置的端点,用你指定的模型。
5.6 第六步:验证请求真的走对了端点
这一步很多人跳过,结果出了问题不知道是配置没生效还是端点本身有问题。验证方法:在 LM Studio 的日志窗口看有没有收到请求,或者用openrig run codex --dry-run(如果支持)打印实际会发出的请求。我习惯在本地端点前面挂一个简单的日志代理,把所有请求打出来,这样一眼就能看出路径、模型名、请求体对不对。
6. 常见问题与排查技巧实录
6.1 端点连不上:从 curl 开始逐层排查
遇到“连不上”,别急着改配置,按这个顺序查:
| 排查层级 | 检查命令 | 预期结果 |
|---|---|---|
| 网络层 | curl -v http://localhost:1234/v1/models | 返回 200 和模型列表 |
| 配置层 | yamllint openrig.yaml | 无输出 |
| 环境变量层 | echo $CLOUD_API_KEY | 输出实际密钥,非空 |
| 工具层 | openrig run claude-code --verbose | 打印实际请求 URL |
大部分“连不上”问题在第一步就暴露了——本地模型服务根本没启动,或者端口不是 1234。
6.2 模型不支持:名字和端点必须严格对应
前面讲过,这里给一个速查表:
| 报错关键词 | 根因 | 解决 |
|---|---|---|
| model is not supported | 模型名与端点不匹配 | 用/v1/models查实际名字 |
| endpoint /responses failed | 路径拼接错误 | baseUrl 只写到 /v1 |
| organization has disabled | 账号权限问题 | 检查账号订阅状态 |
| proxy failed | 代理层配置错误 | 检查代理转发规则 |
6.3 YAML 缩进报错:全角空格是隐形杀手
这个坑我必须单独拎出来说。从网页或聊天窗口复制 YAML 时,很容易混入全角空格(U+3000)或不间断空格(U+00A0)。这两种字符肉眼几乎看不出来,但 YAML 解析器会直接报错,而且报错行号经常是错的。排查方法:
grep -nP '[\x{3000}\x{00A0}]' openrig.yaml这条命令能揪出所有全角和不间断空格。找到后手动替换成普通空格。我现在养成的习惯是:YAML 永远手打缩进,绝不从别处复制。
6.4 Node.js 版本冲突:nvm 和系统版本打架
症状是node -v显示的版本和你nvm use的不一致。根因是 PATH 里系统 Node.js 的路径排在 nvm 前面。检查:
echo $PATH | tr ':' '\n' | grep node如果/usr/bin排在~/.nvm前面,就去~/.bashrc里把 nvm 的初始化脚本移到文件末尾,保证它最后执行、优先级最高。
6.5 密钥泄露:配置文件提交前的最后一道检查
在git add之前,跑一遍:
grep -rn "sk-\|api_key\|apikey" . --include="*.yaml" --include="*.env"确认没有明文密钥。更好的做法是用 git 的 pre-commit hook 自动扫描。这个习惯能救命。
7. 我踩过的坑和几条实在建议
折腾这套东西大半年,有几个体会是文档里不会写的。第一,先把单个工具跑通,再上编排。我一开始图省事,直接配 openrig,结果 Claude Code 连不上,我花了两个小时排查 openrig 配置,最后发现是 Claude Code 本身没装好。分层验证能省大量时间。第二,本地模型的上下文窗口和云端差很多。你用云端模型时习惯了一次丢几千行代码进去,换成本地 7B 模型可能直接爆上下文。配置里最好给每个工具单独设maxTokens之类的参数,别指望一套参数通吃。第三,YAML 里的注释是给未来的自己看的。每个非直觉的配置项旁边写一句为什么这么配,三个月后你回来看会感谢自己。
还有一点关于端点切换的:热搜词里cc switch这类工具本质是帮你快速切换端点,但切换后一定要重启对应的 CLI 进程。很多工具在启动时读取一次配置就缓存了,你改了 YAML 不重启,它还用旧的。openrig 的sync命令如果做了热重载最好,没做的话就老老实实openrig run重新拉起。
最后分享一个我常用的调试技巧:在本地端点前面挂一个极简的日志转发脚本,把所有请求的 URL、headers、body 打到文件里。这样任何“请求发出去但结果不对”的问题,都能从日志里一眼看出是路径错了、模型名错了还是请求体格式错了。这个脚本用 Node.js 写也就二十行,但排查效率提升是数量级的。