OpenRouter 排障指南:API 网关原理、常见报错与 Claude Code 接入
OpenRouter 是一个把多家大模型供应商统一成一个 API 入口的网关服务。它本身不训练模型,也不负责最终推理,而是把客户端的请求转发给背后的模型供应商,再把生成结果返回给调用方。正因为多了这一层代理关系,“OpenRouter Is Having Issues”这句话在实际开发里出现频率很高:昨天还能用的模型今天突然 429;Key 明明有余额却一直提示鉴权失败;模型列表里翻来翻去就是找不到别人提到的 stealth/ox-alpha。下面按“先懂原理、再跑通请求、然后排查报错、最后接入 Claude Code”的顺序,把常见问题和排查思路整理成一套可以直接用的清单。
1. 先理解 OpenRouter 的定位:为什么会有“OpenRouter Is Having Issues”
1.1 网关层、模型层和调用方的三角关系
OpenRouter 在很多项目里被直接当成“一个大模型”来用,这是后续不少问题的源头。
OpenRouter 的实际角色更像 API 网关:
- 客户端向 OpenRouter 发送带 API Key 的请求;
- OpenRouter 根据请求里的
model字段、账号权限、路由策略,把请求转发给上游模型供应商; - 上游供应商返回结果后,OpenRouter 再转发给客户端;
- 计费、限流、日志、模型列表,都由 OpenRouter 这一层统一处理。
所以一次请求是否成功,不只取决于 OpenRouter 本身,还取决于上游供应商的状态。
一个请求失败,可能发生在四个位置:
| 位置 | 常见表现 | 说明 |
|---|---|---|
| 客户端本身 | 参数格式错误、Key 没传、模型 ID 写错 | 请求还没到模型层 |
| OpenRouter 网关 | 限流、余额不足、模型未授权 | 网关层拦截 |
| 上游供应商 | 服务过载、模型下线、上下文超限 | 请求已转发出去 |
| 网络链路 | 超时、连接被中断 | 响应没有正常回到客户端 |
理解这层关系之后,再看“OpenRouter Is Having Issues”就有个基本判断:很多问题不是 OpenRouter“挂了”,而是某个具体模型或供应商不可用,或者请求本身不合法。
1.2 “Is Having Issues”通常体现在哪几类场景
当开发者在社区或状态页看到类似信息时,通常对应以下场景:
| 场景 | 现象 | 最优先检查 |
|---|---|---|
| 模型不可用 | 某模型返回 404 或 400 | 模型 ID 是否还有效 |
| 网关限流 | 大量 429 | 请求频率和 Key 配额 |
| 供应商故障 | 503、超时、空回复 | 官方状态页 |
| 账号问题 | 401、403、402 | Key、权限、余额 |
| 模型下架 | 列表里找不到某个 ID | 模型的发布状态 |
“OpenRouter 正在出问题”很多时候不是一个孤立的软件 Bug,而是模型供应链中的某个环节出现波动。排查时不要只盯着状态页,要从自己的请求开始逐层确认。
2. 从注册、Key、充值到跑通第一个请求
2.1 创建账号和 API Key 时最容易被忽略的细节
注册入口在 OpenRouter 官网,创建 API Key 的位置是账号下的 Keys 区域。常见易错点有三个。
第一,Key 只在创建页面完整展示一次。刷新页面后只能看到 Key 的一部分,后续想找回完整值只能重新创建。所以创建后要立即保存到本地密钥管理工具,不要直接贴进代码仓库。
第二,API Key 要作为Authorization: Bearer <KEY>请求头传递,不是写在 JSON 请求体里。很多第一次接入的开发者在messages旁边顺手写了一个api_key字段,这种写法不会被 OpenRouter 识别。
第三,充值入口在 Billing/Credits 页面。实际支持的支付方式会随账号所在地区和官方政策变化,判断标准以官方 Billing 页面列出的选项为准。不要在聊天、截图或日志里暴露 Key,也不要轻信非官方代充渠道。
2.2 用 curl 验证 Key 和模型是否可用
在写代码之前,先用 curl 验证一遍基本链路。这样可以区分“Key 的问题”和“代码的问题”。
export OPENROUTER_API_KEY="sk-or-v1-你的Key" export OPENROUTER_MODEL="上面查到的模型ID" curl https://openrouter.ai/api/v1/chat/completions \ -H "Authorization: Bearer $OPENROUTER_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "'"$OPENROUTER_MODEL"'", "messages": [ {"role": "user", "content": "你好,请回复三个字"} ] }'如果 Key 有效、模型可用、余额足够,会返回类似下面的结构:
{ "id": "gen-xxxx", "model": "openai/gpt-4o", "choices": [ { "message": { "role": "assistant", "content": "你好。" } } ], "usage": { "prompt_tokens": 18, "completion_tokens": 8, "total_tokens": 26 } }重点看三处:
- 响应里是否包含
choices[0].message.content; - 是否返回错误对象,比如
error.code; usage是否正常记录 token 数。
如果请求失败,错误通常长这样:
{ "error": { "code": 402, "message": "Insufficient credits", "metadata": {} } }先记录code和message,再按后面的排查链路定位。
2.3 用 models 接口查模型 ID,别靠猜
OpenRouter 的模型 ID 通常带模型供应商前缀,比如openai/gpt-4o、anthropic/claude-3.5-sonnet这种格式。模型 ID 是大小写敏感的,也不能随意省略前缀。
查询当前账号可用的模型列表:
curl https://openrouter.ai/api/v1/models | jq '.data[].id'如果环境里没有jq,可以用 Python:
curl -s https://openrouter.ai/api/v1/models | python3 -m json.tool | grep '"id"'拿到列表后,再对照项目代码里配置的模型 ID,能避免大量“模型不存在”的问题。如果某个模型不在列表里,不要执着于改目标模型的名字去猜,更合理的做法是先确认该模型是否属于 OpenRouter 官方目录。
在实际项目里,OpenAI 官方 Python SDK 也能直接接入 OpenRouter,只需要改base_url和api_key:
from openai import OpenAI client = OpenAI( base_url="https://openrouter.ai/api/v1", api_key="sk-or-v1-你的Key", ) resp = client.chat.completions.create( model="openai/gpt-4o", messages=[{"role": "user", "content": "你好"}], ) print(resp.choices[0].message.content)这里要提醒:OpenRouter 的模型目录是动态的。同一个模型 ID,可能在几天内从免费变付费,也可能被上游供应商调整上下文长度。代码里不要硬编码“永久有效”的假设。
3. 常见报错:429、401、403、402、400、404 的排查链路
3.1 429 是限流,不是网络卡顿
HTTP 429 表示请求过多。在 OpenRouter 场景里,它通常来自两个层面:OpenRouter 网关限制,或上游模型供应商限制。
常见原因包括:
- 同一个 Key 在短时间内发起了大量并发请求;
- 使用的是免费模型,免费模型通常有更严格的速率限制;
- 某个模型在社区里热度高,上游供应商排队严重;
- 代码里没有重试逻辑,失败后立刻重复请求。
处理 429 时,先看响应头里有没有Retry-After或类似限流字段。如果有,按 Header 指示的秒数等待。不要无限重试,也不要从 1 毫秒开始快速循环。
推荐做法是使用指数退避:第一次失败后等 1 秒,第二次等 2 秒,第三次等 4 秒,最多重试 3 到 5 次。同时要区分哪些状态值得重试:
| 状态码 | 是否建议重试 | 说明 |
|---|---|---|
| 429 | 是 | 限流,等待后重试 |
| 5xx | 是 | 服务端或上游异常,可重试 |
| 401 | 否 | Key 问题,重试没有意义 |
| 402 | 否 | 余额问题,需先充值 |
| 400 | 权当参数问题,先修复再重试 | |
| 404 | 视情况 | 模型或接口不存在,先核对 |
3.2 401、403、402 分别指向 Key、权限和余额
这几个状态码最容易混淆,因为表现都是“请求被拒绝”。
| 状态码 | 含义 | 典型原因 | 第一步检查 |
|---|---|---|---|
| 401 | 鉴权失败 | Key 错误、Key 被撤销、Header 格式不对 | 重新换取 Key 并确认 Header |
| 403 | 无权限 | 账号受限、模型未授权、Key 权限范围不足 | 检查 Key 的权限设置和模型访问范围 |
| 402 | 需要付费 | 余额不足,或该模型不允许透支 | 查看 Billing 余额,充值或换免费模型 |
实际项目中,最容易出现的错误是把 403 当成 Key 错误,反复换 Key。403 要先看账号本身是否被限制,再看模型是否是当前账号可用的模型。
3.3 400、404 和模型不存在:为什么找不到 stealth/ox-alpha 这类 ID
“为什么我在 OpenRouter 的 API 配置后找不到 stealth/ox-alpha 这个模型”是典型的模型 ID 排查问题。
先说结论:OpenRouter 的模型目录以官方/api/v1/models返回的结果为准。你在其他渠道看到的模型 ID,不一定等于 OpenRouter 目录里的 ID。
找不到某个 ID,通常有几种可能:
- 大小写或路径错误。
Stealth/Ox-Alpha、stealth/OxAlpha这类写法都不会被目录匹配。 - 该模型并不是 OpenAI 兼容命名规范里的标准 ID。比如某些第三方工具内部使用自定义名称,落到 OpenRouter 时需要一个映射。
- 该模型已经下架、改名或只在特定供应商路由下开放。
- 该 ID 来自非官方镜像或转发服务,根本不是 OpenRouter 的模型。
- 模型需要账号满足一定条件才能使用,普通账号查不到。
建议的核对顺序:
curl https://openrouter.ai/api/v1/models | jq '.data[].id' | grep -i 'ox-alpha'如果返回结果为空,基本可以判断该 ID 不在当前 OpenRouter 目录中。此时不要硬配,应该在代码里换成实际存在的模型。
遇到“某人的教程里写了一个模型,但你这里找不到”的情况,不要怀疑自己的 Key 有问题。先更新模型列表,再核对模型 ID 是否完整,最后检查是不是代理工具或第三方配置里动了映射。
4. 用 OpenRouter 接入 Claude Code:环境变量和 CC-Switch 的正确姿势
4.1 Claude Code 真正需要的是三个信息
Claude Code 这类终端工具,本质上是一个客户端。它需要知道三件事:
- 请求发到哪个服务端;
- 用哪个身份凭证;
- 使用哪个模型。
对应到 OpenRouter 场景,就是三个环境变量:
| 环境变量 | 作用 | 示例值 |
|---|---|---|
ANTHROPIC_BASE_URL | 设置 API 端点地址 | OpenRouter 的 Anthropic 兼容端点 |
ANTHROPIC_AUTH_TOKEN | 设置身份凭证 | sk-or-v1-... |
ANTHROPIC_MODEL | 设置模型 ID | anthropic/claude-3.5-sonnet这类 ID |
这里要特别说明:OpenRouter 的端点地址会随官方文档更新,不同 SDK 可能使用不同兼容路径。配置前先打开 OpenRouter 官方文档,看 Anthropic 兼容端点当前是什么,再填写到ANTHROPIC_BASE_URL,不要照搬旧文章里的地址。
4.2 最小环境变量配置和验证方式
在终端里先导出环境变量,再启动 Claude Code:
export ANTHROPIC_BASE_URL="https://openrouter.ai/api/v1/anthropic" export ANTHROPIC_AUTH_TOKEN="sk-or-v1-你的Key" export ANTHROPIC_MODEL="anthropic/claude-3.5-sonnet" claude上面的地址是否可用,要以 OpenRouter 官方文档为准。如果启动后报 404,先去/api/v1/models确认模型 ID,再确认ANTHROPIC_BASE_URL是否被写成了带多余路径的地址。
一个常见坑是:只设置了ANTHROPIC_AUTH_TOKEN,却忘了设置ANTHROPIC_BASE_URL。这种情况下 Claude Code 会请求 Anthropic 官方端点,结果就是鉴权失败或网络错误。
4.3 CC-Switch 能解决什么,不能解决什么
CC-Switch 是社区里用来切换 Claude Code 模型提供方配置的工具。它通常帮你把不同提供方的 Base URL、Token、模型 ID 写进目标配置文件,省去每次手改环境变量的步骤。
它能解决的问题是“多套配置切换太繁琐”。
它不能解决的问题是:
- 不能解决 Key 本身无效的问题;
- 不能解决余额不足的问题;
- 不能解决模型 ID 不在 OpenRouter 目录里的问题;
- 不能解决端点地址过时的问题。
使用 CC-Switch 后如果配置不生效,按这个顺序检查:
- 切换工具写的配置文件路径是否真的被 Claude Code 读取;
- 环境变量和配置文件哪个优先级更高;
- 切换后是否重启了终端进程;
- 当前 shell 里是否残留旧的
ANTHROPIC_*环境变量。
清除残留环境变量可以这样操作:
unset ANTHROPIC_BASE_URL unset ANTHROPIC_AUTH_TOKEN unset ANTHROPIC_MODEL然后再执行切换工具的切换动作,确保配置干净。
5. 余额、免费模型和成本控制:别把网关当成免费出口
5.1 余额、费用和计量口径
OpenRouter 的费用不是按“一次请求多少钱”来算的,而是按模型单价和 token 消耗来算。同一个模型,输入和输出 token 的价格往往不同。
一次请求的消耗会体现在响应体里的usage字段:
{ "usage": { "prompt_tokens": 120, "completion_tokens": 45, "total_tokens": 165 } }实际扣费金额取决于:
prompt_tokens和completion_tokens各自的数量;- 模型定价表里输入、输出 token 的单价;
- 是否开启了额外功能,比如结构化输出、缓存等。
控制成本的方向也有几个:
- 请求前先确认目标模型的单价,不要所有请求都用最贵的旗舰模型;
- 对长上下文场景设置合理上限,避免系统提示词过长;
- 在代码里缓存重复请求的结果;
- 为不同业务使用不同 Key,方便账单审计。
这里要注意,免费模型不意味着可以无限使用。免费模型的速率限制通常更严格,稳定性也更依赖上游供应商的剩余容量。生产环境如果对响应质量有严格要求,不要把关键业务完全绑定在免费模型上。
5.2 免费模型的限制和适用场景
| 对比项 | 付费模型 | 免费模型 |
|---|---|---|
| 请求速度 | 相对稳定 | 可能排队 |
| 速率限制 | 取决于套餐和 Key | 通常更严格 |
| 模型稳定性 | 较高 | 可能随时下架 |
| 适合场景 | 生产、商业、对延迟敏感 | 学习、原型、批量延迟任务 |
免费模型通常不需要从余额扣费,但这不代表账号没有余额也可以访问所有付费能力。遇到 402 时,不要纠结“我没用付费模型为什么还要钱”,先看当前模型是否真的属于免费范围。
6. 遇到 “OpenRouter Is Having Issues” 时的一套排障清单
6.1 按顺序排查的 8 个步骤
面对“OpenRouter 出问题”,最忌讳一上来就看状态页然后干等。推荐的排查顺序是:
| 步骤 | 检查项 | 验证方式 |
|---|---|---|
| 1 | 官方状态页是否报告大范围故障 | 看 OpenRouter status 页面 |
| 2 | 本地 Key 是否有效 | 用 curl 发最小请求 |
| 3 | 请求是否到达 OpenRouter | 看返回状态码和响应体 |
| 4 | 模型 ID 是否存在 | 查/api/v1/models |
| 5 | 余额是否足够 | 看 Billing 页面 |
| 6 | 端点路径是否写错 | 核对官方文档 |
| 7 | 是否触发限流 | 看 429 和响应头 |
| 8 | 上游供应商是否故障 | 换一个模型复现 |
如果换一个模型后恢复正常,问题大概率不在 OpenRouter 主服务,而在某个具体模型或供应商上。
6.2 生产环境使用 OpenRouter 的最佳实践
接入 OpenRouter 时,要把它当成一个外部依赖,而不是本地 SDK。生产环境至少考虑下面几项:
- 为 429 和 5xx 编写指数退避重试,重试间隔逐次递增;
- 不要把 Key 硬编码在代码或配置库里,使用环境变量或密钥管理服务;
- 记录请求的
id、状态码、模型、耗时,方便追查是哪一层失败; - 对模型 ID 做可配置化,避免每次模型下架都改代码;
- 在批量执行前先用小请求验证模型、参数和上下文长度;
- 定期拉取模型列表,及时发现已下架或改名的模型;
- 开发环境和生产环境使用不同 Key,便于限额和审计;
- 对关键模型增加健康检查,不能只依赖 OpenRouter 状态页。
6.3 适合继续练习的三个方向
如果刚接触 OpenRouter,可以按这三个方向练手,能覆盖绝大多数真实场景:
第一,写一个命令行小工具,输入list时打印当前可用模型,输入对话时发送请求并打印本次 token 消耗。这个工具能让你熟悉模型列表、API 请求和响应结构。
第二,在脚本里加入基于状态码的重试逻辑。重点处理 429、5xx 和 401 的不同策略,理解哪些错误值得重试,哪些错误重试也没有意义。
第三,把某个终端工具接入 OpenRouter,用环境变量控制 Base URL、Token 和模型 ID。遇到配置不生效时,用unset清理环境变量,比盲目改配置文件更有效。
OpenRouter 的价值在于用一套 API 访问多个模型,但这也意味着排障链路比单一模型供应商更长。遇到“OpenRouter Is Having Issues”时,先确认自己的请求有没有问题,再看模型目录,最后才判断是不是平台整体故障。这个顺序,能帮你从大多数“看起来像平台故障”的问题里快速走出来。
