
做AI应用集成做久了总会有那么一个瞬间让人特别烦产品想换个更聪明的模型或者想给不同用户分配不同档位的模型结果发现每接一个新模型都要重新注册平台、申请密钥、读一遍文档、写一套兼容代码。更别提各家计费规则还不一样月底对账对得头疼。我后来把团队的项目统一切到了OpenRouter用一套API对接了500多个主流AI模型问题一下子简化了很多。这篇教程会从注册密钥讲起把调用方式、模型选型、多模型切换和降级、流式输出、成本控制这些关键环节都过一遍。不管你是准备在项目里接入AI能力还是想做模型效果对比或者只是厌倦了一家一家注册API这篇文章都值得花十分钟看完。1. 被每家一个API逼疯之后OpenRouter做了什么1.1 多模型接入的重复劳动清单先算一笔账。假设你的产品想用到大模型能力最朴素的方案是直接对接厂商API。接第一个模型你需要注册账号、申请密钥、读鉴权文档、写一个请求封装接第二个模型上述流程再来一遍如果还想接一个开源模型的托管服务又得重复一遍。等接了三四个模型光是适配层和维护不同密钥的成本就够占用一两个开发日。这还不是最难受的。各家返回的错误码不一样有的用HTTP状态码表达限流有的用业务错误码表达额度不足各家计费单位也不一样有的按token有的按请求次数。产品上线之后你还要在日志系统里给每个模型单独做统计。我见过一个项目接了五个模型最后光是对账脚本就写了三百行。1.2 OpenRouter把问题拆成了三层OpenRouter做的事情简单说就是把多模型接入这件事拆成了三层来解决。第一层是协议统一。它对外提供一个OpenAI兼容的Chat Completions接口也就是说你只要会调OpenAI格式的接口就能调通上面绝大多数模型。这个兼容性价值非常大因为市面上大部分AI开发框架和SDK本身支持自定义接口地址改一个base_url就能切过来。第二层是鉴权统一。一个API Key对应一个账户余额所有模型的计费都从同一个钱包里扣。你不用给每个厂商单独充值也不用记每家的密钥规则。第三层是生态统一。模型列表接口里直接给出上下文长度、单位定价、限流信息各种参数一目了然。选型对比不用再开十个浏览器标签页。打个比方以前你要去不同餐馆吃饭每家都得办一张储值卡、记一套点餐规矩OpenRouter相当于一个统一外卖平台把菜单集中到同一个页面你只管点菜剩下的事平台处理。1.3 模型生态速览OpenRouter上的模型覆盖面很广。从各家的旗舰推理模型到中等规模的通用对话模型再到完全开源的社区模型基本都能找到。模型命名遵循厂商/模型名的规律比如openai/gpt-4o-mini、anthropic/claude-3.5-sonnet、google/gemini-flash-1.5这样的格式一眼就能看出是哪个厂商的哪个版本。这个生态最实际的价值是你不需要为每个模型单独适配只要能找到模型ID就能用同一份请求体去测它。我做模型调研的时候通常一次性拉二三十个模型跑同一批测试问题半小时就能得到一份粗略的横向对比。这在以前是不可想象的效率。2. 第一次调用前要做好的三件事注册、密钥、余额2.1 注册与密钥创建权限粒度值得留意注册流程很简单去官网用邮箱注册后进到API Keys页面创建密钥就行。密钥是sk-or-v1-开头的长字符串类似其他平台的标准API Key格式。这里有一个很多人忽略的点OpenRouter允许创建多个Key我建议不要一个Key用到底。开发环境、测试环境、生产环境各用独立的Key万一某个Key泄露可以单独撤销它而不影响其他环境。密钥相当于你账户的总钥匙分得越细出事时可控范围就越大。还有一个容易被忽略的设置项官方文档推荐在请求里带上HTTP-Referer和X-Title两个自定义请求头。前者填你的站点地址后者填你的应用名称。这不是强制要求但带上之后平台可以根据来源识别你的应用流量对账户使用情况做更准确的统计。我习惯在自己封装的上层代码里统一加上这两个头避免每次调用重复写。2.2 充值逻辑它不像你想象的各家预付费OpenRouter的账户是预充值模式充的是美元余额不是某个具体模型的套餐。所有模型按各自的单价从这个统一余额里扣费。这里的优势要展开说如果你直接在多家厂商开户很可能遇到每家的最低充值门槛都高但单个项目根本用不完的情况。OpenRouter把预算集中到一个池子里哪个模型好用就花在哪个模型上不会出现钱分散在十个账户里各自吃灰的局面。我建议第一次充值先充少量金额够你跑几百次测试请求就行。等摸清了各模型的单价和你的调用量再决定要不要追加。查询余额很简单调用GET /api/v1/credits接口就能看到当前剩余额度代码里也能在报错信息里感知到余额不足。2.3 用curl跑通第一个请求环境准备好之后第一个请求建议用curl跑因为curl是排查网络问题最直接的工具不引入任何语言层的干扰。curl https://openrouter.ai/api/v1/chat/completions \ -H Authorization: Bearer sk-or-v1-你的密钥 \ -H Content-Type: application/json \ -d { model: openai/gpt-4o-mini, messages: [ {role: user, content: 用一句话介绍你自己} ] }如果你的网络能正常访问这个接口会收到一段JSON响应关键字段在choices[0].message.content里就是模型生成的内容。同时还有usage字段记录了这次请求消耗的输入和输出token数量。这里我要提醒一件事如果请求超时或者无响应先检查网络层的可达性再用curl -v看详细握手过程别一上来就怀疑接口写错了。排查基础连通性永远是最优先的步骤。3. 关键一步在500多个模型里选出当前任务最合适的那个3.1 模型列表接口透露的信息比想象中多OpenRouter提供了接口获取完整模型列表GET /api/v1/models。返回的数据里每个模型都带id、context_length、pricing、limits等字段。用Python抓一下就能做个快速筛选import requests resp requests.get(https://openrouter.ai/api/v1/models) models resp.json()[data] for m in models[:10]: print(m[id], ctx:, m[context_length], pricing:, m[pricing])context_length表示上下文窗口大小pricing里是输入和输出token的单价limits里有限流信息。这些数据对选型极其重要。比如你的业务要处理长文档就筛context_length大于等于128k的模型如果你的请求量很大就重点看限流上限别选一个每分钟只允许几次请求的模型。很多人在模型列表页面只会盯着模型名字看其实页面上的排序、筛选功能更值得研究。按上下文长度排序、按价格排序、只看支持结构化输出的模型这些筛选条件能快速缩小候选范围。3.2 我的选型经验先定成本上限再按任务类型筛模型选型没有绝对的最好只有在代价约束下的最合适。我的习惯是分三步走。第一步先定成本上限。假设一个功能预计每天调用一万次每次平均消耗输入2000 token、输出500 token那么单次成本上限基本就锁定了。超过这个价格的模型直接不看。第二步按任务类型粗筛。日常对话和AI编排用便宜的小模型就够复杂推理、代码生成用旗舰模型信息抽取和JSON输出要选支持结构化输出的模型涉及图片分析的必须选多模态模型。第三步跑一个小型测评集。不要光看榜单和benchmark我通常是准备20到30个任务相关的真实问题让候选模型分别跑一遍人工看输出质量。这个测评集能筛掉大量纸面很强、实际拉胯的模型。有一个通用参考任务场景建议模型档位备注高并发低延迟便宜小模型或开源模型速度优先质量要求不高长文档理解上下文长度大的旗舰模型注意按token计费成本较高复杂推理/代码推理能力强的主流大模型耗时更长需容忍延迟结构化提取支持JSON模式/工具调用的模型避免后期手工解析文本图像理解多模态模型需确认输入格式兼容3.3 模型命名的坑和兼容性边界模型ID里的后缀不是摆设。:free结尾的是免费模型适合测试流程:floor结尾的表示固定底价模型不会因为供需波动涨价。这些后缀直接决定了你的账单看清楚再下单。参数兼容性是最容易踩坑的地方。max_tokens在不同模型上的上限不一样有的模型只支持到4096你传8192就会被拒。temperature对部分推理模型无效甚至不支持强行传参可能导致请求报错。更隐蔽的是同一个top_p参数在不同模型实现里的实际效果有差异所以大规模切换模型时一定要在代码层面对参数做一次屏蔽处理不能把所有模型的参数写死。我的习惯是在上层封装里维护一份模型参数白名单什么模型支持哪些参数由配置文件控制。这样切换模型时不合格的参数直接不传而不是让模型自己去消化。4. 换模型就像换参数多模型对比与自动降级实战4.1 同一份请求跑多个模型最简单的AB测试逻辑OpenRouter最值钱的使用方式不是某一个模型的效果多好而是换模型这个动作的成本几乎降到了零。同一份messages只改model字段就能在多个模型之间横向对比。import requests import time MODELS [ openai/gpt-4o-mini, anthropic/claude-3.5-sonnet, google/gemini-flash-1.5, ] messages [ {role: user, content: 用不超过50字解释什么是redis} ] for model in MODELS: resp requests.post( https://openrouter.ai/api/v1/chat/completions, headers{Authorization: Bearer sk-or-v1-你的密钥}, json{model: model, messages: messages, max_tokens: 100} ) data resp.json() print(f {model} ) print(data[choices][0][message][content]) print(usage:, data.get(usage)) time.sleep(1) # 简单限速我经常用这个模式做模型效果巡检每周把固定的20个问题跑一遍候选模型记录输出质量、延迟、token消耗做成一张趋势表。哪个模型最近变好了或者变差了数据会直接说话。注意控制并发。虽然是同一个平台但不同模型背后是不同的上游服务几十个请求同时打过去容易触发限流。我一般串行跑或者控制并发在5以内跑完一批再跑下一批。4.2 自动降级的重试策略主模型挂了不中断业务生产环境不能指望某个模型永远可靠。上游厂商会故障免费模型会过载单次请求可能因网络抖动超时。所以一定要设计一套降级策略按优先级排列模型列表主模型失败就尝试备用模型。import time import requests MODEL_CHAIN [ openai/gpt-4o-mini, openai/gpt-4o-mini:free, anthropic/claude-3.5-sonnet, ] def chat_with_fallback(messages, max_retries2): last_error None for model in MODEL_CHAIN: for attempt in range(max_retries 1): try: resp requests.post( https://openrouter.ai/api/v1/chat/completions, headers{Authorization: Bearer sk-or-v1-你的密钥}, json{model: model, messages: messages}, timeout(3.05, 30) ) if resp.status_code 429 or resp.status_code 500: raise RuntimeError(fHTTP {resp.status_code}) resp.raise_for_status() return resp.json() except Exception as e: last_error e time.sleep(1 * (2 ** attempt)) # 指数退避 raise last_error这里有两个细节值得说。第一重试前要判断错误类型429限流和5xx上游故障重试才有意义如果是400参数错误重试一百次也是白费。第二重试间隔用指数退避第一次等1秒、第二次等2秒、第三次等4秒给下游留出恢复时间而不是一秒崩三次去加重故障。4.3 按流量峰谷调整模型档位接口设计成传参就生效之后模型档位就能做成动态的。我见过一个比较成熟的用法白天高并发时段用便宜小模型扛流量晚上低峰期切旗舰模型跑质量要求高的离线任务或者给免费用户用基础模型给付费用户用旗舰模型。省钱思路也类似。先用便宜模型处理如果业务觉得不够好再由触发条件升级到高级模型。比如客服系统先让小模型回答遇到意图识别置信度低的情况再把会话转给大模型。这种先抑后扬的策略能把平均成本压低一大截。5. 走向真实产品必须处理的三件事流式、结构化输出、多模态5.1 流式输出从转圈等到边想边字真要做聊天类产品流式输出是必须的。不开启流式时请求要等模型生成完整回复才一次性返回用户看到的就是一个漫长的加载动画开启流式后内容像打字机一样一个字一个字蹦出来用户等待的体感会好很多。请求里加stream: true即可。返回会变成SSE格式每行以data:开头import requests resp requests.post( https://openrouter.ai/api/v1/chat/completions, headers{Authorization: Bearer sk-or-v1-你的密钥}, json{ model: openai/gpt-4o-mini, messages: [{role: user, content: 讲个冷笑话}], stream: True }, streamTrue, timeout(3.05, 60) ) for line in resp.iter_lines(): if not line or not line.startswith(bdata:): continue chunk line[6:] if chunk.strip() b[DONE]: break print(chunk.decode(utf-8))有两个坑要注意。第一流式请求的超时时间要设置得比普通请求长很多因为首字节可能很快但整个流可能要持续几十秒。第二流式模式下部分字段在中间数据块里是空的别在每块里都解choices[0].message.content要容忍空内容只在数据块有内容时处理。5.2 让模型返回固定结构JSON模式与工具调用聊天模型返回自然语言没问题但想要把输出接到业务代码里最好让模型返回固定结构。OpenRouter支持OpenAI格式的response_format参数json{ model: openai/gpt-4o-mini, messages: [ {role: system, content: 你是信息抽取助手只输出JSON不要多余文字。}, {role: user, content: 提取这段话里的日期、地点、金额} ], response_format: {type: json_object} }这里有个经典坑很多模型在JSON模式下仍然要求提示词里显式提到JSON字样否则可能违反格式约定。所以系统提示词里一定要写清楚只输出JSON对象不要输出其他内容。更可靠的方案是工具调用tool calling / function calling。你定义一个工具声明参数结构让模型按这个结构返回参数值。这个方案对开发者更友好但不同模型对工具调用的实现细节有差异建议切换模型时做一轮专项测试。5.3 图片输入一次对比各家视觉理解能力OpenRouter的多模态请求遵循标准格式在content里混排文本和图片URL。json{ model: openai/gpt-4o-mini, messages: [ { role: user, content: [ {type: text, text: 这张图里有什么}, {type: image_url, image_url: {url: https://example.com/photo.jpg}} ] } ] }不是所有模型都支持图片传图片之前最好先确认目标模型的输入类型。另外图片输入在计费上和文本不一样有些模型会对图片额外收费费用取决于图片尺寸批量跑图之前建议先小额测试算清楚价格。这个功能在选型时很实用。我可以同时让五六个多模态模型看同一张截图对比谁对细节的理解更准确谁在定位特定物体上更靠谱。对比流程和文本模型完全一致改model就行。6. 账单、限流和故障排查跑量前的最后一公里6.1 算清楚一次请求到底花多少钱成本不能靠感觉要靠公式。在模型列表接口返回的pricing字段里单价通常以每token多少美元为单位大幅度的价格数字是正常的不要被那一长串零吓到换算下来往往并不贵。成本计算公式很简单单次成本 输入token数 × 输入单价 输出token数 × 输出单价举例假设某模型输入单价是百万token $3输出单价是百万token $15。一次请求用了2000个输入token、500个输出token那么成本是2000 / 1000000 × 3 500 / 1000000 × 15 0.006 0.0075 0.0135 美元单次一美分出头看起来便宜。但乘上每天十万次调用就是每天一千多美元决策前必须算清楚。还要提一下:floor后缀的模型。普通模型的价格可能随供需波动floor模型则固定单价适合对成本稳定性要求高的场景。免费模型确实不扣费但代价是严格的限流不适合生产环境。6.2 429/5xx/网络超时的区分与重试策略把异常情况分清楚处理起来才有方向。我的经验是做一个表格贴在项目文档里现象可能原因处理方式HTTP 429触发了限流或余额不足指数退避重试检查余额HTTP 5xx上游模型服务故障短暂等待后重试配合备用模型网络超时网络抖动或上游响应过慢设置合理的读取超时流式请求放宽HTTP 400参数错误或模型不支持检查模型参数白名单不要重试重试不是万能药。我在生产环境里的原则是429和5xx可以重试最多三次每次间隔递增400一律不重试先改代码再重新发。把重试逻辑和业务降级逻辑分开封装主模型挂了就切备用模型备用模型也挂了再通知人工。6.3 请求日志与用量监控的轻量做法团队项目还没到上大厂监控平台的时候也可以做好用量管理。我常用的做法是写一个轻量请求日志中间件把每次请求的模型、状态码、耗时、输入token、输出token、估算成本持久化到SQLite里。这个日志表核心字段大概是这样的时间、模型ID、HTTP状态、耗时(ms)、输入tokens、输出tokens、估算成本(USD)有了这个表月底对账不用看供应商后台一条SQL就能查出来哪个模型贡献了最大成本哪个模型报错率最高哪个时段限流最频繁。数据积累一段时间后很多优化决策就不用拍脑袋了。7. 我用OpenRouter这段时间踩过和见过的坑7.1 返回体兼容性别把其他SDK的习惯直接搬过来OpenRouter兼容OpenAI接口格式这导致很多人直接用OpenAI官方的SDK来调用改一个base_url就以为万事大吉。实际用下来有两点需要留意。一是密钥前缀不同有些SDK或框架会硬编码校验其他平台密钥格式换到OpenRouter的sk-or-v1-前缀时会误判需要在上层做适配。二是某些模型在返回choices[0].message.content时可能不是标准字符串或者把长段推理内容放在额外字段里这时候如果只取固定字段可能拿到空内容。我的建议是第一次接一个新模型先打印完整返回JSON看清楚它把内容放在哪再写解析逻辑。别默认所有模型返回结构一模一样这是最省力的避坑方式。7.2 上游模型限流并不是一个固定阈值同一个模型ID、同一个API Key在不同时间段的可用性可能差很多。免费档模型尤其明显白天高峰期经常429凌晨倒是很顺滑。这不是OpenRouter的问题而是上游服务在不同时段的负载不同。所以生产环境不要依赖免费模型也不要把限流阈值当成固定常量来设计系统。我在做容量规划时会按业务峰值的两倍余量来设计重试和降级。重要任务还需要加一个最终人工兜底的逻辑避免模型全挂时业务完全瘫痪。7.3 免费模型真香与免费模型真坑的两面免费模型适合什么适合测试流程、跑通Demo、学习API用法。我刚开始接触OpenRouter时就是用免费模型把整套请求链路跑通的零成本试错确实很香。但免费模型的坑也很真实。某次我做线上演示临时用了一个免费模型兜底结果现场网络抖动叠加限流画面非常尴尬。后来我学乖了凡是需要给外部看的演示一律用付费小模型宁可多花几分钱也要保证稳定输出。免费模型可以出现在代码的降级链末尾但永远不要让它出现在第一个。7.4 关于数据合规的一点提醒最后说一个容易被忽略的问题。请求经过OpenRouter转发给上游模型厂商相当于你的数据多经过了一层中转。对于内部文档、用户隐私数据这类敏感内容要评估是否适合走这条链路。合规的做法是先明确哪些数据能出内网哪些不能不能走API的数据就只能考虑私有化部署模型。还有一条基础安全纪律API Key绝不能写进前端代码、公共仓库或客户端配置里密钥要从服务端环境变量读取。项目上线前做一个密钥扫描这个习惯能省掉很多后续麻烦。我在实际使用中的体会是OpenRouter最大的价值不是省了一次接入而是把模型选型这件事从几个月做一次的大工程变成了随时都能做的常规操作。我现在做新功能固定会先挑两三个候选模型同时跑再根据效果、延迟、成本综合选择。你的第一个请求建议直接从免费模型开始等把链路跑通、有了真实业务数据再决定要不要升级到付费模型。工具只是手段找到最适合自己场景的模型组合才是这篇文章真正想帮你完成的事。