ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

openrig:多AI编码代理本地编排环境搭建与配置指南

openrig:多AI编码代理本地编排环境搭建与配置指南

1. openrig 到底想解决什么问题

第一次看到openrig这个词,我下意识以为是某个硬件机架项目,翻了一圈热词才反应过来——它跟claude code、codex、yaml、node.js这一串东西绑在一起,本质上是一个围绕本地 AI 编码代理运行环境做统一编排的工具思路。说白了,就是当你想在本地同时跑 Claude Code、Codex 这类命令行编码助手,还要让它们各自接不同的模型后端、读不同的配置文件、走不同的代理端口时,环境会变得一团乱。openrig想干的事,就是把这套"机架"搭起来,让多个代理工具能在一个可控、可切换、可复现的环境里工作。

我先说清楚它的定位,免得有人抱错期待。它不是模型,不是 API 网关,也不是某个厂商的官方产品。从热词组合来看,它更像是一个约定 + 配置 + 启动脚本的集合体:用yaml描述每个代理的模型来源、端点、参数,用node.js作为运行时把配置读进来,然后拉起对应的 CLI 进程。你可以把它理解成一个"多代理调度台"——你告诉它有哪些工具、各自连哪个模型,它负责把环境变量、配置文件、启动命令都摆到位。

为什么这个东西现在有需求?因为本地跑编码代理的人越来越多,但每个人的痛点高度一致:Claude Code 想接本地模型要改配置,Codex 想接第三方端点要改另一套配置,两个工具的配置格式还不一样,切换一次要手动改一堆文件,改错了就报cc switch local proxy failed while handling codex endpoint /responses这种让人头大的错误。openrig的价值就在于把这些散落的配置收敛到一处,用一份yaml管住所有代理。

适合谁看这篇?三类人。第一类是本机已经装了 Claude Code 或 Codex,但每次换模型都要折腾半天的开发者;第二类是想同时对比多个模型效果,需要频繁切换后端的人;第三类是想把这套环境固化下来、方便团队复现的工程同学。如果你只是偶尔用一次在线服务,那这篇对你价值有限;但只要你开始认真对待本地代理工作流,openrig这套思路就值得吃透。

2. 拆开 openrig 的骨架:yaml、node.js 与代理进程的分工

要理解openrig,得先把它依赖的三块东西分清楚:yaml负责"描述",node.js负责"执行",代理 CLI 负责"干活"。这三者各司其职,任何一块出问题,整个环境就跑不起来。我见过太多人一上来就抄配置,结果连报错都看不懂,就是因为没搞清这三层的边界。

2.1 yaml 在 openrig 里承担的角色

yaml是这套体系里的"配置语言"。为什么不用 JSON?因为 JSON 不能写注释,而代理配置里到处都是需要标注的地方——比如某个端点为什么这么填、某个参数为什么设成这个值。yaml支持注释、支持多行字符串、缩进即层级,写起来比 JSON 舒服太多。在openrig的语境下,一份典型的配置大概长这样:

# openrig 配置示例 agents: claude-code: command: claude model: local-qwen endpoint: http://127.0.0.1:1234/v1 env: ANTHROPIC_BASE_URL: http://127.0.0.1:1234 codex: command: codex model: deepseek-chat endpoint: http://127.0.0.1:1234/v1 env: OPENAI_BASE_URL: http://127.0.0.1:1234/v1

这里有几个关键点必须讲透。第一,agents下面每个键就是一个代理的名字,你可以随便起,但建议跟实际命令对应,方便排查。第二,env这一层是核心,因为 Claude Code 和 Codex 读取端点的方式不一样——Claude Code 认ANTHROPIC_BASE_URL,Codex 认OPENAI_BASE_URL,填错了就会走到默认的线上端点,然后报各种认证失败。第三,model字段只是给openrig自己看的标签,真正生效的是env里的环境变量和 CLI 自己的参数。

注意:yaml对缩进极其敏感,用 Tab 还是空格、缩进几格,都会影响解析。我建议统一用两个空格,并且在编辑器里打开"显示空白字符",这样能一眼看出缩进错误。

2.2 node.js 为什么是这套方案的运行时

热词里node.js出现频率极高,很多人问"node.js 是干什么的",在这里答案很明确:它是openrig的执行引擎。Claude Code 和 Codex 本身都是基于 Node 生态分发的 CLI 工具,安装它们的前提就是本机有可用的 Node 运行时。openrig用 Node 来读yaml、拼环境变量、spawn子进程,把配置翻译成实际的启动命令。

版本这块是重灾区。热词里有一条error installing 24.21.0: node.js v24.21.0 is not yet released or is not ava,这就是典型的版本号写错导致的安装失败。我的建议是:不要追最新版,用 LTS。LTS 版本经过长时间验证,跟各类 CLI 工具的兼容性最好。安装方式上,Windows 直接去官网下 LTS 安装包,Ubuntu 用包管理器或者版本管理工具都行。装完之后一定要验证:

node -v npm -v

两条命令都能正常输出版本号,才算装好。如果node -v报"不是内部或外部命令",说明 PATH 没配好,重装时记得勾选"添加到 PATH"。

2.3 代理进程的启动与隔离

openrig最容易被忽略的一点是进程隔离。当你同时跑 Claude Code 和 Codex 时,它们各自会读自己的配置文件(通常在用户目录下的隐藏文件夹里),如果两个工具共用同一套环境变量,就会互相污染。openrig的做法是给每个代理单独构造一份环境变量,在spawn时传进去,而不是改全局环境。

这个设计的好处是:你切换代理时不需要动系统环境变量,也不会出现"改了 Codex 的配置结果 Claude Code 也受影响"的情况。代价是配置稍微复杂一点,但换来的是可预测性。我在实际使用中发现,凡是涉及多工具共存的场景,隔离永远比共享省心,哪怕前期多写几行配置。

3. 从零搭一套 openrig 环境的完整路径

这一节我按真实操作顺序走一遍,从装 Node 到跑通第一个代理。每一步我都会说清楚"为什么这么做",而不是只给命令。你照着做,大概率能一次跑通;就算中间卡住,也能根据报错定位到具体环节。

3.1 环境准备:Node 与包管理器的选择

第一步装 Node。Windows 用户去官网下 LTS 的.msi,一路下一步,注意勾选"Add to PATH"。Ubuntu 用户我推荐用nvm这类版本管理工具,因为后面你可能需要切换 Node 版本测试兼容性,用系统包管理器装的 Node 换版本很麻烦。

# Ubuntu 下用 nvm 安装 LTS curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash source ~/.bashrc nvm install --lts nvm use --lts

装完 Node,包管理器npm会一起带上。这里有个经验:不要急着全局装一堆 CLI,先把 Node 环境确认干净,再逐个装代理工具。因为 Claude Code 和 Codex 的安装脚本对 Node 版本有要求,环境不干净时排查问题会非常痛苦。

3.2 安装 Claude Code 与 Codex 的注意事项

Claude Code 的安装,官方推荐用 npm 全局安装。装之前确认 npm 的全局目录在 PATH 里,否则装完命令找不到。Codex 同理,但它的安装包在不同平台上有差异,Windows 桌面版和 CLI 版是两回事,别装混了。

npm install -g @anthropic-ai/claude-code npm install -g @openai/codex

装完之后分别跑claude --version和codex --version验证。如果报your organization has disabled claude subscription access这类错误,那是账号权限问题,跟安装无关,需要检查你的账号配置。热词里还有codex is ignoring 1 unrecognized configuration setting,这是配置文件里写了 Codex 不认识的字段,通常不影响运行,但建议清理掉,免得以后排查时被误导。

提示:安装过程中如果卡在下载阶段,多半是网络问题。可以配置 npm 的镜像源加速,但具体用哪个源要根据你所在网络环境选择,这里不展开。

3.3 编写第一份 openrig 配置

环境齐了,开始写配置。我建议从只配一个代理开始,跑通之后再加第二个。一次性配两个,出问题时你分不清是配置格式错了还是两个代理互相干扰。

agents: claude-code: command: claude env: ANTHROPIC_BASE_URL: http://127.0.0.1:1234 ANTHROPIC_API_KEY: dummy-key

这份最小配置只做一件事:告诉 Claude Code 把请求发到本地1234端口。ANTHROPIC_API_KEY填dummy-key是因为很多本地模型服务不校验 key,但 CLI 要求这个变量必须存在,不填会直接报错退出。这是新手最容易踩的坑之一——以为本地服务不需要 key,结果 CLI 在启动阶段就挂了。

配置写好后,用 Node 写一个最小的启动脚本:

const fs = require('fs'); const yaml = require('js-yaml'); const { spawn } = require('child_process'); const config = yaml.load(fs.readFileSync('./openrig.yaml', 'utf8')); const agent = config.agents['claude-code']; const child = spawn(agent.command, [], { env: { ...process.env, ...agent.env }, stdio: 'inherit' }); child.on('exit', (code) => console.log(`代理退出,代码 ${code}`));

这段脚本干的事很直白:读yaml、取配置、合并环境变量、拉起进程。stdio: 'inherit'是关键,它让子进程直接接管当前终端,你才能跟代理正常交互。如果设成pipe,代理的输出会被吞掉,看起来就像卡死了。

3.4 验证代理是否真的连上了本地模型

跑起来之后,怎么确认它真的走了本地端点,而不是偷偷连了线上?我的做法是看本地模型服务的日志。本地服务每收到一个请求都会打日志,如果代理启动后你发一句话,本地服务日志里出现了对应的请求记录,说明链路通了。反过来,如果本地服务毫无动静,但代理还能回话,那它一定走了别的端点,配置没生效。

另一个验证手段是故意把ANTHROPIC_BASE_URL填成一个不存在的端口,比如http://127.0.0.1:9999。如果代理立刻报连接失败,说明配置生效了;如果它还能正常回话,说明这个环境变量根本没被读到。这个"反向验证法"我在排查配置问题时用得最多,比看文档快得多。

4. 多代理共存时的冲突与排查链路

单代理跑通只是开始,openrig真正的价值在多代理共存时才体现出来。但共存也意味着冲突,这一节我把常见的几类问题按排查顺序讲清楚,你可以当成一份排错清单用。

4.1 端口与端点冲突的典型表现

最常见的冲突是端点串台。你给 Claude Code 配了本地1234,给 Codex 配了另一个本地服务1235,结果发现 Codex 的请求跑到了1234上。原因通常是环境变量没隔离干净——比如你在系统层面设了OPENAI_BASE_URL,而openrig的配置里又设了一遍,两者冲突时以哪个为准取决于加载顺序。

排查这类问题的第一步是打印实际生效的环境变量。在启动脚本里加一行:

console.log('实际环境:', { ...process.env, ...agent.env });

看清楚每个代理拿到的到底是什么。如果发现某个变量被系统环境污染了,就在openrig配置里显式覆盖它,别指望默认值。

4.2cc switch local proxy failed这类报错的定位思路

热词里cc switch local proxy failed while handling codex endpoint /responses这个报错很有代表性。它说的是:切换工具在处理 Codex 的/responses端点时失败了。拆开看,/responses是 Codex 使用的接口路径,local proxy说明中间有一层本地转发。失败的原因通常有三类:本地转发服务没起来、端点路径拼错了、或者请求格式跟服务端不匹配。

我的排查顺序是这样的:先确认本地服务在监听(curl一下端点看有没有响应),再确认配置里的路径跟服务端实际路径一致,最后看请求体格式。很多时候问题出在路径上——服务端提供的是/v1/chat/completions,配置里却写了/responses,自然对不上。这类问题没有捷径,就是逐个环节验证,把链路切成小段,一段段确认。

4.3 模型名不被支持时的处理

热词里the 'gpt-5.6-sol' model is not supported when using codex with a...这种报错,本质是模型名跟后端不匹配。Codex 默认会用一个特定的模型名去请求,如果你的本地服务只认别的名字,就会报不支持。解决办法是在配置里显式指定模型名,让 Codex 用你后端认识的名字去请求。

这里有个细节:不同工具指定模型名的方式不一样。有的通过环境变量,有的通过命令行参数,有的通过配置文件。openrig的价值就在于把这些差异收敛到一份yaml里,你只需要在配置里写一次,启动脚本负责翻译成对应工具认识的形式。这也是为什么我一直强调配置要集中管理——分散的配置迟早会失控。

报错关键词大概率原因优先排查方向
local proxy failed本地转发未启动或路径错误确认服务监听、核对端点路径
model is not supported模型名与后端不匹配配置里显式指定后端认识的模型名
unrecognized configuration setting配置字段拼写错误或多余清理配置,只保留工具认识的字段
organization has disabled账号权限问题检查账号配置,与本地环境无关

5. 把 openrig 用顺手的几个实战心得

配置跑通只是及格线,真正让openrig发挥价值的是日常使用中的一些习惯。这些心得都是我在反复折腾中攒下来的,文档里基本不会写,但能帮你省下大量时间。

5.1 配置版本化,别让环境成为黑盒

我强烈建议把openrig.yaml纳入版本管理。原因很简单:这套配置里包含了端点、模型名、环境变量,任何一项变了都可能导致行为差异。没有版本记录,你根本记不清"上次能跑通"时配置长什么样。用 Git 管起来,每次改动都有记录,出问题能快速回滚。

更进一步,可以把启动脚本也一起管起来。这样换一台机器,git clone下来,装好 Node 和 CLI,直接就能复现整套环境。对于需要团队协作的场景,这一点尤其重要——新人不用再问"你那个配置怎么写的",直接拉代码就行。

5.2 用日志而不是猜测来定位问题

我见过太多人遇到报错就开始猜,改一个配置试一次,试了十几次还没找到原因。正确的做法是让程序告诉你发生了什么。在启动脚本里加日志,把实际执行的命令、实际传入的环境变量、子进程的退出码都打出来。有了这些信息,问题定位速度能快好几倍。

具体来说,我习惯在spawn之前打印完整命令和环境,在exit事件里打印退出码和信号。如果代理是异常退出,退出码往往能直接指向原因——比如127通常是命令找不到,1通常是配置或参数错误。这些数字比任何猜测都可靠。

5.3 切换模型时先小步验证

每次换模型或换端点,不要直接上复杂任务。先用一句简单的话测试,确认链路通了再干正事。因为模型切换涉及端点、模型名、认证方式多个变量,一次性全改,出问题时你分不清是哪个环节的问题。小步验证的原则是:一次只改一个变量,改完立刻验证。

这个习惯看起来慢,实际上快。因为一旦出问题,你能立刻知道是刚才那一步导致的,不用从头排查。我在切换本地模型和第三方端点时,都是先跑一句"你好"确认连通,再开始正式工作。

5.4 关于本地模型与第三方端点的取舍

热词里既有本地模型(如通过 LM Studio 提供的服务),也有第三方端点(如 DeepSeek、Qwen、GLM 等)。这两类各有适用场景。本地模型的优势是数据不出本机、响应稳定、没有额度限制,适合处理敏感代码或需要高频调用的场景;第三方端点的优势是模型能力强、无需本地算力,适合复杂推理任务。

openrig的好处是让你能在两者之间快速切换,而不用改一堆配置。我的做法是在yaml里同时配好本地和第三方两套代理,需要哪个就启动哪个。这样既保留了灵活性,又不用每次手动改配置。实际用下来,日常简单任务走本地,遇到难题切第三方,这个组合最省心。

6. 这套方案还能往哪些方向延伸

openrig目前看起来还是个偏个人的工具思路,但它的骨架其实可以撑起更多场景。比如把配置做成模板,针对不同任务预设不同的代理组合;比如加一层健康检查,启动前先确认本地服务可用;再比如把日志收集起来,分析每个代理的调用频率和响应情况。

我个人最看好的延伸方向是配置的可移植性。现在这套东西还是偏手工,如果能把环境依赖、配置、启动逻辑打包成一个可复现的单元,那换机器、换团队、换项目时就能真正做到开箱即用。这比单纯省几次配置时间有价值得多。

最后分享一个小技巧:如果你同时用多个代理,给每个代理的终端窗口起个明确的名字,或者用不同的终端标签区分。看起来是小事,但当你同时开着三四个窗口时,能一眼认出哪个是哪个,能省下不少"我刚才在哪个窗口敲的命令"的困惑。工具是为人服务的,把这些细节理顺,整套环境才真正顺手。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进