Skip to content

필사 모드: OpenRouter 使用指南 — 用一个 API 调用 300+ 个 LLM

中文
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.

概览

一旦开始同时使用多个 LLM,很快就会撞上同一个问题。你想混用 OpenAI、Anthropic、Google、Meta 的模型,但每家供应商都有各自的 SDK、各自的认证方式、各自的计费、各自的请求 schema。换一个模型就得重写客户端代码,而只要有一家供应商宕机,服务就跟着停摆。

OpenRouter 把这一层收拾干净了。一个端点、一个 API 密钥,就能接入 60+ 家供应商的 300+ 个(最多约 500 个)模型,接口与 OpenAI API 完全兼容。也就是说,如果你已经在用 OpenAI SDK,只需要换掉 base_urlapi_key,就能原样调用 Claude、Gemini、Llama。

本文依次讲清楚为什么要把 OpenRouter 当作网关来用、核心概念是什么,以及从申请密钥到路由/回退/流式输出,实际接入的每一步该怎么做。

1. 为什么需要一层网关

LLM 应用刚起步时,单个模型看起来就够用了。但一旦进入生产环境,就会冒出一些共同的需求。

  • 不同任务适合不同模型。摘要想用便宜的模型,复杂推理想用前沿模型,二者要能分开。
  • 不想被锁死在一家供应商上。一旦涨价或出故障,就得能迁到别的模型。
  • 想把计费和用量汇总在一处看。每家供应商都单开一个仪表盘,效率太低。

网关把这个问题从应用代码里剥离出去。客户端始终请求同一个端点,换模型这件事变成只替换一个字符串(model 字段)。供应商路由、回退、计费汇总都交给网关处理。

直连方式OpenRouter 网关
每家供应商的 SDK/认证/schema 都不同一个端点、一个密钥、兼容 OpenAI 的 schema
换模型要改代码只替换 model 字符串
每家供应商单独开计费账户用一份余额统一计费
故障时要自己实现回退通过 models 数组 / provider 路由自动回退

2. 核心概念

一个端点

所有调用都打向同一个 base URL。

https://openrouter.ai/api/v1

聊天补全(chat completions)请求打到 https://openrouter.ai/api/v1/chat/completions。认证使用标准的 Bearer token 请求头。

Authorization: Bearer YOUR_OPENROUTER_API_KEY

模型 ID

模型用 provider/model 格式的字符串指定。常见例子如下。

模型 ID说明
openai/gpt-4oOpenAI GPT-4o
anthropic/claude-3.5-sonnetAnthropic Claude 3.5 Sonnet
google/gemini-2.0-flash-expGoogle Gemini 2.0 Flash(实验版)
meta-llama/llama-3.3-70b-instructMeta Llama 3.3 70B Instruct
openrouter/auto自动路由器 — 由 OpenRouter 根据请求内容挑选模型

免费变体的 ID 末尾带 :free。完整目录以及每个模型的价格/上下文长度可以在模型页面查到,程序化查询则用 /api/v1/models 端点。

余额与免费额度

免费额度提供每天约 50 次免费请求,以及 25 个以上的免费模型(ID 以 :free 结尾)。付费使用按余额、按量计费,按实际执行的模型的 token 用量计费。充值余额时会收取约 5.5% 的小额手续费,但调用本身的成本,遵循的是实际处理该请求的模型的单价。

3. 申请密钥与第一个 curl 请求

先在 openrouter.ai/keys 申请 API 密钥。把密钥放进环境变量会比较方便。

export OPENROUTER_API_KEY="sk-or-你申请到的密钥"

现在用 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", "messages": [{"role":"user","content":"Hello"}] }'

返回的响应结构与 OpenAI 的 chat completions 完全一致。想换模型的话,只需把 model 值换成 anthropic/claude-3.5-sonnetgoogle/gemini-2.0-flash-exp,请求的其余部分保持不变。

4. OpenAI SDK 无缝替换

"OpenRouter 兼容 OpenAI" 这句话的实际含义是:继续用官方 OpenAI SDK,只是把接入点指向 OpenRouter。

Python

from openai import OpenAI

client = OpenAI(
    base_url="https://openrouter.ai/api/v1",
    api_key="YOUR_OPENROUTER_API_KEY",
)

completion = client.chat.completions.create(
    model="anthropic/claude-3.5-sonnet",
    messages=[
        {"role": "user", "content": "用一句话说明网关为什么有用"},
    ],
)

print(completion.choices[0].message.content)

OpenAI(...) 构造函数里,只需把 base_urlapi_key 换成 OpenRouter 的值,之后 client.chat.completions.create(...) 的调用方式和平时完全一样。响应正文从 completion.choices[0].message.content 读取。

TypeScript

TypeScript 也是同样的思路。给 openai npm 客户端指定 baseURLapiKey 即可。

import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'https://openrouter.ai/api/v1',
  apiKey: process.env.OPENROUTER_API_KEY,
});

const completion = await client.chat.completions.create({
  model: 'anthropic/claude-3.5-sonnet',
  messages: [{ role: 'user', content: 'Hello' }],
});

console.log(completion.choices[0].message.content);

不用 SDK,直接用 fetch 发 POST 也可以。只要端点和请求头对得上,行为完全一致。

const res = await fetch('https://openrouter.ai/api/v1/chat/completions', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.OPENROUTER_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'openai/gpt-4o',
    messages: [{ role: 'user', content: 'Hello' }],
  }),
});

const data = await res.json();
console.log(data.choices[0].message.content);

5. 模型选择与路由

供应商路由覆盖

同一个模型有时由多家供应商提供。这种情况下,OpenRouter 默认会根据价格、延迟、可用性自动选择供应商。想强制指定某种策略,就在请求里加入 provider 字段来覆盖默认行为。比如可以指定供应商优先级(order)、是否允许回退(allow_fallbacks)、排序标准(sort)等。

{
  "model": "meta-llama/llama-3.3-70b-instruct",
  "messages": [{ "role": "user", "content": "Hello" }],
  "provider": {
    "sort": "throughput",
    "allow_fallbacks": true
  }
}

模型级回退 — models 数组

与供应商路由分开,还可以指定按顺序依次尝试多个模型的回退。传入 models 数组后,会从头开始依次尝试。

{
  "models": [
    "openai/gpt-4o",
    "anthropic/claude-3.5-sonnet",
    "meta-llama/llama-3.3-70b-instruct"
  ],
  "messages": [{ "role": "user", "content": "Hello" }]
}

回退会在触及速率限制、停机、上下文长度超限、内容审核错误等情况下触发。计费方式是要点所在。即便列出了多个模型,也只会对实际执行并生成响应的那个模型的 token 计费。尝试过但失败的模型不产生费用。

自动路由器 — openrouter/auto

当自己选模型比较为难时,可以把 model 值设为 openrouter/auto。OpenRouter 会根据请求内容路由到合适的模型。这在早期原型验证阶段,或者只是需要"一个能用的模型"的时候很有用。

6. 流式输出 / 工具调用 / 结构化输出

这三个功能的工作方式都和 OpenAI API 一致。

流式输出

传入 stream=True(TypeScript 里是 stream: true)就能以分块方式接收响应。

stream = client.chat.completions.create(
    model="openai/gpt-4o",
    messages=[{"role": "user", "content": "写一首短诗"}],
    stream=True,
)

for chunk in stream:
    delta = chunk.choices[0].delta.content
    if delta:
        print(delta, end="")

工具 / 函数调用

工具(函数)调用同样沿用 OpenAI 的 schema。把函数定义放进 tools 数组,处理模型返回的 tool_calls,再把结果作为消息喂回去。

{
  "model": "openai/gpt-4o",
  "messages": [{ "role": "user", "content": "告诉我首尔的天气" }],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "返回某个城市的当前天气",
        "parameters": {
          "type": "object",
          "properties": { "city": { "type": "string" } },
          "required": ["city"]
        }
      }
    }
  ]
}

结构化输出

也支持基于 JSON schema 的结构化输出。在 response_format 里指定 json_schema,就能强制响应遵循该 schema。

{
  "model": "openai/gpt-4o",
  "messages": [{ "role": "user", "content": "生成一个示例用户" }],
  "response_format": {
    "type": "json_schema",
    "json_schema": {
      "name": "user",
      "schema": {
        "type": "object",
        "properties": {
          "name": { "type": "string" },
          "age": { "type": "integer" }
        },
        "required": ["name", "age"]
      }
    }
  }
}

7. 归属请求头与用量查询

OpenRouter 支持可选的归属(attribution)请求头,用于 openrouter.ai 的排行榜(哪个应用在多用哪个模型)。这不是必填项,填了就能让自己的应用出现在排行榜上。

  • HTTP-Referer — 自己站点的 URL
  • X-Title — 自己应用的名称

在 OpenAI SDK 里,这些请求头作为默认请求头传入。Python 用 default_headers,JavaScript 用 defaultHeaders

client = OpenAI(
    base_url="https://openrouter.ai/api/v1",
    api_key="YOUR_OPENROUTER_API_KEY",
    default_headers={
        "HTTP-Referer": "https://your-site.example",
        "X-Title": "My App",
    },
)
const client = new OpenAI({
  baseURL: 'https://openrouter.ai/api/v1',
  apiKey: process.env.OPENROUTER_API_KEY,
  defaultHeaders: {
    'HTTP-Referer': 'https://your-site.example',
    'X-Title': 'My App',
  },
});

可用模型列表及其元数据通过 /api/v1/models 端点查询。

curl https://openrouter.ai/api/v1/models \
  -H "Authorization: Bearer $OPENROUTER_API_KEY"

8. 实务技巧与注意事项

  • 成本始终遵循实际执行的下层模型的单价。使用 openrouter/automodels 回退时,要记住单价会随实际执行的模型而变化。
  • :free 模型免费,但速率限制较低。如果生产流量完全依赖免费模型,很快就会撞上限额。更适合用在原型验证或低负载场景。
  • API 密钥务必放在服务端。一旦在浏览器打包产物或客户端代码里暴露密钥,它就会被直接窃取。如果必须从前端发起调用,就在前面架一层自己的后端做代理,再由后端调用 OpenRouter。
  • 换模型时响应 schema 依然保持兼容 OpenAI,不需要为每个模型重写解析代码。不过工具调用、结构化输出的支持程度可能因模型而异,切换到新模型时要实际验证该功能是否可用。
  • 回退数组能提高稳定性,但如果把昂贵的模型放在末尾,故障发生时成本可能会飙升。排列回退顺序时,不仅要考虑可用性,也要把单价一并纳入考量。

参考资料

현재 단락 (1/175)

一旦开始同时使用多个 LLM,很快就会撞上同一个问题。你想混用 OpenAI、Anthropic、Google、Meta 的模型,但每家供应商都有各自的 SDK、各自的认证方式、各自的计费、各自的请求...

작성 글자: 0원문 글자: 6,464작성 단락: 0/175