openrig 实战:用 YAML 编排 Claude Code 与 Codex 多模型配置

发布时间:2026/10/1 19:45:23
openrig 实战:用 YAML 编排 Claude Code 与 Codex 多模型配置 1. 从零认识 openrig它到底解决什么问题第一次看到 openrig 这个名字很多人会以为是某个硬件项目毕竟 rig 这个词在英文里常指设备支架或者矿机机架。但如果你最近在折腾 Claude Code、Codex 这类命令行 AI 编程工具大概率已经在某个 issue 或者讨论帖里见过它。openrig 本质上是一个面向 AI 编程助手的配置编排层它把散落在各个工具里的模型接入、代理转发、会话管理、终端复用这些琐碎事情收敛成一套可版本化、可复用的 YAML 配置。我最初接触它是因为一个很具体的痛点手上同时跑着 Claude Code 和 Codex 两个 CLI一个要接本地 LM Studio 的模型一个要接 DeepSeek 的 API每次换项目就得手动改环境变量、改配置文件改完还经常忘记哪个项目用的是哪套。更麻烦的是这两个工具对配置文件的路径、字段命名、优先级规则都不一样Claude Code 认~/.claude/settings.jsonCodex 认~/.codex/config.toml一旦涉及本地代理转发还得再叠一层端口映射。openrig 的出现就是为了把这一堆东西抽象出来用一份 YAML 描述我要什么模型、走什么通道、在哪个项目里生效剩下的交给它去分发。它适合谁如果你只是偶尔用一下 Claude Code 写个脚本那确实没必要上这套东西。但如果你符合下面任意一条openrig 值得花半小时研究同时使用两个以上 AI 编程 CLI需要在本地模型和云端模型之间频繁切换团队里多人共用一套模型接入规范想把 AI 助手的配置纳入 Git 管理。这几种场景下手工维护配置的边际成本会迅速超过学习成本。需要说明的是openrig 目前并不是一个官方标准社区里存在多个同名或近似的实现有的偏向 tmux 会话编排有的偏向代理路由。下面我讲的这套思路是基于我实际用下来最顺手的一种组合方式核心是把 YAML 作为唯一事实来源tmux 作为运行时载体代理层作为模型接入的统一出口。你可以根据自己的工具链做裁剪。2. 核心设计思路为什么是 YAML 加 tmux 加代理层2.1 为什么选 YAML 而不是 JSON 或 TOML配置文件格式的选择看似小事实际影响很大。Claude Code 用 JSONCodex 用 TOML这两种格式各有拥趸但当你需要写注释、需要多行字符串、需要嵌套结构的时候YAML 的优势就出来了。比如你要描述一个模型接入配置里面包含 base_url、api_key 引用、模型名、超时时间、重试策略用 YAML 写出来是这样的models: local-qwen: provider: openai-compatible base_url: http://127.0.0.1:1234/v1 api_key_env: LOCAL_KEY model: qwen2.5-coder-32b timeout: 120 retries: 2 deepseek-chat: provider: openai-compatible base_url: https://api.deepseek.com/v1 api_key_env: DEEPSEEK_KEY model: deepseek-chat timeout: 60同样的内容用 JSON 写不能加注释多行处理别扭用 TOML 写嵌套层级一深就变得冗长。YAML 的缩进敏感确实容易踩坑但配合编辑器的 YAML 插件和 schema 校验这个问题基本可以忽略。更重要的是YAML 天然适合做配置的配置也就是元配置你可以用一份 YAML 生成多份下游工具的配置文件这在多工具协同场景下非常关键。2.2 tmux 在这里扮演什么角色很多人会问配置管理就配置管理为什么要扯上 tmux答案在于 AI 编程 CLI 的运行形态。Claude Code 和 Codex 都是长驻进程一次会话可能持续几十分钟甚至几个小时中间你要切换窗口去看代码、跑测试、查日志。如果每个 CLI 都开一个独立终端窗口很快桌面就乱了。tmux 的价值在于它把会话和窗口解耦你可以用一个 tmux session 承载多个 pane每个 pane 跑一个 AI 助手或者一个监控命令。openrig 和 tmux 结合的方式通常是通过tmuxp或者自定义脚本根据 YAML 里定义的布局自动拉起会话。比如你定义了一个叫ai-dev的 session里面左边 pane 跑 Claude Code右边 pane 跑 Codex下面再开一个 pane 跑日志监控。一条命令就能把整个工作环境恢复出来这对于每天要重复同样操作的人来说节省的时间非常可观。2.3 代理层为什么不可省略代理层是整套方案里最容易被低估的部分。表面上看Claude Code 和 Codex 都支持直接配置 base_url似乎不需要额外代理。但实际用起来代理层解决了三个硬问题。第一是协议差异。Claude Code 走的是 Anthropic 的 messages 格式Codex 走的是 OpenAI 的 responses 格式而本地模型或者第三方 API 往往只兼容其中一种。代理层做协议转换让上游工具无感知。第二是密钥管理。你肯定不想把 API key 明文写在每个工具的配置里代理层可以统一从环境变量或者密钥管理服务读取下游工具只认本地地址。第三是流量观测。代理层可以记录每个请求的耗时、token 消耗、错误码这些数据对于排查问题和成本控制非常有用。社区里常见的做法是用 LiteLLM 或者 one-api 这类项目做代理它们都支持 YAML 配置和 openrig 的思路天然契合。你只需要在 openrig 的 YAML 里声明这个模型走本地代理的哪个端口剩下的交给代理层处理。3. 实操落地从安装到跑通第一条链路3.1 环境准备与依赖安装在开始之前先把基础环境理清楚。我假设你用的是 macOS 或者 LinuxWindows 用户建议走 WSL2因为 tmux 在原生 Windows 上体验很差。需要安装的东西不多tmux、Python 3.10 以上、以及你选择的代理工具。# macOS brew install tmux python3.11 # Ubuntu/Debian sudo apt update sudo apt install -y tmux python3.11 python3.11-venv # 安装代理层这里以 LiteLLM 为例 pip install litellm[proxy]Claude Code 和 Codex 的安装各自有官方文档这里不展开。需要提醒的是Claude Code 对 Node 版本有要求建议用 nvm 管理 Node 版本避免和系统自带的冲突。Codex 如果是桌面版注意安装包来源尽量走官方渠道。安装完成后先验证基础命令可用tmux -V python3.11 --version litellm --version claude --version codex --version如果某个命令报找不到先解决 PATH 问题不要急着往下走。我见过太多人卡在这一步最后发现是 shell 配置文件没 source。3.2 编写 openrig 主配置文件openrig 的核心就是一份 YAML我习惯叫它openrig.yaml放在项目根目录或者~/.config/openrig/下。这份文件分几个大块模型定义、代理配置、工具映射、会话布局。version: 1 models: local-qwen: provider: openai-compatible base_url: http://127.0.0.1:4000/v1 api_key_env: LITELLM_MASTER_KEY model: qwen2.5-coder-32b context_window: 32768 deepseek-chat: provider: openai-compatible base_url: http://127.0.0.1:4000/v1 api_key_env: LITELLM_MASTER_KEY model: deepseek-chat context_window: 65536 proxy: engine: litellm listen: 127.0.0.1:4000 config_path: ./litellm_config.yaml log_level: info tools: claude-code: config_path: ~/.claude/settings.json default_model: deepseek-chat env: ANTHROPIC_BASE_URL: http://127.0.0.1:4000 ANTHROPIC_API_KEY: ${LITELLM_MASTER_KEY} codex: config_path: ~/.codex/config.toml default_model: local-qwen env: OPENAI_BASE_URL: http://127.0.0.1:4000/v1 OPENAI_API_KEY: ${LITELLM_MASTER_KEY} sessions: ai-dev: layout: main-vertical panes: - name: claude command: claude model: deepseek-chat - name: codex command: codex model: local-qwen - name: logs command: tail -f ./logs/proxy.log这份配置里models定义逻辑模型proxy定义代理层怎么起tools定义下游工具怎么接sessions定义 tmux 布局。四块之间通过模型名和端口关联改一处就能全局生效。3.3 代理层的 YAML 配置与启动LiteLLM 的配置单独一份文件因为它的字段和 openrig 的关注点不同。这份文件描述上游真实模型是什么、密钥从哪来、限流怎么设。model_list: - model_name: qwen2.5-coder-32b litellm_params: model: openai/qwen2.5-coder-32b api_base: http://127.0.0.1:1234/v1 api_key: os.environ/LMSTUDIO_KEY - model_name: deepseek-chat litellm_params: model: deepseek/deepseek-chat api_key: os.environ/DEEPSEEK_KEY general_settings: master_key: os.environ/LITELLM_MASTER_KEY database_url: null litellm_settings: drop_params: true set_verbose: false启动代理export LITELLM_MASTER_KEYsk-local-1234 export DEEPSEEK_KEY你的真实密钥 export LMSTUDIO_KEYlm-studio litellm --config ./litellm_config.yaml --port 4000启动后先用 curl 验证一下curl http://127.0.0.1:4000/v1/models \ -H Authorization: Bearer sk-local-1234返回模型列表就说明代理层通了。这一步不通后面全是白搭所以务必先验证。3.4 把 Claude Code 和 Codex 接到代理上Claude Code 的配置在~/.claude/settings.json关键字段是env里的ANTHROPIC_BASE_URL和ANTHROPIC_API_KEY。注意 Claude Code 对 base_url 的处理有个细节它会在后面拼/v1/messages所以你的代理必须支持这个路径。LiteLLM 默认支持但如果你用的是别的代理要确认一下。Codex 的配置在~/.codex/config.toml格式是 TOMLmodel qwen2.5-coder-32b model_provider local [model_providers.local] name Local Proxy base_url http://127.0.0.1:4000/v1 env_key OPENAI_API_KEY这里有个坑Codex 的env_key指的是环境变量名不是密钥本身。你要确保OPENAI_API_KEY这个环境变量在启动 Codex 的 shell 里存在。我建议把这些 export 写进一个env.sh每次开新终端先 source 一下或者用 direnv 自动加载。3.5 用 tmux 一键拉起工作环境手动开三个终端太累写个脚本根据 openrig.yaml 自动拉起 tmux 会话#!/usr/bin/env bash set -euo pipefail SESSIONai-dev if tmux has-session -t $SESSION 2/dev/null; then tmux attach -t $SESSION exit 0 fi tmux new-session -d -s $SESSION -n claude tmux send-keys -t $SESSION:claude source ./env.sh claude C-m tmux new-window -t $SESSION -n codex tmux send-keys -t $SESSION:codex source ./env.sh codex C-m tmux new-window -t $SESSION -n logs tmux send-keys -t $SESSION:logs tail -f ./logs/proxy.log C-m tmux select-window -t $SESSION:claude tmux attach -t $SESSION这个脚本的逻辑很简单先检查会话是否存在存在就直接 attach不存在就按预设布局创建。send-keys后面的C-m相当于回车别漏了漏了命令不会执行。4. 常见问题与排查技巧实录4.1 代理转发失败的典型表现与定位社区里搜 cc switch local proxy failed while handling codex endpoint /responses 这类报错的人不少本质上是代理层不认识 Codex 发过来的请求格式。Codex 用的是 OpenAI 的 responses API而很多代理默认只处理 chat completions。解决办法有两个一是换用支持 responses 的代理版本二是在代理层做路径重写把/responses映射到/chat/completions并做格式转换。排查顺序建议这样先看代理日志有没有收到请求再看请求体格式最后看上游返回。如果代理日志里压根没有记录说明请求没到代理检查 base_url 和端口如果有请求但报 404检查路径如果报 400检查请求体字段。4.2 密钥与环境变量的那些坑codex auth token is unavailable这个报错我遇到过好几次原因五花八门。最常见的是环境变量没 export或者 export 在了错误的 shell 里。比如你在.zshrc里 export但 tmux 启动时用的是.bashrc那就读不到。另一个坑是密钥带了多余的空格或换行从网页复制的时候很容易带上。建议用echo -n $KEY | wc -c检查长度和预期对不上就是有问题。还有一点LiteLLM 的 master key 和上游真实 key 是两回事。下游工具用的是 master key代理层用 master key 鉴权后再用真实 key 去请求上游。不要把真实 key 配到下游工具里那样代理层就失去意义了。4.3 本地模型接入的上下文窗口问题用 LM Studio 跑本地模型的时候context_window这个参数很关键。Claude Code 默认会按 200k 上下文来组织请求如果你的本地模型只支持 32k请求会被截断或者直接报错。解决办法是在代理层做上下文裁剪或者在下游工具里显式设置最大 token 数。LiteLLM 支持max_input_tokens参数可以强制限制。另外本地模型的推理速度和显存占用要提前评估。32B 的模型在消费级显卡上跑首 token 延迟可能到好几秒交互体验和云端 API 差距明显。我的建议是本地模型只用来做代码补全和简单重构复杂任务还是走云端。4.4 tmux 会话管理的实用技巧tmux 用久了会发现几个痛点会话名记不住、窗口太多找不到、断线后会话丢失。针对第一个可以用tmux ls列出所有会话配合 alias 简化常用操作。针对第二个建议给窗口起有意义的名字用Ctrl-b w可以列出所有窗口快速跳转。针对第三个tmux 默认在服务器断线后会话还在但如果是本地机器重启就没了可以用tmux-resurrect插件做持久化。还有一个细节tmux 里的环境变量继承的是启动 tmux 时的环境如果你在 tmux 外面改了环境变量里面的会话不会自动更新。要么重启 tmux要么用tmux setenv手动同步。4.5 常见问题速查表现象可能原因排查动作代理启动报端口占用4000 端口被其他进程占用lsof -i :4000找到进程并处理Claude Code 报 401master key 不匹配检查下游 env 和代理 master_key 是否一致Codex 报 responses 404代理不支持 responses 路径升级代理版本或做路径重写本地模型响应超时模型加载慢或显存不足降低模型规模或增加 timeouttmux 里命令找不到PATH 未继承在 tmux 内重新 source 环境文件YAML 解析报错缩进用了 Tab 或冒号后缺空格用 yamllint 校验5. 进阶玩法让 openrig 真正融入日常开发流5.1 配置的版本化与团队共享把 openrig.yaml 和 litellm_config.yaml 纳入 Git 管理是这套方案从个人玩具变成团队基础设施的关键一步。但要注意密钥绝对不能进仓库。我的做法是仓库里只放模板文件用${VAR}占位实际值放在.env里.env加入.gitignore。新成员克隆仓库后复制.env.example为.env填入自己的密钥即可。更进一步可以用git-crypt或者sops对敏感文件加密这样连.env都能进仓库适合小团队协作。不过加密方案会增加上手成本人少的时候用.env就够了。5.2 多项目配置的继承与覆盖一个人同时维护多个项目每个项目的模型偏好可能不同。openrig 可以通过 YAML 的锚点和合并语法实现配置继承defaults: defaults timeout: 60 retries: 2 models: fast-model: : *defaults model: deepseek-chat timeout: 30 heavy-model: : *defaults model: qwen2.5-coder-32b timeout: 180: *defaults会把 defaults 里的字段合并进来同名字段以当前层为准。这样公共配置只写一次项目特有的覆盖掉就行。YAML 的锚点语法初看有点怪但用熟了能省很多重复。5.3 监控与成本控制代理层跑起来之后日志里会有每个请求的 token 消耗。把这些日志接到一个简单的分析脚本就能看到每天用了多少 token、花了多少钱。LiteLLM 支持把日志写到数据库配合 Grafana 可以做可视化。如果不想搞这么重用grep加awk也能凑合grep completion_tokens ./logs/proxy.log \ | awk -Fcompletion_tokens {sum$2} END {print sum}这个命令统计总 completion token 数虽然粗糙但够用。关键是养成定期看的习惯避免某个月账单出来才发现超支。5.4 踩过的坑与个人体会最后分享几个我实际踩过的坑。第一个是 YAML 的布尔值陷阱yes、no、on、off在 YAML 1.1 里会被解析成布尔值如果你本来想写字符串就会出问题。解决办法是加引号。第二个是 tmux 的send-keys对特殊字符的处理命令里如果有$或者反引号会被 shell 提前展开要用单引号包裹或者转义。第三个是代理层的超时设置默认值往往偏短本地模型跑长任务容易断建议把 timeout 调到 300 秒以上。这套方案不是银弹它解决的是多工具、多模型、多项目场景下的配置一致性问题。如果你的场景很简单手工配置反而更直接。但一旦工具数量超过两个或者需要在不同模型间频繁切换openrig 这种YAML 驱动、tmux 承载、代理统一的思路就能明显降低心智负担。我现在的日常是早上打开终端一条命令拉起整个 AI 开发环境三个窗口各司其职改配置只改一份 YAML剩下的交给脚本。这种顺畅感值得花一个下午把它搭起来。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询