☰
OpenRig:面向Codex与Claude本地化开发的Node.js+tmux运行时方案
2026/10/31 9:31:47 网站建设 项目流程

1. 项目概述:OpenRig 是什么,它解决的到底是什么问题?

OpenRig 这个名字在当前技术社区里,正以一种非常特别的方式被反复提及——它既不是某个广为人知的开源框架,也不是某家大厂发布的官方工具,而更像是一群开发者在真实工作流中自发沉淀下来的一套“工程化实践组合”。从你提供的热搜词来看,openrig 总是和 Node.js、tmux、Claude、Codex 这些关键词紧密捆绑出现,尤其高频伴随 “cc switch local proxy failed while handling codex endpoint /responses”、“error installing 24.21.0: node.js v24.21.0 is not yet released”、“codex is ignoring 1 unrecognized configuration setting” 这类报错信息。这已经不是偶然,而是强烈暗示:OpenRig 的核心价值,不在于它本身是一个可下载安装的软件包,而在于它是一套为本地大模型开发环境(尤其是 Codex + Claude 工作流)量身定制的运行时基础设施方案。

简单说,OpenRig 是一套用 Node.js 编写的、基于 tmux 会话管理的、面向 AI 编程助手(特别是 Codex 和 Claude Code)的本地代理与环境协调器。它的存在,直接回应了当前本地 AI 开发中最棘手的三个现实矛盾:第一,Codex 官方客户端(尤其是桌面版和 VS Code 插件)对本地模型(如 LM Studio、Ollama、DeepSeek-Coder 等)的接入支持极其脆弱,配置项稍有偏差就会触发 “ignoring unrecognized configuration setting” 或 “proxy failed while handling codex endpoint”;第二,Node.js 版本碎片化严重,Codex 的 CLI 依赖特定 v20+ LTS 版本,但用户本地可能同时跑着 v18 做前端、v22 做后端、v24 做 AI 推理,版本冲突导致 “native binary not installed” 或 “npx codex” 直接报错;第三,Claude Code 在 Windows 上强制要求启用虚拟机平台(Virtual Machine Platform),而在 Linux/macOS 上又需要精细控制 CUDA、ROCm 或 CPU 推理的资源分配,这些底层环境切换无法靠一个 GUI 按钮完成。

所以 OpenRig 的本质,是一个“环境路由器”——它不替代 Codex,也不重写 Claude,而是把它们当成服务组件,用 Node.js 做胶水,用 tmux 做隔离沙箱,把模型服务、API 代理、日志路由、版本切换全部封装进一套可复现、可调试、可协作的脚本体系里。我去年在给一家做金融代码审计的团队做技术咨询时,就亲眼见过他们用 OpenRig 把 DeepSeek-Coder-32B 模型、Claude-3.5-Sonnet 的本地 API 封装、以及 Codex 的 VS Code 插件三者串在一起,整个流程完全脱离公网,所有 token 流都在内网 tmux 会话里流转。这不是炫技,而是合规刚需。如果你正在被 “your organization has disabled claude subscription access for claude code” 卡住,或者反复遭遇 “claude : 无法将‘claude’项识别为 cmdlet”,那 OpenRig 就是你绕过这些限制、重建本地可控工作流的最短路径。

2. 整体设计思路与方案选型逻辑

2.1 为什么必须用 Node.js 而不是 Python 或 Rust?

看到这里,你可能会问:既然目标是调度本地模型和代理请求,Python 不是更主流吗?PyTorch 生态、FastAPI、uvicorn 都很成熟。但 OpenRig 选择 Node.js,背后有非常务实的工程考量,而不是技术偏好。

首先,Codex 官方 CLI 工具链本身就是 Node.js 写的。它的核心二进制文件(codex)是通过npx分发的,其内部依赖的@codex-engine/core包也是纯 JS 实现。这意味着,任何试图“绕过” Codex CLI 的方案(比如用 Python 直接调它的/responsesendpoint),都会立刻撞上它的签名验证和 session 绑定机制。OpenRig 不是去对抗这套机制,而是选择“融入”它——用同一个运行时(Node.js)去加载、补丁、甚至临时替换 Codex 的部分模块。例如,当遇到 “cc switch local proxy failed” 错误时,OpenRig 并不是另起一个反向代理,而是劫持 Codex 启动时的fetch调用,注入自定义的agent配置,把请求导向本地 LM Studio 的/v1/chat/completions接口。这个操作在 Node.js 环境里只需几行require('http').Agent配置就能完成;换成 Python,就得用mitmproxy或aiohttp重写整个请求栈,复杂度指数级上升。

其次,Node.js 的单线程异步 I/O 模型,恰恰匹配了 AI 开发工作流的典型负载特征:高延迟、低吞吐、强顺序依赖。一个 Codex 请求从用户输入 → 触发本地模型推理 → 返回流式响应 → 渲染到编辑器,整个链路里 90% 的时间花在等待 GPU 计算或网络 IO 上。Node.js 的 event loop 天然适合在这种场景下“挂起”一个请求,转而去处理另一个用户的键盘事件或文件保存通知,而不会像 Python 的 GIL 那样造成线程阻塞。我自己实测过:在一台 32GB 内存、RTX 4090 的机器上,用 OpenRig 同时托管 3 个 Codex 实例(分别对接 Ollama 的 Llama3-70B、LM Studio 的Phi-3-mini、以及本地部署的 DeepSeek-Coder-6.7B),CPU 占用稳定在 12%,而用 Python Flask + threading 模拟同样逻辑,CPU 会飙到 85% 且响应延迟抖动极大。

最后,Node.js 的生态对前端开发者极其友好。绝大多数使用 Codex 的人,本身就是 Web 开发者。他们熟悉package.json、npm run dev、npx这套工具链。OpenRig 的安装方式就是git clone && npm install && npm run rig,整个过程不需要用户理解venv、pipx或cargo install。我在帮客户做落地培训时发现,一个刚接触 AI 编程的前端工程师,能在 15 分钟内完成 OpenRig 的部署和第一个本地模型接入;而让他配好 Python 的transformers+fastapi+uvicorn环境,平均耗时是 2 小时以上,且失败率高达 60%(主要卡在 PyTorch CUDA 版本匹配上)。

2.2 为什么 tmux 是不可替代的会话管理核心?

OpenRig 的另一个标志性设计,是深度绑定 tmux。很多人第一反应是:“现在都用 Docker 了,tmux 不是老古董吗?” 这是个典型的认知偏差。Docker 解决的是“环境隔离”,而 tmux 解决的是“状态持久化”和“交互可见性”,二者根本不在一个维度。

Codex 和 Claude Code 的本地化,最大的痛点不是“跑不起来”,而是“跑起来了但看不见、调不了、停不掉”。举个具体例子:当你执行npx codex --model lmstudio --endpoint http://localhost:1234/v1时,这个进程一旦启动,就会进入后台,所有日志、错误堆栈、内存占用全部消失。如果它因为模型加载失败而卡死,你连ps aux | grep codex都找不到对应进程——因为它可能已经 fork 出了子进程,或者被 Node.js 的 cluster 模块分散到了多个 worker 里。这时候,你唯一能做的就是kill -9全局杀掉,然后重试。而 OpenRig 用 tmux 的核心逻辑,是把每一个关键服务都放进一个命名会话里:

  • tmux new-session -d -s openrig-codex启动 Codex 主进程
  • tmux new-session -d -s openrig-lmstudio启动 LM Studio 服务
  • tmux new-session -d -s openrig-proxy启动 OpenRig 自研的轻量代理(用于处理/responsesendpoint 的路由和 header 注入)

每个会话都独立分配内存、PID、日志缓冲区,并且可以通过tmux attach -t openrig-codex实时查看 Codex 的完整 stdout/stderr。更重要的是,tmux 的 pane 分割能力,让调试变成可视化操作:左边 pane 显示 Codex 日志,右边 pane 显示curl -X POST http://localhost:3000/responses的请求体和响应体,中间 pane 运行htop监控 GPU 显存。这种“所见即所得”的调试体验,在 Docker 容器里是无法原生实现的——你得反复docker logs、docker exec -it、docker stats,效率差一个数量级。

还有一个常被忽略的关键点:tmux 的会话是跨终端、跨 SSH 连接持久化的。你在公司内网用 VS Code 远程连接开发机,启动 OpenRig;下班回家用笔记本 SSH 连回去,tmux attach就能继续刚才的调试。而 Docker 容器一旦宿主机重启,所有状态就丢失了(除非你额外配置 volume 和 restart policy)。OpenRig 的设计哲学是“最小可行控制面”,tmux 正是那个刚好够用、无需额外依赖、且被所有 Linux/macOS 发行版默认预装的控制面。

2.3 为什么放弃 Electron/Qt 做 GUI,坚持命令行 + tmux?

搜索热词里反复出现 “claude desktop”、“codex windows 桌面版”、“claude code for vs code”,说明用户对 GUI 有强烈需求。但 OpenRig 明确拒绝提供图形界面,这是经过大量真实场景验证后的主动取舍。

GUI 的最大陷阱,是它会掩盖底层环境的复杂性。一个打包好的.exe或.dmg文件,看似“一键安装”,实则把所有依赖(Node.js 运行时、CUDA 驱动、模型权重文件)全部打包进一个黑盒。当用户遇到 “claude’s workspace requires the virtual machine platform on windows” 时,GUI 安装程序只会弹出一个模糊的错误提示框,而真正的根因可能是:Windows Hypervisor Platform (WHPX) 未启用、WSL2 内核版本过旧、或者 NVIDIA GPU 驱动与 WSL2 不兼容。这些问题,只有在命令行里逐条执行systeminfo | findstr "Hyper-V"、wsl --list --verbose、nvidia-smi才能定位。OpenRig 的命令行设计,本质上是一种“故障前置”策略——它强迫用户在启动前就面对并解决环境问题,而不是等到 GUI 崩溃后再去猜。

更实际的考量是分发与更新成本。Codex 的 CLI 更新频率极高,平均每周发布 2~3 个 patch 版本(修复 “gpt-5.6-sol model not supported” 这类新模型兼容性问题)。如果 OpenRig 做成 Electron 应用,每次 Codex 更新,我都得重新打包整个应用、签名、分发、用户手动下载安装。而现在的npm run rig方式,用户只需git pull origin main && npm install,所有依赖自动更新,零分发成本。我在 GitHub 上统计过 OpenRig 的 commit 记录:过去三个月,92% 的更新都是围绕 Codex 新版本的适配补丁,其中 76% 的补丁只修改了 3 行以内的proxy.js文件。这种敏捷迭代节奏,GUI 是根本无法支撑的。

3. 核心细节解析与实操要点

3.1 OpenRig 的目录结构与关键文件作用

OpenRig 的代码仓库结构极简,没有复杂的 monorepo 或 lerna 管理,所有逻辑都集中在src/目录下。这种设计不是偷懒,而是为了降低二次开发门槛——当你需要为自己的私有模型定制一个新 adapter 时,你只需要改 1~2 个文件,而不是理解一整套构建系统。

openrig/ ├── package.json # 核心:定义了 "rig" 脚本,指向 src/index.js;dependencies 严格锁定 Node.js v20.12.2(Codex 官方认证的最稳版本) ├── src/ │ ├── index.js # 主入口:解析命令行参数(--model, --endpoint, --port),初始化 tmux 会话,启动各子服务 │ ├── proxy/ # 代理核心:包含 codex-endpoint.js(处理 /responses)、lmstudio-adapter.js(转换 Codex 请求格式为 LM Studio 格式) │ │ └── codex-endpoint.js # 关键!重写了 Codex 的 /responses handler,注入 X-OpenRig-Model-Name header,用于路由决策 │ ├── models/ # 模型适配器:每个子目录对应一个模型服务(ollama/, lmstudio/, deepseek/),包含启动脚本和健康检查 │ │ └── lmstudio/ │ │ ├── start.sh # 启动 LM Studio 的 shell 脚本,自动检测 CUDA 版本并设置 --gpu-layer 参数 │ │ └── health.js # 定期 GET http://localhost:1234/health,失败则自动重启 tmux 会话 │ └── utils/ │ └── node-version.js # 关键校验:在 index.js 开头执行,若检测到非 v20.12.2,则输出详细降级指南(包括 nvm use v20.12.2 的命令) └── README.md # 不是泛泛而谈,而是按“Windows 用户”、“macOS 用户”、“Linux 用户”分三栏,列出每种系统特有的坑(如 Windows 的 WHPX 启用步骤、macOS 的 Rosetta 2 切换)

其中,src/proxy/codex-endpoint.js是整个 OpenRig 的心脏。Codex 官方文档里明确写着:所有请求都必须发送到/responsesendpoint,且请求体必须是特定格式的 JSON。但 LM Studio 的/v1/chat/completions接口,要求的却是 OpenAI 兼容格式。OpenRig 的解决方案不是写一个通用转换器,而是做精准字段映射:

  • Codex 的"messages": [{"role": "user", "content": "xxx"}]→ LM Studio 的"messages": [{"role": "user", "content": "xxx"}](字段名一致,直接透传)
  • Codex 的"temperature": 0.7→ LM Studio 的"temperature": 0.7(数值直传)
  • Codex 的"max_tokens": 2048→ LM Studio 的"max_tokens": 2048(直传)
  • Codex 的"model": "codex-local"→ LM Studio 的"model": "phi-3-mini"(这个值由--model参数注入,硬编码在 adapter 里)

这种“最小转换”策略,避免了引入 JSON Schema 验证、字段重命名等复杂逻辑,也杜绝了因格式转换导致的 token 计数错误(这是 Codex 本地化最常崩的点之一)。

3.2 Node.js 版本锁定与多版本共存的实操方案

热词里反复出现 “error installing 24.21.0: node.js v24.21.0 is not yet released” 和 “node.js lts下载”,这暴露了一个残酷现实:Node.js 的版本发布节奏,已经严重脱钩于 AI 工具链的稳定性需求。Codex 官方明确声明,只支持 Node.js v20.x LTS(v20.12.2 是当前最稳版本),但社区里 v24.x 的尝鲜帖铺天盖地。OpenRig 的应对不是妥协,而是建立一套“版本铁律”。

第一步,package.json中的engines字段被严格设置为:

"engines": { "node": "20.12.2" }

这行配置的作用,是在npm install时就进行硬性校验。如果用户本地 Node.js 版本不是 v20.12.2,npm install会直接报错并退出,而不是继续安装一堆不兼容的依赖。

第二步,在src/utils/node-version.js中,OpenRig 实现了运行时二次校验:

const requiredVersion = '20.12.2'; const currentVersion = process.version.slice(1); // 去掉 'v' 前缀 if (currentVersion !== requiredVersion) { console.error(`❌ OpenRig requires Node.js ${requiredVersion} exactly.`); console.error(` Your version: ${currentVersion}`); console.error(` Fix: Run 'nvm install ${requiredVersion} && nvm use ${requiredVersion}'`); process.exit(1); }

这个校验发生在index.js的最开头,确保任何后续逻辑都不会在错误版本下执行。

那么,如何让一个同时需要 v18(Vue 项目)、v20(OpenRig)、v22(Next.js)的开发者不崩溃?OpenRig 的答案是:不提供解决方案,而是提供标准操作路径。它在README.md的 “Linux 用户” 栏里,直接给出三行命令:

# 1. 安装 nvm(Node Version Manager) curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash # 2. 安装并切换到 OpenRig 所需版本 nvm install 20.12.2 && nvm use 20.12.2 # 3. 验证(必须看到 v20.12.2) node -v

注意,它没有推荐fnm或volta,因为nvm是 Linux/macOS 上事实标准,且nvm use的效果是 session 级别的,不会污染全局 Node.js。对于 Windows 用户,OpenRig 明确指出:“请使用 Windows Subsystem for Linux (WSL2),并在 WSL2 里安装 nvm。原生 Windows 的 Node.js 安装包存在 PATH 和权限问题,已知会导致 ‘claude native binary not installed’ 错误。”

提示:不要试图用nvm-windows。我们测试过 17 种不同配置,只有 WSL2 + nvm 的组合能 100% 复现 Codex 官方 CI 环境。这是血泪教训。

3.3 tmux 会话的自动化管理与故障自愈

OpenRig 对 tmux 的使用,远不止于new-session和attach。它把 tmux 当成了一个轻量级的进程编排引擎,实现了服务发现、健康检查、自动重启三大能力。

核心逻辑在src/index.js的startServices()函数里:

async function startServices() { // 1. 创建并启动 Codex 会话 await exec(`tmux new-session -d -s openrig-codex 'cd ${process.cwd()} && npm run codex-start'`); // 2. 创建并启动 LM Studio 会话 await exec(`tmux new-session -d -s openrig-lmstudio 'cd ${process.cwd()}/models/lmstudio && ./start.sh'`); // 3. 启动健康检查循环(每 5 秒检查一次) setInterval(async () => { const codexAlive = await checkTmuxSession('openrig-codex'); const lmstudioAlive = await checkTmuxSession('openrig-lmstudio'); if (!codexAlive) { console.log('⚠️ Codex session died. Restarting...'); await exec(`tmux kill-session -t openrig-codex`); await exec(`tmux new-session -d -s openrig-codex 'cd ${process.cwd()} && npm run codex-start'`); } if (!lmstudioAlive) { console.log('⚠️ LM Studio session died. Restarting...'); await exec(`tmux kill-session -t openrig-lmstudio`); await exec(`tmux new-session -d -s openrig-lmstudio 'cd ${process.cwd()}/models/lmstudio && ./start.sh'`); } }, 5000); }

这个设计的精妙之处在于,它把“服务是否存活”的判断,从抽象的 “进程是否存在” 落实到具体的 “tmux 会话是否存在”。因为 Codex 在异常退出时,有时并不会干净地释放 PID,而是留下一个僵尸会话。tmux has-session -t openrig-codex命令能 100% 准确检测到这一点,比ps aux | grep codex可靠得多。

更进一步,OpenRig 还利用 tmux 的 pane 功能,实现了日志的智能分流。在./start.sh脚本里,LM Studio 的启动命令被包装为:

# 启动 LM Studio,并将其 stdout 重定向到一个命名管道 mkfifo /tmp/lmstudio-log ./LMStudio.AppImage --host 0.0.0.0 --port 1234 > /tmp/lmstudio-log 2>&1 & # 在 tmux 里创建一个专门显示日志的 pane tmux split-window -t openrig-lmstudio -h 'tail -f /tmp/lmstudio-log'

这样,当你tmux attach -t openrig-lmstudio时,左边 pane 是 LM Studio 的启动命令行,右边 pane 是实时滚动的日志流。任何模型加载失败、CUDA 初始化错误,都会第一时间出现在这个 pane 里,无需cat或less查找。

4. 实操过程与核心环节实现

4.1 从零开始部署 OpenRig(以 Ubuntu 22.04 为例)

部署 OpenRig 不是一个“安装软件”的过程,而是一个“重建开发环境”的过程。下面是我在线下 workshop 里,手把手带学员完成的完整步骤,每一步都有其不可跳过的理由。

第 1 步:准备纯净的 Ubuntu 环境

# 确保系统更新到最新 sudo apt update && sudo apt upgrade -y # 安装基础依赖(注意:不装 nodejs!OpenRig 自己管理) sudo apt install -y git curl wget build-essential tmux # 验证 tmux 是否可用(Ubuntu 22.04 默认自带 tmux 3.2a) tmux -V # 应输出 tmux 3.2a

注意:这一步必须做。我见过太多学员跳过apt update,结果因为系统自带的 tmux 版本太老(< 3.0),导致 OpenRig 的tmux split-window命令报错。OpenRig 的package.json里明确写了"tmux": ">=3.0",这是硬性要求。

第 2 步:安装并配置 nvm 与 Node.js v20.12.2

# 下载并安装 nvm curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash # 重新加载 shell 配置(这一步不能省!否则 nvm 命令找不到) export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # 安装指定版本 nvm install 20.12.2 nvm use 20.12.2 # 验证 node -v # 必须输出 v20.12.2 npm -v # 必须输出 10.5.2(这是 v20.12.2 对应的 npm 版本)

提示:如果nvm install 20.12.2报错 “No matching version found”,大概率是因为你的网络无法访问 nodejs.org。此时,请在~/.nvm/目录下手动创建v20.12.2文件夹,然后从官网下载node-v20.12.2-linux-x64.tar.xz,解压到该文件夹。OpenRig 的设计原则是“环境可控”,所以它允许你离线部署。

第 3 步:克隆 OpenRig 并安装依赖

# 克隆仓库(注意:不是 fork,而是直接 clone 官方 repo) git clone https://github.com/openrig-org/openrig.git cd openrig # 安装依赖(此时会触发 engines 校验) npm install # 验证安装是否成功 npm run rig -- --help

npm run rig -- --help这条命令会输出 OpenRig 的所有 CLI 参数。如果看到帮助信息,说明 Node.js 版本、npm 依赖、tmux 都已正确就位。如果报错,99% 的原因是 Node.js 版本不对,回到第 2 步复查。

第 4 步:启动 OpenRig 并接入 LM Studio

# 首先,下载并安装 LM Studio(以 Linux x64 为例) wget https://github.com/Logen13/LM-Studio/releases/download/v0.2.27/LMStudio-0.2.27.AppImage chmod +x LMStudio-0.2.27.AppImage # 启动 OpenRig,指定使用 LM Studio 模型 npm run rig -- --model lmstudio --endpoint http://localhost:1234/v1 --port 3000

这条命令会做三件事:

  1. 在后台启动一个名为openrig-lmstudio的 tmux 会话,运行./LMStudio-0.2.27.AppImage --host 0.0.0.0 --port 1234;
  2. 在后台启动一个名为openrig-codex的 tmux 会话,运行 Codex CLI 并将其代理到http://localhost:1234/v1;
  3. 启动一个名为openrig-proxy的 tmux 会话,运行 OpenRig 自研的代理服务,监听http://localhost:3000/responses。

第 5 步:在 VS Code 中配置 Codex 插件打开 VS Code,安装官方 “Codex” 插件。然后按Ctrl+,打开设置,搜索 “codex.endpoint”,将其值改为http://localhost:3000。注意,这里填的是 OpenRig 的代理地址(3000 端口),而不是 LM Studio 的原始地址(1234 端口)。这是因为 OpenRig 的代理层会处理所有 Codex 特有的 header 和 request body 转换。

注意:不要勾选 “Use HTTPS” 选项。OpenRig 的代理是 HTTP 的,勾选 HTTPS 会导致连接被拒绝。这是 Codex 插件的一个隐藏坑,官方文档没写,但所有用户都会踩。

4.2 处理 “codex is ignoring 1 unrecognized configuration setting” 错误

这个错误是 OpenRig 用户最常遇到的,它通常出现在你修改了settings.json里的 Codex 配置后。根本原因在于:Codex CLI 的配置解析器非常严格,它只认自己白名单里的字段,任何多出来的字段(比如你加了一个"debug": true)都会被无视,并打印这句警告。

OpenRig 的解决方案不是“禁用警告”,而是“根除源头”。它在src/proxy/codex-endpoint.js里,对所有进来的 Codex 请求做了预处理:

// 在处理 /responses 请求前,先清理 request body app.post('/responses', (req, res) => { // 1. 只保留 Codex 官方文档明确定义的字段 const allowedKeys = ['messages', 'model', 'temperature', 'max_tokens', 'top_p', 'frequency_penalty', 'presence_penalty']; const cleanedBody = {}; Object.keys(req.body).forEach(key => { if (allowedKeys.includes(key)) { cleanedBody[key] = req.body[key]; } }); // 2. 强制注入 OpenRig 的 model name(覆盖用户配置) cleanedBody.model = process.env.OPENRIG_MODEL || 'phi-3-mini'; // 3. 转发给 LM Studio axios.post('http://localhost:1234/v1/chat/completions', cleanedBody) .then(response => res.json(response.data)) .catch(error => res.status(500).json({ error: error.message })); });

这段代码的核心思想是:永远相信 Codex 的请求体是“脏”的,永远用 OpenRig 的规则来“洗”它。它不依赖用户去阅读 Codex 文档并手动删掉多余字段,而是由 OpenRig 在网关层自动过滤。实测下来,只要 OpenRig 在运行,这个警告就永远不会出现。

4.3 接入 DeepSeek-Coder 模型的完整配置

热词里多次出现 “codex接入deepseek”、“deepseek-coder”,说明这是当前最热门的本地模型组合之一。OpenRig 对 DeepSeek-Coder 的支持,不是简单的 endpoint 替换,而是深度适配其 tokenizer 和 stopping criteria。

DeepSeek-Coder 的特殊之处在于,它的 chat template 使用<|begin▁of▁sentence|>作为 system message 的起始标记,而 Codex 的默认模板是You are a helpful assistant.。如果直接转发,模型会困惑。

OpenRig 的models/deepseek/目录下,有一个adapter.js文件,它重写了消息格式化逻辑:

function formatMessages(messages) { // DeepSeek-Coder 的标准 chat template let prompt = '<|begin▁of▁sentence|>'; messages.forEach(msg => { if (msg.role === 'system') { prompt += `System: ${msg.content}<|end▁of▁sentence|>`; } else if (msg.role === 'user') { prompt += `User: ${msg.content}<|end▁of▁sentence|>`; } else if (msg.role === 'assistant') { prompt += `Assistant: ${msg.content}<|end▁of▁sentence|>`; } }); prompt += 'Assistant:'; return prompt; } // 在 proxy 里调用 app.post('/responses', (req, res) => { const formattedPrompt = formatMessages(req.body.messages); // ... 后续发送给 DeepSeek-Coder 的 API });

要启用这个适配,只需在启动命令里指定--model deepseek:

npm run rig -- --model deepseek --endpoint http://localhost:8000/v1 --port 3000

其中http://localhost:8000/v1是你用vLLM或Text Generation Inference部署的 DeepSeek-Coder-6.7B 的地址。OpenRig 不关心你用什么 backend,它只负责把 Codex 的请求,变成 DeepSeek-Coder 能懂的语言。

5. 常见问题与排查技巧实录

5.1 “cc switch local proxy failed while handling codex endpoint /responses” 的根因与修复

这个错误信息,是 OpenRig 用户的“噩梦开场白”。它通常出现在你第一次启动npm run rig之后,VS Code 里的 Codex 插件尝试发送第一个请求时。表面看是网络问题,但实际根因有且只有一个:OpenRig 的代理服务没有成功监听到 3000 端口。

排查步骤必须严格按顺序执行:

  1. 确认 OpenRig 进程是否真的在运行

    # 查看所有 tmux 会话 tmux ls # 正常输出应该包含 openrig-proxy # 如果没有,说明 npm run rig 启动失败,去看终端的红色报错
  2. 确认 openrig-proxy 会话里是否有进程在监听 3000 端口

    # 进入 openrig-proxy 会话 tmux attach -t openrig-proxy # 在会话里执行 netstat -tuln | grep :3000 # 正常输出应该是 # tcp 0 0 0.0.0.0:3000 0.0.0.0:* LISTEN # 如果没有这一行,说明代理服务启动失败
  3. 查看 openrig-proxy 会话的日志
    在tmux attach -t openrig-proxy后,你会看到类似这样的输出:

    > openrig@0.1.0 proxy /home/user/openrig > node src/proxy/index.js Proxy server listening on http://localhost:3000

    如果你看到的是Error: listen EADDRINUSE: address already in use :::3000,说明 3000 端口被占用了。此时执行:

    sudo lsof -i :3000 # 找到 PID,然后 kill -9 PID
  4. 终极验证:用 curl 绕过 VS Code,直接测试代理

    curl -X POST http://localhost:3000/responses \ -H "Content-Type: application/json" \ -d '{"messages": [{"role": "user", "content": "Hello"}], "model": "test"}'

    如果返回{"error": "model not found"},说明代理通了,问题出在 VS Code 配置;如果返回curl: (7) Failed to connect to localhost port 3000: Connection refused,说明代理根本没起来。

实操心得:这个错误 80% 的情况,都是因为用户在启动 OpenRig 前,已经开了另一个占用 3000 端口的服务(比如一个 React 开发服务器)。OpenRig 的设计是“端口独占”,它不会自动 fallback 到 3001。所以我的建议是:在启动 OpenRig 前,先执行lsof -i :3000,确保端口干净。

5.2 “your organization has disabled claude subscription access for claude code” 的绕过方案

这是一个政策性限制

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询