OpenRouter 是一个把多家大模型接口聚合到一起的 API 路由平台。最近公开的数据显示,它的周 token 处理量在过去两年增长了约 9000 倍。这个数字单独看会让人觉得夸张,但放到大模型应用快速普及的这两年,其实是符合直觉的:模型厂商越来越多,开发者不想为每个模型单独注册账号、单独申请 API Key、单独维护计费逻辑,而是希望一个 Key 能调用所有主流模型。OpenRouter 解决的就是这个诉求。
这篇文章适合三类人看:正在做 LLM 应用开发、想对比多个模型效果、或者被登录失败、403、token 失效这类问题卡住的开发者。我会按六个部分拆:平台价值、账号与计费、调用流程、成本控制、报错排查、选型边界。整个过程按实际测试的顺序来,先跑通单条请求,再谈批量和生产化。
1. 为什么一个统一的模型网关能涨 9000 倍
1.1 核心定位:一张 API Key 调用所有主流模型
OpenRouter 做的事情,本质上是一个大模型网关。它把 OpenAI、Anthropic、Google、Meta、Mistral 等多家厂商的模型接口,统一成一套 OpenAI 兼容的请求格式。你只需要在平台注册一个账号、拿到一个 API Key,之后请求不同模型时只改model字段,不用改请求地址,不用改鉴权方式。
这个价值对做 LLM 应用的团队非常直观。以前接三个模型,要维护三套 SDK、三个计费后台、三个 Key 的轮换逻辑。走 OpenRouter 之后,一套请求代码可以横跨十几个模型,切模型只改一个字符串。很多 Agent 类工具和开源客户端支持填自定义 API 地址,填上 OpenRouter 的地址就能在不同模型之间切换,这也是它被广泛使用的原因之一。
1.2 9000 倍增长背后的三个推动因素
第一个因素是模型供给爆发。过去两年新增的开源和闭源模型数量非常多,开发者做评测、做路由、做备灾,都需要一个能快速访问所有新模型的地方。OpenRouter 这类平台天然适合承担"模型超市"的角色。
第二个因素是 Agent 类应用大量出现。Agent 的逻辑里经常需要同一个任务换不同模型试效果,或者让不同模型分工。统一网关能显著降低这类代码的维护成本。
第三个因素是低门槛测试。平台上有不少免费模型,也有按量计费的模型,新用户不需要先买大额套餐,充一点钱就能把所有接口试一遍。这对早期开发者和小团队很友好。
1.3 和直连官方 API 的差别
直连官方接口的优势是稳定、延迟可控、功能更新最快。OpenRouter 这类网关的优势是接入成本低、模型选择多、切换灵活。两者不是替代关系,更像不同阶段的工具。
| 对比维度 | 直连官方 API | 走 OpenRouter 网关 |
|---|---|---|
| 接入成本 | 每个厂商单独注册、单独熟悉文档 | 一次接入,统一格式 |
| 模型种类 | 只有该厂商的模型 | 多个厂商模型集中可选 |
| 计费方式 | 各厂商独立账单 | 统一 Credits 余额 |
| 稳定性 | 相对更可控 | 多一层网关,需关注服务状态 |
| 适用阶段 | 生产环境、长期固定调用 | 原型验证、多模型对比、快速切换 |
2. 动手之前:注册、额度和 token 的两层含义
2.1 先区分"登录 Token"和"API Key"
token这个词在 OpenRouter 相关讨论里有两个完全不同的含义,很多人混淆之后就容易卡壳。
第一个含义是文本计费单位。大模型把文本切分成 token 来计算输入输出量,1 个 token 大约对应 0.7 到 1 个英文单词,中文通常一个字会占 1 到 2 个 token。文章标题说的"周 token 量激增 9000 倍",指的就是这种文本处理量。
第二个含义是鉴权凭证。登录站点、第三方账号授权时会出现access token、refresh token,请求 API 时用的是 API Key。你在代码里实际使用的,是创建好的 API Key,而不是登录状态的 Token。
我见过很多新手把这两个概念混在一起,登录报错时去代码里查 API Key,API 报 401 时又去重新登录账号。先分清这两层,后面排查会快很多。
2.2 注册、API Key 和 Credits 的关系
注册在 OpenRouter 官网完成。正常流程是:注册账号、登录控制台、在 API Keys 页面创建 Key、给账号充值 Credits,之后用 Key 发起请求,每次请求按 token 用量从 Credits 里扣费。
很多新用户会问"刚注册有多少额度"。这个信息会随平台运营策略变化,我不建议把某个固定的注册赠送额度当成长期事实。最稳妥的办法是登录控制台看当前余额,再找一个免费模型跑一条最小请求,确认链路是通的。
Credits 是预付余额,token 是计费单位,用量是请求返回结果里usage字段给出的数值。三者关系是这样的:每次请求耗用一定数量的 token,平台按模型单价折算成费用,从 Credits 里扣除。
2.3 免费模型和低成本验证
控制台里有模型列表,部分模型标注为免费。第一次测试时,先用免费模型或者最便宜的小模型跑通,不要一上来就调用最大参数模型。免费模型通常有速率限制,适合验证请求格式、鉴权、输出解析,不适合大流量生产。
注意:免费模型能跑通,不代表它适合批量生产。速率限制、上下文长度、稳定性都需要单独评估。
3. 从单条请求到批量任务:完整调用流程
3.1 最基础的 Chat Completions 请求
OpenRouter 的接口路径是/api/v1/chat/completions,请求格式与 OpenAI 兼容。用一个最简单的 curl 示例:
curl https://openrouter.ai/api/v1/chat/completions \ -H "Authorization: Bearer $OPENROUTER_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "openai/gpt-4o-mini", "messages": [ {"role": "user", "content": "用一句话介绍 OpenRouter"} ] }'请求成功后,返回的 JSON 里会有choices数组,里面是模型生成的内容,还有usage字段,里面是本次请求消耗的 token 数量。
环境变量OPENROUTER_API_KEY需要提前设置好。不建议把 Key 硬编码到代码里,尤其是要提交到仓库的时候。
3.2 Python 调用和核心参数
用 Python 的requests库可以快速写一个可复用的调用函数:
import requests API_KEY = "sk-or-v1-xxxxxxxx" def chat_once(model, user_content, max_tokens=512): resp = requests.post( "https://openrouter.ai/api/v1/chat/completions", headers={ "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json", }, json={ "model": model, "messages": [{"role": "user", "content": user_content}], "max_tokens": max_tokens, "temperature": 0.7, }, timeout=60, ) resp.raise_for_status() data = resp.json() content = data["choices"][0]["message"]["content"] usage = data.get("usage", {}) return content, usage几个核心参数的判断标准:
| 参数 | 作用 | 建议 |
|---|---|---|
model | 指定模型 ID | 必须先在控制台确认模型 ID 完整准确 |
messages | 对话上下文 | 第一轮用 user,多轮要带上历史 |
max_tokens | 限制最大输出长度 | 按任务需要设置,别给太大 |
temperature | 控制随机性 | 0 到 1 之间微调 |
timeout | 请求超时时间 | 默认可以设 30 到 60 秒,长文本任务要放宽 |
3.3 批量任务怎么设计
批量调用和单条调用完全不是一回事。单条跑通只是起点,批量要面对的是并发、失败重试、输出保存、日志记录。
我建议的顺序是:
- 先用一条样例确认请求、响应、解析逻辑都正常。
- 再用一个 3 到 5 条的小列表跑一遍串行循环,看总耗时和输出格式。
- 确认稳定之后,再加并发。并发数不要一上来就拉满,从 3 到 5 开始,逐步加。
一个带并发控制的示例思路:
from concurrent.futures import ThreadPoolExecutor, as_completed def run_batch(items, model, max_workers=4): results = [] with ThreadPoolExecutor(max_workers=max_workers) as executor: futures = { executor.submit(chat_once, model, item["content"]): item for item in items } for future in as_completed(futures): item = futures[future] try: content, usage = future.result() results.append({"item": item, "content": content, "usage": usage}) except Exception as exc: results.append({"item": item, "error": str(exc)}) return results注意几个点:
ThreadPoolExecutor是线程级并发,适合 I/O 密集型请求。如果单机要跑很大的量,再考虑异步方案或任务队列。- 并发加大的时候,可能触发平台的速率限制,报 429 或者 HTTP 5xx。遇到这种情况,先降低并发数,加入重试逻辑。
- 重试要有退避机制,比如第一次等 1 秒,第二次等 2 秒,第三次等 4 秒。不要无脑重试,那样只会把网关打得更堵。
3.4 处理流式输出
如果任务需要实时展示生成内容,可以用stream: true。响应会变成 SSE 格式,每一行是一个事件:
resp = requests.post( "https://openrouter.ai/api/v1/chat/completions", headers={ "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json", }, json={ "model": "openai/gpt-4o-mini", "messages": [{"role": "user", "content": "讲一个短笑话"}], "stream": True, }, timeout=120, ) for line in resp.iter_lines(): if not line: continue text = line.decode("utf-8") if text.startswith("data: "): data_text = text[6:] if data_text == "[DONE]": break # 这里解析 JSON,取出 delta.content流式请求有两个容易踩的坑:一是超时时间要设置得比非流式更长,二是解析必须按 SSE 格式逐行处理,不能直接当成完整 JSON。如果只是后台跑任务、不需要实时反馈,建议不用流式,逻辑更简单。
4. Token 用量统计与成本控制
4.1 从返回结果读懂 token 消耗
每次正常请求返回的usage结构一般是这样的:
{ "usage": { "prompt_tokens": 12, "completion_tokens": 34, "total_tokens": 46 } }prompt_tokens是输入消耗,completion_tokens是输出消耗,total_tokens是总和。做成本核算的时候,一定要把输入和输出分开,因为很多模型对输入 token 和输出 token 的单价不一样,输出往往更贵。
4.2 成本估算方式
单次请求的成本可以这样估算:
成本 = prompt_tokens / 1000000 × 模型输入单价 + completion_tokens / 1000000 × 模型输出单价不同模型的价格差异非常大。小模型的成本可能只是大模型的几十分之一。开发阶段用便宜模型,正式上线再根据效果决定要不要升级,是更常见的做法。
4.3 控制成本的五个手段
第一,限制max_tokens。很多任务根本不需要长输出,把上限设到合理范围,能避免模型"话痨"式输出烧 token。
第二,模型降级。先判断任务对模型能力的真实要求。简单分类、信息抽取,用小模型就够了,不需要每次都调用顶级模型。
第三,缓存重复请求。如果业务里有大量相同或相似的输入,可以在本地加一层缓存,命中后直接返回缓存结果,不产生 token 消耗。
第四,批量任务控制并发。并发过高导致报错重试,重试也会产生 token 消耗,而且浪费更多时间。稳定的批量策略比激进并发更省钱。
第五,定期查看控制台用量报表。设置余额提醒,不要等账单跳出来才发现某个任务异常消耗了大量 token。
4.4 平台增长对使用者意味着什么
周 token 量两年增长 9000 倍,说明有大量开发者和应用在往这个平台走。对使用者来说,这是双刃剑。
好处是模型池会持续扩充,平台有更多资源投入稳定性,生态工具也会越来越多。坏处是流量集中之后,免费额度、速率限制、定价策略都可能调整。我的建议是:把它当作重要的模型入口之一,但不要在核心生产链路上做唯一依赖,保留切换回官方 API 或其他平台的代码能力。
5. 高频报错排查:登录失败、403、token 失效
5.1token exchange failed到底是什么
热搜里有很多人搜sign-in could not be completed token exchange failed。这个报错出现在账号登录流程里,尤其是使用第三方账号或 OAuth 授权登录的时候。
token exchange failed的意思是:登录过程中,授权服务器尝试用临时授权码换取访问 Token 时失败了。这不是你的 API Key 有问题,也不是模型调用有问题,而是登录环节的问题。
排查顺序:
- 清掉浏览器旧 Cookie 和登录缓存,重新走一遍登录流程。
- 检查第三方账号授权状态,看是不是在授权页取消了确认。
- 确认网络环境能正常访问登录服务,有时是运营商 DNS 或网络波动导致授权请求发送失败。
- 看具体错误码。如果错误信息里有
error sending request,一般是网络请求层面没到服务器;如果是403 forbidden,则是服务端拒绝了请求。
5.2403 country, region, or territory not supported怎么处理
错误信息里带country, region, or territory not supported,含义很清楚:当前网络所在地区不在该服务支持范围内。这是服务方的商业策略和合规策略,不是技术配置问题。
遇到这种提示,正确的处理方式是查看官方支持地区和状态说明,确认服务是否覆盖你所在的区域。如果服务没有覆盖,应该选择当地合规可用的同类平台或服务,不要尝试用非官方方式绕过限制。作为开发者,在编码和部署时也要按照服务条款来,避免给业务带来不必要的合规风险。
这里特别提醒:很多开发者在代码里拿到了403,第一反应是怀疑 Key 不对,或者接口地址写错。不要急着改代码,先确认地区支持状态,否则会浪费很多时间。
5.3401 unauthorized和invalid token
如果请求 API 时返回401 unauthorized或invalid token,排查顺序是:
- 检查 API Key 是否复制完整,有没有多空格、少字符。
- 检查请求头格式,必须是
Authorization: Bearer <你的 Key>。 - 检查环境变量是否正确加载,很多本地能跑、部署后报 401 的问题都出在环境变量没传对。
- 检查 Key 是否被误删或重置过。在控制台重新创建一个 Key,再做对比测试。
5.4 模型不存在和上下文超长
model not found通常不是网关问题,而是模型 ID 拼写错误。在控制台模型列表里复制完整 ID,不要手动缩写。
上下文超长则表现为context length exceeded之类的错误。处理办法是:减少历史消息数量,或者给历史消息做摘要,或者改用上下文窗口更大的模型。不要为了塞下全部内容硬调max_tokens,那解决不了问题。
常见报错排查表:
| 报错现象 | 可能原因 | 排查优先级 |
|---|---|---|
| 登录时报 token exchange failed | 浏览器缓存、OAuth 授权、网络波动 | 先清缓存,再查网络 |
| 登录时 403 country not supported | 地区不在支持范围 | 看官方支持名单,不要绕过 |
| API 请求 401 invalid token | Key 错误、格式错误、环境变量未加载 | 先检查 Key 和请求头 |
| model not found | 模型 ID 拼写错误 | 去控制台复制完整 ID |
| context length exceeded | 消息太多,超出模型窗口 | 截断或摘要历史 |
| 请求超时 | 网络波动、服务压力、timeout 太短 | 先加 timeout,再查状态页 |
6. 什么场景适合接 OpenRouter,什么场景要谨慎
6.1 推荐接入的四种场景
第一种是原型验证。产品还在验证阶段,不确定最终用哪个模型,用统一网关快速做 A/B 对比,效率最高。
第二种是多模型评测。想做模型效果基准测试,或者为不同任务选不同模型,OpenRouter 可以一套脚本测完所有模型。
第三种是 Agent 工具链。Agent 经常需要动态决定调用哪个模型,统一网关能减少代码分支。
第四种是客户端工具接入。很多 AI 客户端和 CLI 工具支持自定义 API 地址,填一个 OpenRouter Key 就能在不同模型间切换。
6.2 要谨慎的三种场景
第一种是严格合规场景。企业数据出境、行业监管、数据隐私有硬性要求时,数据经过第三方网关会增加合规复杂度。这类场景要先过法务和安全评估。
第二种是高可用生产场景。如果业务对延迟、错误率、可用性有严格 SLA,多一层网关就多一个故障点。线上问题定位会多一层排查成本。
第三种是超大规模成本敏感场景。当请求量级很大时,直连官方 API 的批量折扣和网络链路优化,可能比走网关更有成本优势。这时候要重新算一笔账。
6.3 我的选型建议和落地清单
按我自己的经验,比较稳的做法是这样:
- 用 OpenRouter 做模型发现、评测、快速切换的入口。
- 核心业务如果只依赖某一个模型,且调用量已经稳定,优先考虑直连官方 API。
- 如果要长期使用网关,提前整理好日志格式、用量统计、余额告警,不要等出问题再补。
下面是落地时我会盯住的检查清单:
- 单条请求跑通,确认返回结构和 usage 字段能正常解析。
- 用免费或低成本模型做稳定性小测,观察连续请求的成功率。
- 批量任务加上超时、重试、退避、输出命名规则。
- 控制台设置余额预警。
- API Key 用环境变量或密钥管理服务保存,不要提交到代码仓库。
- 保留切换模型或切换服务商的抽象层,避免业务和某个网关强绑定。
个人更建议的做法:把 OpenRouter 当成一个"模型超市 + 快速切换层",而不是唯一依赖。单条请求先跑通,再考虑批量;日志先看全,再改参数。真正消耗时间的地方往往不是模型效果,而是鉴权、计费和输入输出格式不一致。先把这些基础问题处理干净,后面无论接多少个模型,都不会手忙脚乱。