OpenRouter Provider¶
1. 定位¶
OpenRouter 是模型聚合 Gateway,用一个 API Key 访问 300+ 模型.优势: - 单一 Key 访问所有主流模型 - 自动路由最优模型 - 支持 100+ 提供商的聚合 - 模型排名和成本透明度
2. 支持的模型¶
OpenRouter 动态获取模型列表,从 /api/v1/models 实时拉取.
主要模型(来自 capabilities-baseline.json):
| 模型 | Context | Input $/1M | Output $/1M | 备注 |
|---|---|---|---|---|
| anthropic/claude-opus-4.6 | 1M | $5 | $25 | 透明网关 |
| anthropic/claude-sonnet-4.6 | 1M | $3 | $15 | 透明网关 |
| anthropic/claude-haiku-4.5 | 200K | $1 | $5 | 透明网关 |
| deepseek/deepseek-r1 | 64K | $0.7 | $2.5 | 推理优化 |
| google/gemini-2.0-flash-001 | 1M | $0.10 | $0.40 | 透明网关 |
| minimax/minimax-m2.7 | 205K | $0.3 | $1.2 | 透明网关 |
| openai/gpt-4o | 128K | $2.5 | $10 | 透明网关 |
注意: 实际价格以 OpenRouter 官网为准,此处为参考值.
3. 配置示例¶
import "git.flytoex.net/yuanwei/git.flytoex.net/yuanwei/flyto-agent/pkg/providers/openrouter"
p := openrouter.New(openrouter.Config{
APIKey: os.Getenv("OPENROUTER_API_KEY"),
BaseURL: "https://openrouter.ai", // 默认;可指向私有代理或测试 mock
SiteURL: "https://myapp.com", // HTTP-Referer,用于排名统计(可选)
AppName: "My Flyto Agent", // X-Title,用于排名显示(可选)
DefaultThinking: true, // 所有请求默认启用 thinking
DefaultThinkingTokens: 8000, // thinking token 上限(0 = OpenRouter 默认)
EnableCaching: true, // 系统消息加 cache_control(仅 Anthropic 后端)
Timeout: 60 * time.Second, // 可选, 见 §3.1
})
字段说明:
- BaseURL:覆盖默认 https://openrouter.ai,用于私有代理和单元测试 mock.
- EnableCaching:仅对 Anthropic 系列后端有效(Sonnet ≥1024t / Haiku ≥2048t 才会建立缓存);非 Anthropic 路径下静默忽略.
3.1 Timeout (P1 契约加固, 2026-04-13)¶
Config.Timeout 通过 http.Transport.ResponseHeaderTimeout 实现, 约束"请求发出到收到响应首字节"的时间, 不影响 SSE 流式 body 读取.
OpenRouter 特殊考虑: 聚合网关内部会根据请求切换底层 provider, 某些冷启动的 open-weights 模型 (DeepSeek / Qwen / Llama) 首字节可能比 OpenAI / Anthropic 慢.如果主要使用此类模型, 建议将 Timeout 设为 90 * time.Second 或更高; 默认 60s 已覆盖主流商业模型.
| 场景 | Config 字段 | 行为 |
|---|---|---|
| 默认 | HTTPClient=nil, Timeout=0 |
使用 defaultTimeout=60s |
| 显式 Timeout | HTTPClient=nil, Timeout=Xs |
使用 Xs |
| 自定义 client | HTTPClient=&http.Client{...} |
完全交给消费者, Timeout 被忽略 |
陷阱警告: 不要误用 http.Client.Timeout - 详见 anthropic.md §3.1.
4. 认证方式¶
Bearer Token: Authorization: Bearer <API_KEY>
API Key 获取: OpenRouter
5. 能力矩阵¶
| 能力 | 支持 | 备注 |
|---|---|---|
| Streaming | ✓ | 透传 |
| Tool Use | ✓ | 透传 |
| Extended Thinking | ✓ | 统一 reasoning 参数 |
| Vision | ✓ | 透传 |
| JSON Mode | ✓ | 透传 |
| Caching | ✓ | 仅 Anthropic 后端,需 >1024 tokens |
| Batch API | ✗ | 不支持 |
6. 已知 quirks¶
统一 Thinking 参数¶
OpenRouter 的 reasoning 参数统一了不同后端(Anthropic,DeepSeek,OpenAI)的 thinking 表达,Provider 自动适配.
Cache 限制¶
EnableCaching: true 只对 Anthropic 后端有效:
- 需要模型支持(至少 1024 tokens)
- 非 Anthropic 后端会静默忽略
可选排名 Headers¶
p := openrouter.New(openrouter.Config{
APIKey: key,
SiteURL: "https://myapp.com", // HTTP-Referer header
AppName: "MyAgent", // X-Title header
})
这些 headers 影响 OpenRouter 的模型排名.
透明网关¶
OpenRouter 作为网关,将请求转发给实际 Provider.因此: - 速率限制取决于底层 Provider - 错误消息可能包含底层 Provider 的状态码
模型列表动态更新¶
不像其他 Provider 有静态表,OpenRouter 通过 /api/v1/models 实时拉取.
注意:拉取发生在 Models(ctx) 调用时,不是 New() 时--构造 Provider 不会触发任何 HTTP 请求,OpenRouter 不可达不会阻塞 Provider 初始化或后续 Stream() 请求.
7. 错误处理¶
| 状态码 | 含义 | 处理建议 |
|---|---|---|
| 401 | API Key 无效 | 检查 Key |
| 402 | 余额不足 | 充值 |
| 429 | 全局速率限制 | 等待后重试 |
| 400 | 请求格式错误 | 检查 payload |
| 503 | 底层 Provider 不可用 | 换用其他模型 |
8. 成本估算示例¶
通过 OpenRouter 访问 Claude Sonnet 4.6(1000 input,500 output):
直接用 Anthropic API 相同请求:
价格一致,OpenRouter 不加价,但提供聚合便利.
9. 使用场景¶
最佳场景: - 多模型切换:一个 Key 访问所有 - 模型探索:想尝试不同模型的效果 - 成本透明:同一界面看所有模型价格 - 统一接口:不想管理多个 API Key
10. 数据驱动能力(Capabilities)¶
参见
docs/architecture/data-driven-capabilities-rfc.md了解整体机制.PR2.5(2026-04)落地--这是 PR2 中特化最多的 provider.
本 provider 的能力决策来自 req.Capabilities(engine 从 ModelRegistry 注入).包内 const openrouterMaxTools = 0 降级为兜底.
本 provider 的决策路径(三路径全覆盖):
| 路径 | helper | 兜底策略 |
|---|---|---|
MaxTools + Exhaustive |
resolveMaxTools |
openrouterMaxTools = 0(透传底层 provider,自身无统一上限) |
SupportsThinking |
resolveThinkingSupport |
兜底 true(语义反转) |
SupportsCaching |
resolveCachingSupport |
兜底 true(语义反转) |
openrouter 的关键语义反转:兜底 true.其他 provider(ollama / gemini / minimax 等)的兜底要么 false("保守默认"),要么扫静态表.openrouter 没有静态模型表--它完全依赖 live API(Models(ctx) 每次实时拉取 /api/v1/models).因此 req.Capabilities == nil 时无从查询模型能力,必须假设支持以维持早期方案"无脑注入 reasoning / cache_control"的零回归行为.只有 registry 显式声明 can=false 时才触发 warning.
零回归的第二个关键特化:不清零字段.其他 provider(如 gemini)在 can=false 时会清零 thinking budget;openrouter 不清零--wireReq.Reasoning 和 wireReq.EnableSystemCaching 仍无条件注入下游.理由:openrouter 底层可能存在 fallback 机制(某些非 Anthropic 后端也接受 cache_control 并自行忽略),清零会破坏这种 fallback.warning 让消费者看到风险,但最终是否干预由消费者决定.
双开关协议(want × can)三路径检测:
- thinking want: Config.DefaultThinking=true 或 req.NeedsThinking=true
- caching want: Config.EnableCaching=true
- 两路径 want × can 独立判断,可能同时 emit 两个 WarningEvent(比如调 openai/gpt-4o 同时设了 DefaultThinking + EnableCaching,registry 说 gpt-4o 既不支持 thinking 也不支持 cache_control → 2 个 warning)