Claude Code Router CI/CD 集成实战:3 个关键配置让 AI 代码审查稳定跑在 GitHub Actions
【免费下载链接】claude-code-routerOne local control plane for every AI agent: route across models, fuse new capabilities, orchestrate tools, and stay fully in control.项目地址: https://gitcode.com/GitHub_Trending/cl/claude-code-router
本文以 GitHub Actions 为例,讲一套 Claude Code Router CI/CD 集成的最小做法。先说清为什么交互式 AI 命令行工具在 CI 环境里会挂起,再给出一个可直接套用的工作流,随后逐个解释非交互模式、密钥注入与超时这三类配置。最后介绍按任务分档模型来控制 API 成本,以及排错时最常踩的几个坑。
🧭 CI 里 AI 工具为什么会挂起
为终端设计的 CLI 遇上无终端的 Runner
Claude Code 一类的命令行工具生来为交互设计:等用户输入、用颜色渲染提示、随时可中断。
GitHub Actions 的 Runner 恰好相反:没有 TTY,没有键盘,标准输入是空的。进程一旦读取输入就会一直等下去,任务显示在运行,实际上一步都没走。
更隐蔽的后果是日志停止滚动。平台监控到长时间无输出会直接判定超时杀掉任务,你损失的是一整轮 Runner 分钟数,却只得到一条含糊的超时记录。
用非交互模式配置解决挂起
要解决这件事,只需一个配置项:把NON_INTERACTIVE_MODE设为true。
CCR 检测到该配置后会自动处理环境差异:设置CI=true,关闭彩色输出与 readline 交互,关闭标准输入管道。进程不再等待任何人工输入,所有输出直接进入任务日志。
{ "NON_INTERACTIVE_MODE": true, "API_TIMEOUT_MS": 300000, "Providers": [ { "name": "openrouter", "api_base_url": "https://openrouter.ai/api/v1/chat/completions", "api_key": "$OPENROUTER_API_KEY", "models": ["anthropic/claude-3.5-sonnet"] } ], "Router": { "default": "openrouter,anthropic/claude-3.5-sonnet" } }下一节就用这份配置组装完整工作流。
最小可运行工作流:PR 触发 AI 代码审查
15 行以内的工作流
目标是让一个 PR 自动跑一次代码审查。流程只有四步:拉代码、装 Node、装 CCR、执行审查。
on: pull_request: branches: [main] jobs: review: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '22' - run: npm install -g @musistudio/claude-code-router - run: ccr code --review env: OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}npm 包安装的 CLI 需要 Node 22 及以上,安装后会启动同一个本地网关,默认监听127.0.0.1:3456,Agent 与兼容的 API 客户端都指向这个端点即可。
密钥与配置各放哪里
两个原则,都关于安全:
- API 密钥只走 secrets,YAML 里用
${{ secrets.XXX }}引用并挂到步骤的env上。YAML 通常是公开的,明文密钥一旦提交就是泄露。 - 上一节的 JSON 要落盘到
~/.claude-code-router/config.json,用带引号定界符的 heredoc(<< 'EOF')写入,这样$OPENROUTER_API_KEY原样进入文件,由 CCR 在加载时解析,而不是被 shell 提前替换。
密钥插值与超时设置
环境变量插值让配置可以提交
CCR 在配置文件里支持$VAR与${VAR}两种写法,加载时替换为进程环境中的实际值。
上一节配置里的$OPENROUTER_API_KEY就是靠这个机制生效的:密钥只存在于 Runner 环境中,配置文件本身不含敏感信息,可以放心入库复用。
⚠️ 插值发生在配置加载阶段。某个变量在进程环境里不存在时,请求会以无效凭据直接失败,报错指向鉴权而不是配置。
超时按环境分档设置
API_TIMEOUT_MS约束单次上游 API 请求的等待上限,默认 600000,也就是 10 分钟。
CI 里更希望快速失败、尽早释放 Runner,建议调低。参考值如下:
| 场景 | API_TIMEOUT_MS 建议 | 理由 |
|---|---|---|
| 交互式开发 | 600000(默认) | 给慢响应留余地 |
| CI/CD 流水线 | 120000 – 300000 | 快速失败,减少等待 |
| 长时批量分析 | 1800000 | 复杂任务需要完整时间 |
超时之外,还可以为路由配置备用模型:主模型失败后自动切换到下一个重试,避免单次抖动直接打断流水线。更多配置项可参考仓库内的 docs/README.md。
💰 按任务拆分模型,控制 API 成本
Router 分档
CCR 的 Router 配置允许给不同场景各指定一个「供应商 + 模型」组合,请求按入口名路由。
不要所有请求都走同一档模型,按任务拆档:
"Router": { "default": "openrouter,anthropic/claude-3.5-sonnet", "background": "openrouter,anthropic/claude-3.5-haiku", "think": "deepseek,deepseek-reasoner", "longContext": "openrouter,google/gemini-2.5-pro-preview", "longContextThreshold": 60000 }longContextThreshold是触发条件:单次请求上下文超过约 60000 token 时,自动改走longContext档,而不是靠人工判断。
各档位的成本对照
| 任务 | Router 入口 | 模型档位 | 成本 |
|---|---|---|---|
| 后台轻量任务 | background | 小/快模型 | 低 |
| 标准代码审查 | default | 中档 API | 中 |
| 深度推理 | think | 推理模型 | 高 |
| 长上下文分析 | longContext | 长上下文模型 | 高 |
工作流中用CLAUDE_ROUTER_MODEL环境变量指定某一步走哪个入口,不同 job 就能各用各的档位:
🛠 常见坑与排错
任务因长时间无输出被杀
平台会对 6 分钟内没有日志输出的任务做超时判定,而 AI 任务在等待模型响应时恰恰最安静。
对策是两件事:给 job 设置合理的timeout-minutes;开启 CCR 的请求日志,让日志流在任务期间持续滚动,既避免被判挂起,也留下排错现场。
heredoc 与密钥的两类典型故障
- heredoc 定界符忘了加引号,
$OPENROUTER_API_KEY先被 shell 吃掉,CCR 拿到的是空值或字面量,表现为鉴权失败。 - secret 拼写不一致时,报错指向鉴权错误而非「变量未定义」,排查时先核对步骤
env是否真的引用了对应的 secret。
另外两类错误可直接对号入座:401 查密钥,429 查供应商限流,超时类报错回头核对API_TIMEOUT_MS。
把日志存成构建产物
排错依赖现场,把日志目录上传为 artifact:
- uses: actions/upload-artifact@v4 if: always() with: name: ccr-logs path: ~/.claude-code-router/logs/非交互模式解决「能不能跑」,密钥与超时配置解决「跑得稳不稳」,Router 分档解决「花多少钱」。先把最小工作流跑通,再按需叠加产物归档与多档位路由即可。
【免费下载链接】claude-code-routerOne local control plane for every AI agent: route across models, fuse new capabilities, orchestrate tools, and stay fully in control.项目地址: https://gitcode.com/GitHub_Trending/cl/claude-code-router
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考