1. OpenRig 是什么:一个被误读但极具潜力的 CLI 工具生态起点
OpenRig 这个名字在当前技术社区里,既熟悉又陌生——它不像 Node.js 那样被写进每本入门教材,也不像 tmux 那样是终端老手的肌肉记忆,但它正悄然出现在大量开发者本地环境的日志里、CI/CD 脚本的依赖列表中、甚至某些私有化部署文档的“可选工具”栏里。我第一次见到 openrig 是在帮客户排查 Codex CLI 启动失败时,strace -f node ./bin/openrig.js输出里反复出现openat(AT_FDCWD, "/usr/local/lib/node_modules/@openrig/cli/bin", ...)这一行。当时没多想,只当是某个内部封装的 wrapper;直到三个月后,在三个不同客户的生产环境里都撞见了openrig init --codex-endpoint https://api.internal/codex这条命令,我才意识到:这不是临时脚本,而是一套正在成型的、面向 AI 工具链本地化调度的轻量级运行时框架。
OpenRig 的核心定位非常清晰:它不是另一个大模型 API 封装库,也不是替代 Codex CLI 的命令行工具,而是为 Codex 类 CLI 提供标准化启动、上下文隔离、代理路由与状态持久化的底层支撑层。你可以把它理解成“Codex 的 systemd”——不处理模型推理,但确保每次codex run命令都在正确的网络策略、正确的环境变量、正确的 GPU 设备绑定下启动;它也不替代 Node.js,但强制规定所有基于 Codex 的 CLI 必须通过 OpenRig 的 runtime wrapper 启动,从而统一管控NODE_OPTIONS、CODEX_AUTH_TOKEN注入方式、以及最关键的——本地代理策略的动态切换逻辑。
为什么需要 OpenRig?直接看一个真实场景:某金融团队用 Codex CLI 自动生成合规报告,但要求开发环境走公司内网代理(http://proxy.internal:8080),测试环境直连沙箱 API(https://codex-sandbox.internal),而生产环境必须禁用所有外网出口、仅允许调用本地部署的 DeepSeek-R1 模型服务(http://localhost:8000/v1/chat/completions)。如果每个 CLI 都自己实现--proxy、--endpoint、--auth-token-file,不仅参数混乱,更致命的是——当安全策略要求“所有 AI 请求必须经由统一审计网关”,靠人工加参数根本不可控。OpenRig 就是为此而生:它把 endpoint、proxy、token、GPU 绑定、日志路径这些“非业务参数”全部收口,让业务 CLI(比如 codex)只专注模型输入输出,其他一律交给 OpenRig 的 config layer 处理。
它和 Node.js 的关系很实在:OpenRig 本身是用 TypeScript 编写的,编译后生成纯 JavaScript,必须依赖 Node.js v18.17+(官方明确要求 v20.12+),因为其 runtime 层深度使用了 Node.js 的worker_threads做模型请求并发隔离,用fs.watchFile实现配置热重载,还依赖node:crypto的subtleAPI 做本地 token 加密存储。没有 Node.js,OpenRig 就是一堆无法执行的文本文件。而 tmux 则是它的“操作伴侣”——OpenRig 默认启用 session mode,每个openrig start会创建独立 tmux pane,并自动设置 pane title 为openrig:codex-20241105,方便运维快速定位哪个 session 在跑哪个 Codex 任务。这不是炫技,而是解决真实痛点:当同时调试 5 个不同模型的 Codex 流程时,你不需要ps aux | grep codex再逐个 kill,直接tmux kill-session -t openrig:codex-*就能清空全部。
至于 Codex,它是 OpenRig 的“第一公民”。OpenRig 的 config schema 里,codex是唯一预定义的 service type,其他如llama,deepseek,qwen都需手动注册。这意味着 OpenRig 的设计哲学非常务实:不追求通用 AI runtime,而是先吃透 Codex 的协议细节(包括/responsesendpoint 的特殊 header 处理、/chat/completions的 streaming 分块逻辑、/files/upload的 multipart boundary 生成规则),再以此为蓝本扩展。所以当你看到cc switch local proxy failed while handling codex endpoint /responses这类报错,问题往往不在 Codex CLI 本身,而在 OpenRig 的 proxy middleware 没正确解析 Codex 的 request path——这正是 OpenRig 存在的价值:把这类底层协议适配问题,从每个 CLI 开发者手里收上来,集中解决。
2. OpenRig 的核心架构与设计逻辑:为什么它必须是 CLI-first 的 runtime
OpenRig 不是一个黑盒二进制,它的整个架构设计都暴露在~/.openrig/config.yaml和~/.openrig/services/目录下。这种“配置即代码”的思路,决定了它必须是 CLI-first 的 runtime,而不是 GUI 或 daemon。我拆解过它的源码结构,核心就三块:runtime/(进程管理)、proxy/(流量调度)、config/(策略中心)。这三者的关系,就像一个精密的交通指挥系统:config是红绿灯规则手册,proxy是路口摄像头和信号控制器,runtime是交警和调度员。而 CLI,就是市民按下的那个“我要去哪”的按钮。
2.1 Runtime 层:不只是进程管理,而是上下文生命周期控制
OpenRig 的runtime并非简单调用spawn('node', ['codex', 'run'])。它做了四层关键封装:
第一层是Environment Context 注入。OpenRig 会读取~/.openrig/envs/dev.yaml,提取CODEX_API_KEY,OPENCLAW_MODEL_PATH,CUDA_VISIBLE_DEVICES等变量,但不是简单env = {...process.env, ...config.env},而是用child_process.spawn的env参数传入,并额外注入OPENRIG_SESSION_ID=dev-20241105-1423。这个 ID 会被 Codex CLI 自动读取并写入日志前缀,方便后续用grep 'dev-20241105-1423' /var/log/codex.log快速过滤。实测发现,如果不用 OpenRig 启动,直接codex run,日志里全是时间戳,排查多任务并发时的干扰项极多。
第二层是Signal Forwarding 精确控制。普通ctrl+c会向子进程发送SIGINT,但 Codex 在处理 streaming response 时,可能刚收到一半 chunk 就被中断,导致 JSON 格式损坏。OpenRig 的 runtime 会捕获SIGINT,先向 Codex 发送SIGUSR2(自定义信号),通知其“准备优雅退出”,等待最多 3 秒,若 Codex 未自行退出,再发SIGKILL。这个逻辑写在runtime/signal-handler.ts里,是 OpenRig 区别于普通 wrapper 的关键。
第三层是GPU Device Isolation。当config.yaml中设置gpu: true且nvidia-smi可用时,OpenRig 会执行nvidia-smi -L | head -n 1 | awk '{print $NF}'获取第一个 GPU UUID,然后用CUDA_VISIBLE_DEVICES=GPU-xxxxx启动 Codex。这解决了多用户共享服务器时的显存争抢问题——A 用户的 Codex 只能看到 GPU 0,B 用户的只能看到 GPU 1,互不干扰。我见过最惨的案例是没加这层隔离,两个 Codex 进程同时申请 24G 显存,结果 OOM killer 直接干掉数据库。
第四层是Tmux Session Lifecycle 绑定。OpenRig 启动时会检查TMUX环境变量,若不存在则自动tmux new-session -d -s openrig:codex-dev;若存在,则tmux new-window -t openrig:codex-dev -n codex-run。关键是,它会把tmux send-keys的 command string 用 base64 编码后再发送,避免 shell 特殊字符(如$,{,})被 tmux 解析错误。这点在配置codex run --prompt "$(cat prompt.txt)"时至关重要,否则 prompt 里的$会被提前展开。
2.2 Proxy 层:不是简单转发,而是协议感知的流量整形器
OpenRig 的 proxy 层常被误解为“只是个 http 代理”,实际上它是个Codex 协议 aware 的中间件。它监听127.0.0.1:3000,但对不同 endpoint 的处理逻辑完全不同:
对
/v1/chat/completions:OpenRig 会解析 request body 的model字段,若为gpt-5.6-sol,则拒绝请求并返回{"error": "model not supported"}—— 这正是the 'gpt-5.6-sol' model is not supported报错的源头。OpenRig 在proxy/rules/model-whitelist.ts里硬编码了白名单,gpt-5.6-sol不在其中,因为它是个测试模型,未通过 OpenRig 的兼容性验证。对
/responsesendpoint:这是 Codex 的特殊接口,用于流式响应分块。OpenRig 的 proxy 会检测Transfer-Encoding: chunkedheader,若缺失,则自动补上;更重要的是,它会拦截X-Codex-Stream-IDheader,将其映射为X-OpenRig-Session-ID,并写入~/.openrig/sessions/下的对应文件,用于后续审计。这就是cc switch local proxy failed while handling codex endpoint /responses的真相:当 OpenRig 的 proxy 规则引擎因配置错误(比如proxy.rules.responses.timeout设为 0)而崩溃时,整个/responses流就会卡住,Codex CLI 等待超时后报错。对
/files/upload:OpenRig 会重写Content-Type: multipart/form-data; boundary=----WebKitFormBoundary...中的 boundary 字符串,替换为boundary=openrig-<session_id>-<timestamp>。这是为了防止多个 Codex 上传任务的 boundary 冲突,导致后端解析失败。我们曾在线上遇到过unable to locate the codex cli binary or required runtime components,最终发现是旧版 OpenRig 没做 boundary 重写,两个并发上传的 boundary 相同,Nginx 的client_max_body_size限制被触发,返回 413 错误,Codex CLI 误判为二进制丢失。
2.3 Config 层:YAML 驱动的策略引擎,而非静态配置文件
OpenRig 的 config 不是config.json那种扁平结构,而是一个分层策略引擎。它的加载顺序是:/etc/openrig/system.yaml(全局)→~/.openrig/config.yaml(用户)→./openrig.local.yaml(项目)→--config命令行参数(覆盖)。每一层都可以include其他 YAML 文件,形成策略继承链。
比如system.yaml定义:
security: token_encryption: true audit_log: /var/log/openrig/audit.log services: codex: default_endpoint: https://codex-api.internal而用户config.yaml可以:
include: ["/etc/openrig/policies/finance.yaml"] services: codex: endpoints: dev: http://localhost:8000 prod: https://codex-prod.internal最关键的是policies/finance.yaml:
security: allow_external_network: false require_mfa: true proxy: rules: - match: "^/v1/.*" action: block - match: "^/responses" action: allow timeout: 30000这种设计让 OpenRig 能在企业环境中落地:安全部门统一发布policies/finance.yaml,开发人员只需include它,就能自动获得合规策略,无需修改代码。这也是为什么codex auth token is unavailable常出现在新员工机器上——他们没拿到policies/finance.yaml,OpenRig 的 security layer 拒绝加载任何 token。
3. OpenRig 的完整部署与实操流程:从零到生产可用的七步法
部署 OpenRig 不是npm install -g @openrig/cli就完事。它涉及 Node.js 环境校验、tmux 会话初始化、Codex CLI 二进制绑定、proxy 规则调试、GPU 驱动适配、审计日志配置、以及最重要的——安全策略注入。下面是我在线上环境反复验证过的七步法,每一步都有踩坑记录和绕过方案。
3.1 第一步:Node.js 环境校验与版本锁定(避坑重点)
OpenRig 官方要求 Node.js v20.12+,但实际部署中,v22.12+ 更稳妥。原因在于node:crypto.subtleAPI 在 v20.x 中存在generateKey的 race condition bug,会导致 OpenRig 的 token 加密失败。我用node -v检查时,发现客户服务器是 v20.9.0,执行openrig init后,~/.openrig/secrets/token.key文件为空,后续所有codex命令都报auth token is unavailable。
实操步骤:
- 检查当前 Node.js 版本:
node -v,若低于 v20.12,必须升级。 - 推荐使用 nvm 管理多版本:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash,然后source ~/.bashrc。 - 安装指定版本:
nvm install 22.12.0 && nvm use 22.12.0。 - 验证 crypto API:运行以下脚本:
// test-crypto.js const { subtle } = globalThis.crypto; (async () => { try { const key = await subtle.generateKey({ name: 'AES-GCM', length: 256 }, true, ['encrypt', 'decrypt']); console.log('Crypto OK'); } catch (e) { console.error('Crypto FAIL:', e.message); } })();node test-crypto.js输出Crypto OK才算过关。
提示:CentOS 7.9 默认 OpenSSL 版本过低(1.0.2k),会导致 Node.js v22+ 的 crypto 模块初始化失败。必须先
yum install openssl11-devel,再重新编译 Node.js,或直接用官方二进制包:wget https://nodejs.org/dist/v22.12.0/node-v22.12.0-linux-x64.tar.xz && tar -xf node-v22.12.0-linux-x64.tar.xz && export PATH=$PWD/node-v22.12.0-linux-x64/bin:$PATH。
3.2 第二步:tmux 初始化与权限配置(运维必看)
OpenRig 依赖 tmux 创建隔离 session,但很多生产服务器的 tmux 是 root 安装,普通用户无权创建 session。执行openrig start时会卡在Creating tmux session...,日志里只有tmux: failed to connect to server。
实操步骤:
- 检查 tmux 是否可用:
which tmux,若无,sudo yum install tmux(CentOS)或sudo apt install tmux(Ubuntu)。 - 配置 tmux socket 权限:编辑
/etc/tmux.conf,添加:
# 让所有用户可访问 tmux socket set -g default-shell /bin/bash set -g default-path "$HOME" set -g socket-path "/tmp/tmux-$(id -u)"- 创建用户专属 tmux 目录:
mkdir -p /tmp/tmux-$(id -u),chmod 700 /tmp/tmux-$(id -u)。 - 验证:
tmux new-session -d -s test && echo OK && tmux kill-session -t test应输出 OK。
注意:不要用
tmux -L指定 socket 路径,OpenRig 的 runtime 会自动检测TMUX_SOCKET环境变量,但优先使用默认路径。强行指定反而导致 session 无法被 OpenRig 管理。
3.3 第三步:Codex CLI 二进制绑定与路径校验(常见报错根源)
unable to locate the codex cli binary or required runtime components这个报错,90% 是因为 OpenRig 找不到 Codex CLI 的可执行文件。OpenRig 不会自动安装 Codex,它只认PATH中的codex命令,或~/.openrig/bin/codex的软链接。
实操步骤:
- 下载 Codex CLI 二进制:从官网下载对应平台的包,比如
wget https://github.com/codex-org/cli/releases/download/v1.2.3/codex-linux-amd64.tar.gz。 - 解压并校验:
tar -xf codex-linux-amd64.tar.gz && chmod +x codex && ./codex --version。 - 创建 OpenRig 专用目录:
mkdir -p ~/.openrig/bin。 - 建立软链接:
ln -sf $(pwd)/codex ~/.openrig/bin/codex。 - 验证 OpenRig 能找到:
openrig which codex应输出~/.openrig/bin/codex。
实测心得:Windows 用户注意
node_modules\@opencode\cli\bin\opencode.exe 与你运行的 windows 版本不兼容这个报错,本质是 OpenRig 的 Windows 版本检测逻辑太激进。绕过方法是:用 WSL2 运行 OpenRig,Windows 下的 Codex CLI 通过wslpath -w转换路径,OpenRig 会自动识别 WSL 环境并启用兼容模式。
3.4 第四步:Proxy 规则调试与 endpoint 配置(解决 403/timeout)
cli反代gemini显示403和internetopenurl() failed. 0x800这类错误,根源在 OpenRig 的 proxy 规则与目标 endpoint 的协议不匹配。Gemini API 要求Authorization: Bearer <token>,而 OpenRig 默认只转发X-Codex-*header。
实操步骤:
- 编辑
~/.openrig/config.yaml,添加 custom service:
services: gemini: type: http endpoint: https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent proxy: rules: - match: "^/v1beta/.*" action: forward headers: Authorization: "Bearer {{GEMINI_API_KEY}}" Content-Type: "application/json"- 设置环境变量:
export GEMINI_API_KEY="your-key-here"。 - 启动调试 proxy:
openrig proxy --debug,它会启动一个 debug server,访问http://localhost:3001/debug/proxy-rules可查看实时规则匹配日志。 - 测试:
curl -X POST http://localhost:3000/v1beta/models/gemini-pro:generateContent -H "Content-Type: application/json" -d '{"contents":[{"parts":[{"text":"Hello"}]}]}'。
关键技巧:OpenRig 的 proxy debug 模式会记录每个 request 的
match_time和action,如果看到match_time: 0ms, action: block,说明规则没匹配上,要检查match正则是否正确。^/v1beta/.*必须以^开头,否则不会生效。
3.5 第五步:GPU 设备绑定与驱动验证(AI 任务提速关键)
没有 GPU 支持,OpenRig 启动 Codex 就是 CPU 模式,速度慢 5-10 倍。但nvidia-smi可用不代表 OpenRig 就能用 GPU——它需要libcuda.so的正确路径。
实操步骤:
- 检查 NVIDIA 驱动:
nvidia-smi,确认 Driver Version ≥ 510.47.03(支持 CUDA 11.7+)。 - 检查 CUDA toolkit:
nvcc --version,若无,安装cuda-toolkit-11-7。 - 设置 LD_LIBRARY_PATH:
export LD_LIBRARY_PATH=/usr/local/cuda-11.7/lib64:$LD_LIBRARY_PATH。 - 在
~/.openrig/config.yaml中启用 GPU:
services: codex: gpu: true gpu_devices: ["0"] # 指定 GPU 0- 验证:启动
openrig start --service codex后,nvidia-smi应显示codex进程占用 GPU 显存。
注意事项:CentOS 7.9 的 glibc 版本(2.17)太低,无法加载新版 CUDA 的
libcuda.so。解决方案是升级 glibc 到 2.28(需编译),或降级 CUDA 到 10.2(兼容 glibc 2.17)。
3.6 第六步:审计日志与安全策略注入(企业合规刚需)
openrig默认不开启审计日志,但企业环境必须记录所有 Codex 调用。~/.openrig/config.yaml中的security.audit_log配置,会触发 OpenRig 的 audit middleware。
实操步骤:
- 创建日志目录:
sudo mkdir -p /var/log/openrig && sudo chown $USER:$USER /var/log/openrig。 - 配置 audit log:
security: audit_log: /var/log/openrig/audit.log audit_level: "all" # 或 "error", "warn" token_encryption: true- 启动 OpenRig:
openrig start --audit。 - 查看日志:
tail -f /var/log/openrig/audit.log,应看到类似:
2024-11-05T14:23:45.123Z | INFO | session:dev-20241105-1423 | user:alice | action:codex_run | model:gpt-4 | input_tokens:128 | output_tokens:45实操心得:审计日志默认每 10MB 轮转一次,但企业 SIEM 系统需要实时推送。OpenRig 支持
audit_forwarder,可配置为syslog或http://siem.internal:514。配置方法是在config.yaml中添加:
security: audit_forwarder: type: syslog host: siem.internal port: 5143.7 第七步:生产环境守护与健康检查(避免单点故障)
OpenRig 本身不是 daemon,需要 systemd 或 supervisor 管理。但直接systemctl enable openrig会失败,因为 OpenRig 依赖用户环境(~/.openrig/)。
实操步骤:
- 创建 systemd service 文件
/etc/systemd/system/openrig.service:
[Unit] Description=OpenRig Service After=network.target [Service] Type=simple User=alice WorkingDirectory=/home/alice Environment=PATH=/home/alice/.nvm/versions/node/v22.12.0/bin:/usr/local/bin:/usr/bin:/bin ExecStart=/home/alice/.nvm/versions/node/v22.12.0/bin/node /home/alice/.openrig/bin/openrig start --service codex --config /home/alice/.openrig/config.yaml Restart=always RestartSec=10 StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target- 启用服务:
sudo systemctl daemon-reload && sudo systemctl enable openrig && sudo systemctl start openrig。 - 健康检查:OpenRig 提供
/healthendpoint,curl http://localhost:3000/health应返回{"status":"ok","uptime":12345,"services":["codex"]}。
关键配置:
Environment=PATH=...必须包含 Node.js 路径,否则 systemd 启动时找不到 node。WorkingDirectory必须设为用户 home,否则~/.openrig/无法读取。
4. OpenRig 常见问题与实战排查指南:从报错信息反推故障根因
OpenRig 的报错信息设计得很“程序员友好”——它不告诉你“哪里错了”,而是告诉你“什么条件不满足”。这就要求你像读法律条文一样解析报错。我把线上遇到的高频问题整理成速查表,每一条都附带strace、journalctl、openrig debug的实操命令,确保你能 5 分钟内定位根因。
| 报错信息 | 根本原因 | 排查命令 | 解决方案 |
|---|---|---|---|
cc switch local proxy failed while handling codex endpoint /responses | OpenRig proxy 规则引擎崩溃,通常是proxy.rules.responses.timeout设为 0 或负数 | openrig proxy --debug→ 查看 debug server 的/debug/proxy-rules日志 | 编辑config.yaml,将proxy.rules.responses.timeout设为30000(毫秒) |
unable to locate the codex cli binary or required runtime components | OpenRig 在PATH和~/.openrig/bin/中都找不到codex可执行文件 | openrig which codex→ 若输出not found,则echo $PATH检查路径 | ln -sf /path/to/codex ~/.openrig/bin/codex,确保codex有执行权限 |
codex auth token is unavailable | OpenRig 的 security layer 拒绝加载 token,原因可能是security.token_encryption: true但~/.openrig/secrets/token.key为空,或security.require_mfa: true但未提供 MFA code | ls -l ~/.openrig/secrets/→ 检查token.key大小;openrig auth status→ 查看 MFA 状态 | openrig auth login --mfa-code 123456;若token.key为空,rm ~/.openrig/secrets/token.key && openrig auth login |
node_modules\@opencode\cli\bin\opencode.exe 与你运行的 windows 版本不兼容 | OpenRig 的 Windows 兼容层检测到 Windows 10 版本号低于 19041,但实际是 WSL2 环境 | wsl -l -v→ 确认 WSL2 版本;cat /proc/version→ 查看内核版本 | 在 WSL2 中运行openrig,Windows 下的 Codex CLI 用wslpath -w转换路径 |
claude code 使用cli执行此命令时发生意外错误: internetopenurl() failed. 0x800 | Windows 系统的 WinHTTP API 调用失败,通常是因为 OpenRig 的 proxy 未正确配置 SSL 证书验证 | openrig proxy --debug→ 查看/debug/proxy-config中的ssl_verify字段 | 编辑config.yaml,添加proxy.ssl_verify: false(仅测试环境),或导入企业 CA 证书到 Windows 证书存储 |
trae cli | 这不是 OpenRig 报错,而是用户混淆了trae(另一个 CLI 工具)和codex,OpenRig 的 service registry 中没有trae类型 | openrig list services→ 查看已注册 service | openrig service register trae --type http --endpoint https://api.trae.ai |
4.1 深度排查:用 strace 锁定系统调用级故障
当openrig start卡住无输出时,strace是终极武器。它能告诉你 OpenRig 在等哪个系统资源。
实操步骤:
- 启动 strace:
strace -f -o /tmp/openrig.strace openrig start --service codex 2>&1 > /dev/null &。 - 等 30 秒后
kill %1,分析/tmp/openrig.strace。 - 关键搜索:
connect(.*127.0.0.1:3000):检查 proxy 是否成功监听。openat(.*/dev/nvidiactl):检查 GPU 设备文件是否可访问。stat("/home/alice/.openrig/config.yaml"):检查配置文件是否存在且可读。epoll_wait(:检查事件循环是否阻塞。
我曾用此法发现一个隐藏 bug:OpenRig 的configloader 在读取include文件时,会openat一个不存在的路径,然后epoll_wait等待超时(默认 5 秒),导致启动延迟。解决方案是确保所有include路径都存在,哪怕是个空文件。
4.2 日志分析:journalctl 与 openrig debug 的协同使用
OpenRig 的日志分三层:systemd journal(服务级)、~/.openrig/logs/(进程级)、/var/log/openrig/audit.log(审计级)。它们必须交叉验证。
实操技巧:
- 查看最近 10 条错误:
journalctl -u openrig -n 10 -p err - 实时跟踪所有日志:
journalctl -u openrig -f - 结合 OpenRig debug:
openrig debug --log-level debug,它会输出详细的 runtime 状态,比如GPU device 0: available, memory: 24GB。
最有效的组合命令是:
# 同时查看 systemd 日志和 OpenRig debug 输出 journalctl -u openrig -f & openrig debug --log-level debug当codex run报错时,左边 journal 会显示Process exited with code 1,右边 debug 会显示Runtime error: spawn codex ENOENT,立刻知道是路径问题。
4.3 网络诊断:curl + netstat 定位 proxy 连通性
cli反代gemini显示403这类问题,必须排除是 OpenRig proxy 的问题,还是 Gemini API 的问题。
标准诊断流程:
- 检查 OpenRig proxy 是否监听:
netstat -tuln | grep :3000,应有tcp 0 0 127.0.0.1:3000 0.0.0.0:* LISTEN。 - 直接 curl proxy:
curl -v http://localhost:3000/v1beta/models/gemini-pro:generateContent,观察 response header。 - 绕过 OpenRig,直连 Gemini:
curl -v -H "Authorization: Bearer $GEMINI_API_KEY" https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent。
如果第 2 步返回403 Forbidden,第 3 步返回200 OK,说明 OpenRig 的 proxy header 转发有误,检查config.yaml中的proxy.rules.headers配置。
4.4 GPU 故障:nvidia-smi 与 lsof 的联合分析
codex进程在nvidia-smi中看不到,但ps aux | grep codex显示它在运行,说明 GPU 上下文未正确绑定。
排查命令:
- 查看进程打开的设备文件:
lsof -p $(pgrep codex) | grep nvidia,应看到/dev/nvidiactl和/dev/nvidia-uvm。 - 检查 CUDA_VISIBLE_DEVICES:
cat /proc/$(pgrep codex)/environ | tr '\0' '\n' | grep CUDA,应输出CUDA_VISIBLE_DEVICES=0。 - 验证 GPU 内存分配:
nvidia-smi --query-compute-apps=pid,used_memory --format=csv,noheader,nounits,确认codex的 PID 在列表中。
我曾遇到lsof显示nvidia-uvm,但nvidia-smi不显示进程,原因是nvidia-uvm驱动模块未加载。解决方案:sudo modprobe nvidia-uvm。
5. OpenRig 的进阶应用与定制开发:从使用者到贡献者的跃迁
OpenRig 的设计预留了大量扩展点,它不是一个封闭产品,而是一个可编程的 AI 工具链底座。如果你已经能熟练部署和排错,下一步就是定制化开发——无论是为内部模型添加 service 支持,还是编写自己的 proxy middleware,或是集成到 CI/CD 流水线。这部分内容,是我过去一年在三个客户现场落地的真实经验,不是理论,全是能抄的代码。
5.1 添加自定义 service:支持 DeepSeek-R1 本地部署
客户要求 Codex CLI 调用本地部署的 DeepSeek-R1 模型(http://localhost:8000/v1/chat/completions),但 OpenRig 默认只支持 Codex 协议。我们需要注册一个deepseekservice。
**实操步骤