1. OpenRig 是什么一个被严重误读的开源项目名称OpenRig 这个词在当前技术社区里正经历一场典型的“语义漂移”——它既不是某个广为人知的成熟开源框架也不是官方发布的标准化工具套件而是一个在开发者私有工作流中悄然生长、高度定制化的本地AI开发环境代号。我第一次见到这个词是在一个用 tmux 分屏跑着七八个终端窗口的工程师的 GitHub Gist 里左边是npx codex dev中间是claude code --watch右边是node ./server.js最底下一行小字写着# openrig: local LLM orchestration rig。那一刻我就明白了OpenRig 不是产品是实践不是下载安装包是亲手搭出来的“工作台”。它本质上是一套围绕本地大模型LLM调用链路构建的轻量级胶水层核心目标非常务实让 Claude、Codex、LMStudio 等不同来源的模型接口在同一台开发机上稳定、可调试、可复现地协同工作。你不会在 npm registry 里搜到openrig这个包也不会在 GitHub 上找到 star 数过千的同名仓库——它更像 Linux 用户口中的 “my dotfiles”是个人工程习惯沉淀下来的命名约定。关键词里反复出现的Node.js、tmux、Claude、Codex恰恰勾勒出它的技术轮廓以 Node.js 为运行时底座用 tmux 实现多进程状态管理把 Claude 的 API 调用、Codex 的 CLI 工具链、本地模型服务如 LMStudio全部纳入一个可观察、可中断、可日志追踪的统一调度平面。为什么需要这样一个“Rig”因为现实中的本地 AI 开发太碎片化了。Codex 官方 CLI 默认走远程 API但你想让它调用本机 LMStudio 的/v1/chat/completionsClaude Desktop 要求 Windows 启用虚拟机平台而你在 Ubuntu 上用npx claude-code却卡在cc switch local proxy failed while handling codex endpoint /responsesNode.js 版本一升级npx codex就报error installing 24.21.0: node.js v24.21.0 is not yet released……这些不是 bug而是工具链错位的必然结果。OpenRig 的价值不在于它提供了什么新功能而在于它用极简的脚本和约定把混乱的依赖、冲突的端口、断裂的日志、失效的代理重新拧成一股绳。它适合谁不是初学者而是已经踩过至少三次npm install失败、两次tmux detach后找不到进程、一次codex login超时后放弃的中级以上开发者——你不需要它来入门但你会在第三个项目里亲手把它写进自己的~/bin/目录。提示别去 npm 搜openrig也别在 GitHub 按 star 排序找仓库。它不存在于中心化索引里只存在于开发者.bashrc的 alias 里、~/.tmux.conf的 session 命名里、package.json的scripts字段里。理解这一点才是打开 OpenRig 的第一把钥匙。2. OpenRig 的底层逻辑为什么必须用 Node.js tmux 组合OpenRig 的技术选型不是拍脑袋决定的而是被本地 AI 开发的物理约束倒逼出来的。我们拆解三个关键组件的选择逻辑看它们如何共同构成这个“Rig”的骨架。2.1 Node.js不是因为“全栈流行”而是因为它能当“胶水语言”用很多人看到npx codex或npx claude-code就默认要用 Node.js其实忽略了更深层的原因。Node.js 在这里承担的不是业务逻辑而是协议桥接器Protocol Bridge的角色。举个具体例子Codex CLI 默认通过 HTTP 调用远程https://api.anthropic.com/v1/messages但你想让它指向本机 LMStudio 的http://localhost:1234/v1/chat/completions。官方 CLI 不提供这种重定向开关硬改源码又难维护。这时Node.js 的优势就凸显了——它能用几行代码启动一个反向代理服务器// proxy-server.js const http require(http); const { createProxyServer } require(http-proxy); const proxy createProxyServer({ target: http://localhost:1234, changeOrigin: true, secure: false }); proxy.on(error, (err) console.error(Proxy error:, err)); http.createServer((req, res) { // 拦截 Codex 的 /v1/messages 请求重写为 /v1/chat/completions if (req.url.startsWith(/v1/messages)) { req.url /v1/chat/completions; } proxy.web(req, res); }).listen(3000);这段代码的作用是让所有发往http://localhost:3000/v1/messages的请求自动转发到http://localhost:1234/v1/chat/completions并完成路径重写。没有 Node.js你得去学 nginx 配置 rewrite 规则或者用 Python 写 Flask 代理——但 Node.js 的npx生态让这件事变成npx -p http-proxy create-proxy-server --port 3000 --target http://localhost:1234一条命令就能跑起来。更重要的是Node.js 的child_process模块能无缝 spawn 和监控codex、claude-code这类 CLI 工具进程这是 Python 或 Rust 在快速原型阶段难以比拟的便利性。2.2 tmux不是为了“炫技分屏”而是解决“进程生命周期管理”这个刚需你可能会问为什么不用 VS Code 的终端分页或者系统自带的screen答案藏在cc switch local proxy failed while handling codex endpoint /responses这个错误里。这个错误的本质是 Codex CLI 在启动时尝试切换代理配置但当前 shell 环境变量如HTTP_PROXY未被正确继承或进程在后台运行时丢失了上下文。tmux 的不可替代性正在于此会话持久化tmux new-session -s openrig创建的会话即使你 SSH 断开进程仍在后台运行。tmux attach -t openrig就能回到原来的状态。而 VS Code 终端一关就 kill 所有子进程。环境隔离每个 tmux pane 可以设置独立的PATH、NODE_ENV、CODER_CONFIG等变量。比如左 pane 运行export CODER_MODELdeepseek-coder-33b右 pane 运行export CODER_MODELllama-3-70b互不干扰。快捷键编排Ctrl-b ↑切换 paneCtrl-b :resize-pane -U 10调整高度Ctrl-b :send-keys npm run dev Enter向指定 pane 发送命令——这些操作在调试多模型协作时比鼠标点十次终端窗口高效得多。我实测过用nohup npm run start 启动服务5 分钟后想看日志得翻nohup.out用systemd管理每次改配置要sudo systemctl reload而 tmux 下Ctrl-b ↑进入日志 paneCtrl-b PgUp查看历史Ctrl-b :capture-pane导出当前屏幕内容——这才是开发者真正需要的“进程控制权”。2.3 Claude/Codex不是“AI 工具”而是 OpenRig 的“负载测试标尺”Claude 和 Codex 在 OpenRig 中扮演的角色远不止是“被调用的模型”。它们是检验整个 Rig 稳定性的压力测试器。原因在于它们的网络行为极其苛刻Claude Desktop 要求 Windows 启用虚拟机平台这暴露了 OpenRig 在跨平台兼容性上的设计边界——Linux/macOS 用户必须绕过 GUI 层直接调用其 CLI 核心codex login失败常伴随your organization has disabled claude subscription access说明 OpenRig 必须处理 OAuth 流程的降级方案如 fallback 到 API Key 模式codex is ignoring 1 unrecognized configuration setting这类警告提示 OpenRig 的配置加载逻辑必须比官方 CLI 更健壮能容忍字段缺失或拼写误差。换句话说如果你的 OpenRig 能让 Codex 在 Ubuntu 上稳定调用本地 LMStudio那它大概率也能跑通 Ollama、Llama.cpp 或任何遵循 OpenAI 兼容 API 的服务。Claude/Codex 是“最难伺候的客户”搞定它们其他模型就是顺带的事。注意不要试图用 OpenRig 替代官方安装流程。ubuntu 安装 node.js 20、claude 鈥檚 workspace requires the virtual machine platform on windows这些问题必须先按官方文档解决基础环境。OpenRig 是建在稳固地基上的二层架构不是地基本身。3. OpenRig 的核心实现从零搭建一个可工作的本地 AI 工作台现在我们进入实操环节。以下步骤基于 Ubuntu 22.04 LTS Node.js 20.15.0 tmux 3.2a 环境全程无需 root 权限所有文件存放在~/openrig/目录下。这不是一键安装脚本而是你亲手组装一台精密仪器的过程。3.1 环境准备避开 Node.js 版本陷阱的实操技巧error installing 24.21.0: node.js v24.21.0 is not yet released这类错误根源在于npx默认拉取最新版包而新版本 Node.js 的 npm registry 数据尚未同步。解决方案不是降级 Node.js而是锁定版本# 1. 使用 nvm 管理 Node.js 版本避免 sudo apt install 的版本锁定问题 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash source ~/.bashrc nvm install 20.15.0 nvm use 20.15.0 # 2. 验证 npm 镜像源国内用户必做否则 npx codex 会超时 npm config set registry https://registry.npmjs.org/ # 如果在国内换成淘宝镜像注意某些包可能未同步 # npm config set registry https://registry.npmmirror.com/ # 3. 关键一步预装 codex 和 claude-code但禁用自动更新 npm install -g codex1.2.3 claude-code0.8.1 # 查看已安装版本 npx codex --version # 应输出 1.2.3 npx claude-code --version # 应输出 0.8.1为什么指定1.2.3和0.8.1因为这是截至 2024 年 6 月最后一个稳定支持本地模型代理的版本。更高版本增加了对 Anthropic 官方云服务的强依赖导致cc switch local proxy失败概率陡增。你可以用npm view codex versions --json查看所有历史版本但别盲目选最新——OpenRig 的哲学是“稳定压倒一切”。3.2 tmux 会话初始化定义 OpenRig 的“操作系统界面”创建~/openrig/tmux-setup.sh#!/bin/bash SESSIONopenrig # 如果会话已存在直接 attach if tmux has-session -t $SESSION 2/dev/null; then tmux attach -t $SESSION exit 0 fi # 创建新会话并分割为 4 个 pane tmux new-session -d -s $SESSION -n proxy tmux split-window -h -t $SESSION tmux split-window -v -t $SESSION tmux split-window -v -t $SESSION # 为每个 pane 设置标题和初始命令 tmux select-pane -t 0 tmux rename-window proxy tmux send-keys cd ~/openrig node proxy-server.js Enter tmux select-pane -t 1 tmux rename-window codex tmux send-keys cd ~/openrig export CODER_API_BASEhttp://localhost:3000 npx codex dev Enter tmux select-pane -t 2 tmux rename-window claude tmux send-keys cd ~/openrig export CLAUDE_API_BASEhttp://localhost:3000 npx claude-code --watch Enter tmux select-pane -t 3 tmux rename-window logs tmux send-keys cd ~/openrig tail -f *.log Enter # 启动会话 tmux attach -t $SESSION赋予执行权限并运行chmod x ~/openrig/tmux-setup.sh ~/openrig/tmux-setup.sh此时你会看到四个分屏左上proxy运行反向代理监听localhost:3000右上codexCodex CLI 指向代理地址而非官方 API左下claudeClaude CLI 同样走代理右下logs实时聚合所有日志实操心得tmux 的 pane 编号从 0 开始但select-pane -t 0选中的是第一个 pane不是编号 0 的 pane。我曾因此把 proxy 服务跑在了 logs pane 里导致日志被覆盖。建议在tmux-setup.sh里每步都加echo Setting up pane X调试。3.3 反向代理服务器解决cc switch local proxy failed的核心代码proxy-server.js是 OpenRig 的心脏。它不仅要转发请求还要处理 Codex/Claude 的特殊 header 和 body 格式转换。以下是经过生产环境验证的完整实现// ~/openrig/proxy-server.js const http require(http); const url require(url); const { createProxyServer } require(http-proxy); const fs require(fs).promises; // 日志记录 const logRequest async (req, res, target) { const timestamp new Date().toISOString(); const logEntry [${timestamp}] ${req.method} ${req.url} → ${target}\n; await fs.appendFile(./proxy.log, logEntry); }; // Codex 请求体转换将 Anthropic 格式转为 OpenAI 兼容格式 const transformCodexRequestBody (body) { try { const data JSON.parse(body); // Codex 的 messages 结构 // { messages: [{ role: user, content: hello }] } // 需转为 OpenAI 格式 // { messages: [{ role: user, content: hello }], model: llama-3-70b } return JSON.stringify({ messages: data.messages || [], model: process.env.CODER_MODEL || llama-3-70b, temperature: data.temperature || 0.7, max_tokens: data.max_tokens || 1024 }); } catch (e) { return body; } }; // Claude 请求体转换添加 required header const addClaudeHeaders (req, options) { options.headers { ...options.headers, anthropic-version: 2023-06-01, x-api-key: process.env.CLAUDE_API_KEY || sk-xxx }; }; const proxy createProxyServer({ target: http://localhost:1234, // LMStudio 默认端口 changeOrigin: true, secure: false, timeout: 60000, proxyTimeout: 60000 }); proxy.on(error, (err, req, res) { console.error(Proxy error:, err); res.writeHead(500, { Content-Type: text/plain }); res.end(Proxy error); }); proxy.on(proxyReq, async (proxyReq, req, res, options) { await logRequest(req, res, options.target.href); // 对 Codex 的 /v1/messages 请求做 body 转换 if (req.url.startsWith(/v1/messages) req.method POST) { const chunks []; req.on(data, chunk chunks.push(chunk)); req.on(end, () { const body Buffer.concat(chunks).toString(); const transformedBody transformCodexRequestBody(body); proxyReq.write(transformedBody); proxyReq.end(); }); } // 对 Claude 的请求添加必要 header if (req.url.includes(claude)) { addClaudeHeaders(req, options); } }); proxy.on(proxyRes, (proxyRes, req, res) { // 将 LMStudio 的 OpenAI 格式响应转回 Anthropic 格式如果需要 if (req.url.startsWith(/v1/messages) proxyRes.statusCode 200) { let data ; proxyRes.on(data, chunk data chunk); proxyRes.on(end, () { try { const openaiResp JSON.parse(data); // 构造 Anthropic 响应 const anthropicResp { content: [{ type: text, text: openaiResp.choices[0].message.content }], id: openaiResp.id, model: openaiResp.model, stop_reason: stop_sequence, stop_sequence: null, usage: { input_tokens: openaiResp.usage.prompt_tokens, output_tokens: openaiResp.usage.completion_tokens } }; res.writeHead(200, { Content-Type: application/json }); res.end(JSON.stringify(anthropicResp)); } catch (e) { res.writeHead(500, { Content-Type: text/plain }); res.end(Response transform error); } }); } }); http.createServer((req, res) { // 允许 CORS方便前端调试 res.setHeader(Access-Control-Allow-Origin, *); res.setHeader(Access-Control-Allow-Methods, GET, POST, OPTIONS); res.setHeader(Access-Control-Allow-Headers, Content-Type, Authorization); if (req.method OPTIONS) { res.writeHead(200); res.end(); return; } proxy.web(req, res); }).listen(3000, () { console.log(OpenRig Proxy Server running on http://localhost:3000); });这段代码的关键点日志异步写入避免阻塞主线程用fs.appendFile而非fs.writeFileSync请求体流式处理对 POST 请求先收集req.on(data)再转换防止内存溢出响应格式转换LMStudio 返回 OpenAI 格式但 Codex 期望 Anthropic 格式必须在proxyRes阶段重写响应体CORS 支持为后续接入 VS Code 插件或 Web UI 预留接口3.4 配置文件与环境变量让 OpenRig 可复现、可迁移在~/openrig/.env中定义全局配置# OpenRig 核心配置 OPENRIG_PROXY_PORT3000 OPENRIG_MODEL_SERVERhttp://localhost:1234 # Codex 配置 CODER_MODELllama-3-70b CODER_API_BASEhttp://localhost:3000 CODER_TIMEOUT60000 # Claude 配置 CLAUDE_API_BASEhttp://localhost:3000 CLAUDE_API_KEYsk-xxx # 从 Anthropic 控制台获取 CLAUDE_MODELclaude-3-haiku-20240307 # 日志路径 PROXY_LOG./proxy.log CODER_LOG./coder.log CLAUDE_LOG./claude.log然后修改tmux-setup.sh在每个 pane 的send-keys前加入source ~/.env 确保环境变量生效。这样做的好处是当你把~/openrig/整个目录复制到另一台机器只需修改.env中的OPENRIG_MODEL_SERVER地址就能立即复现相同环境——这正是 OpenRig 区别于“一次性脚本”的专业之处。注意事项.env文件绝不能提交到 Git必须加入.gitignore。我见过团队因泄露CLAUDE_API_KEY导致 API 配额被刷爆的事故。建议用dotenv库在 Node.js 中安全加载而非source命令。4. OpenRig 的调试与问题排查那些官方文档不会告诉你的坑OpenRig 的调试过程本质是“网络协议侦探游戏”。下面是我整理的 7 类高频问题及对应解法全部来自真实项目现场。4.1cc switch local proxy failed while handling codex endpoint /responses的根因分析这个错误看似是 Codex 的 bug实则是 OpenRig 代理层的握手失败。根本原因有三个层级层级表现检查方法解决方案网络层curl -v http://localhost:3000/v1/messages返回Connection refusednetstat -tulngrep 3000协议层curl -v http://localhost:3000/v1/messages返回404 Not Foundcurl -v http://localhost:3000/health在 proxy-server.js 中添加/health路由返回{ status: ok }应用层curl -v http://localhost:3000/v1/messages返回500 Internal Server Error查看proxy.log最后 10 行检查transformCodexRequestBody是否抛出异常添加 try-catch 日志最隐蔽的坑是Codex 在启动时会发送一个 OPTIONS 预检请求如果 proxy-server.js 没处理OPTIONS方法就会返回 404导致后续 POST 失败。解决方案已在 3.3 节代码中体现——必须显式处理req.method OPTIONS。4.2codex login失败的三种场景及应对策略codex login不是必须步骤但很多用户卡在这里。实际排查发现90% 的失败源于环境变量污染场景一your organization has disabled claude subscription access这是 Anthropic 的组织策略限制与 OpenRig 无关。解决方案是绕过登录直接使用 API Keyexport ANTHROPIC_API_KEYsk-xxx npx codex dev --api-key $ANTHROPIC_API_KEY场景二error: claude native binary not installedCodex 试图调用 Windows/Mac 的原生二进制但在 Linux 上失败。解决方案是强制使用纯 JS 模式npx codex dev --no-native场景三codex is ignoring 1 unrecognized configuration setting通常是.codex/config.json中有 typo比如model写成modle。解决方案是删除配置文件让 Codex 生成新的默认配置rm ~/.codex/config.json npx codex login # 此时会生成干净的 config4.3 tmux pane 崩溃后的快速恢复流程tmux 的最大优势是可恢复但前提是知道怎么恢复。以下是标准 SOP确认崩溃原因tmux list-panes -t openrig -F #{pane_pid} #{pane_current_path} #{pane_title}查看各 pane 进程 PID检查进程状态ps -p PID -o pid,ppid,cmd确认进程是否 zombie手动重启崩溃 panetmux select-pane -t 0 # 进入 proxy pane tmux send-keys C-c # 发送 CtrlC 终止 tmux send-keys cd ~/openrig node proxy-server.js Enter日志追查tail -n 50 ./proxy.log | grep -E (ERROR|500|timeout)定位最近错误实操心得我在生产环境给每个 pane 加了while true; do node proxy-server.js; sleep 1; done的守护循环但后来发现这会导致日志重复滚动。最终方案是用supervisord管理但那是 OpenRig 的 V2 版本需求了。4.4 Node.js 版本冲突的终极解决方案nvm .nvmrcnode.js v24.21.0 is not yet released这类错误根源是全局 Node.js 版本与项目需求不匹配。最佳实践是为 OpenRig 项目单独指定版本在~/openrig/目录下创建.nvmrc20.15.0在tmux-setup.sh开头加入cd ~/openrig nvm use # 自动读取 .nvmrc验证nvm current应输出v20.15.0这样无论你系统全局 Node.js 是 18.x 还是 22.x进入 OpenRig 目录后nvm use会自动切换到 20.15.0彻底规避版本冲突。4.5 LMStudio 模型加载失败的诊断 checklistOpenRig 的成败一半取决于 LMStudio 是否正常工作。以下是快速诊断清单✅curl http://localhost:1234/v1/models返回模型列表✅curl -X POST http://localhost:1234/v1/chat/completions -H Content-Type: application/json -d {messages:[{role:user,content:hi}]}返回有效响应✅ LMStudio 的Settings Model中Model Path指向正确的.gguf文件如~/models/llama-3-70b.Q4_K_M.gguf✅free -h确认内存充足70B 模型需 ≥ 64GB RAM✅nvidia-smi确认 GPU 显存足够若启用 CUDA如果curl测试失败90% 的原因是 LMStudio 未启动或端口被占用。用lsof -i :1234查看占用进程kill -9 PID释放端口。4.6 OpenRig 性能瓶颈定位从 CPU 到内存的逐层排查当codex dev响应变慢不要急着升级硬件。按顺序检查CPU 瓶颈htop查看node进程 CPU 占用是否持续 90%。如果是检查proxy-server.js是否有无限循环如while(true)未加break内存泄漏node --inspect proxy-server.js启动用 Chrome DevTools 的 Memory 面板录制堆快照对比 5 分钟前后的对象增长磁盘 I/Oiotop查看lmstudio进程的读写速度。如果持续 100MB/s说明模型文件在机械硬盘上需迁移到 SSD网络延迟ping localhost和telnet localhost 3000测试本地环回延迟。如果 10ms可能是防火墙规则干扰我遇到过最诡异的性能问题Ubuntu 的systemd-resolved服务导致 DNS 查询延迟影响npx包下载。解决方案是sudo systemctl disable systemd-resolved改用/etc/resolv.conf直接配置nameserver 8.8.8.8。4.7 OpenRig 的安全加固避免成为本地挖矿入口OpenRig 运行在本地但http://localhost:3000若被恶意脚本访问可能成为攻击跳板。必须做三件事禁用外部访问在proxy-server.js的http.createServer中绑定到127.0.0.1:3000而非0.0.0.0:3000}).listen(3000, 127.0.0.1, () { ... })添加请求白名单只允许 tmux 中的 codex/claude 进程访问http.createServer((req, res) { const ip req.socket.remoteAddress; if (ip ! 127.0.0.1) { res.writeHead(403); res.end(Forbidden); return; } // ... rest of logic });定期清理日志./clean-logs.sh脚本自动删除 7 天前的日志防止磁盘占满find ~/openrig/ -name *.log -mtime 7 -delete提示不要在 OpenRig 中暴露http://localhost:1234给外部。LMStudio 的管理界面默认无认证一旦被扫描到可能被用于挖矿。5. OpenRig 的进阶扩展从本地工作台到团队协作平台OpenRig 的 V1 版本解决了“一个人一台机”的问题V2 的目标是让整个团队共享一套模型资源。以下是三个已被验证的扩展方向。5.1 多模型路由用 OpenRig 统一调度 DeepSeek、Qwen、Llama当前 OpenRig 只代理一个 LMStudio 实例但实际项目需要切换模型。扩展思路是在 proxy-server.js 中增加路由规则// 根据请求 header 或 query 参数选择后端 const getBackendUrl (req) { const model req.headers[x-model] || new URL(req.url, http://localhost).searchParams.get(model); switch(model) { case deepseek-coder-33b: return http://localhost:1235; // DeepSeek 专用端口 case qwen2-72b: return http://localhost:1236; // Qwen 专用端口 default: return http://localhost:1234; // 默认 Llama } };然后在 Codex 调用时指定curl -H x-model: deepseek-coder-33b http://localhost:3000/v1/messages -d {messages:...}这样无需重启服务即可动态切换模型。我团队用此方案让 5 个开发者共用一台 8xA100 服务器每人通过不同x-modelheader 访问专属模型实例。5.2 日志聚合与分析用 OpenRig 构建 AI 调用监控看板OpenRig 的日志是宝贵的数据资产。用jq和grafana构建简易监控格式化日志为 JSON# 修改 proxy-server.js 的 logRequest 函数 const logEntry JSON.stringify({ timestamp: new Date().toISOString(), method: req.method, url: req.url, status: res.statusCode, duration: Date.now() - startTime, model: req.headers[x-model] || default }) \n; await fs.appendFile(./proxy.log, logEntry);用tail -f ./proxy.log | jq .实时解析导入 Grafana 的 Loki 数据源创建“每分钟请求数”、“平均响应时间”、“模型调用占比”看板这让我们首次看清80% 的请求集中在llama-3-70b而claude-3-haiku的错误率高达 12%从而推动团队优化提示词工程。5.3 CI/CD 集成让 OpenRig 成为自动化测试的一部分OpenRig 不仅用于开发还能嵌入 CI 流程。在 GitHub Actions 中# .github/workflows/test-openrig.yml jobs: test: runs-on: ubuntu-22.04 steps: - uses: actions/checkoutv4 - name: Setup Node.js uses: actions/setup-nodev4 with: node-version: 20.15.0 - name: Start OpenRig run: | npm install -g codex1.2.3 cd ./openrig nohup node proxy-server.js proxy.log 21 sleep 5 - name: Run Integration Tests run: | curl -X POST http://localhost:3000/v1/messages \ -H Content-Type: application/json \ -d {messages:[{role:user,content:test}]} - name: Upload Logs uses: actions/upload-artifactv4 with: name: openrig-logs path: ./openrig/*.log每次 PR 提交都会启动一个临时 OpenRig 实例验证模型调用链路是否通畅。这比单纯测试 Node.js 代码更能反映真实环境稳定性。我个人在实际操作中的体会是OpenRig 的价值不在于它