Feature Request: 智能模型自动发现与匹配(Auto Model Discovery & Smart Matching)
背景
Token Proxy 作为多上游 API 网关,核心价值之一就是让用户统一管理多个渠道。但目前模型名称的映射完全依赖用户手动配置
model_mappings,这在实际多渠道场景下非常痛苦。
问题描述
痛点 1:同一模型在不同渠道命名不统一
实际使用中,我有多个上游渠道(官方直连、中转站、镜像站),同一个模型在不同渠道的名字千奇百怪:
Claude 系列示例:
┌──────────┬─────────────────────────────┐
│ 渠道 │ claude-opus-4-6 的实际名称 │
├──────────┼─────────────────────────────┤
│ 官方直连 │ claude-opus-4-0609 │
├──────────┼─────────────────────────────┤
│ 中转站 A │ anthropic/claude-opus-4-6 │
├──────────┼─────────────────────────────┤
│ 中转站 B │ [ant]-claude-opus-4-6-count │
├──────────┼─────────────────────────────┤
│ 中转站 C │ claude-opus-4 │
├──────────┼─────────────────────────────┤
│ 镜像站 D │ rc-claude-opus-4-6-high │
└──────────┴─────────────────────────────┘
GPT 系列示例:
┌──────────┬────────────────────┐
│ 渠道 │ gpt-4.1 的实际名称 │
├──────────┼────────────────────┤
│ 官方直连 │ gpt-4.1-2025-04-14 │
├──────────┼────────────────────┤
│ 中转站 A │ openai/gpt-4.1 │
├──────────┼────────────────────┤
│ 中转站 B │ gpt-4.1-chat │
└──────────┴────────────────────┘
Gemini 系列示例:
┌──────────┬─────────────────────────────────────┐
│ 渠道 │ gemini-2.5-pro 的实际名称 │
├──────────┼─────────────────────────────────────┤
│ 官方直连 │ models/gemini-2.5-pro-preview-05-06 │
├──────────┼─────────────────────────────────────┤
│ 中转站 A │ google/gemini-2.5-pro │
├──────────┼─────────────────────────────────────┤
│ 中转站 B │ gemini-2.5-pro-latest │
└──────────┴─────────────────────────────────────┘
痛点 2:维护成本随渠道和模型数量爆炸增长
* 5 个渠道 × 10 个常用模型 = 50 条映射规则需要手动配置
* 新模型发布后(比如 Claude 出了新版),每个渠道都要重新配一遍
* 新增一个渠道,又要把所有模型的映射写一遍
* 稍有配错就出现 No available upstream configured 错误,排查成本高
痛点 3:用户不知道渠道商给模型起了什么名字
很多中转站的模型命名没有文档说明,用户只能通过 /v1/models 接口去查,然后对着一长串列表手动找对应关系,非常低效。
期望功能
一句话概括:只填 API Key,不配任何 model_mappings,代理自动识别并正确路由。
- 自动探测上游可用模型
* 代理启动时(及可选定期刷新)自动调用各上游的模型列表接口
* OpenAI 系:GET /v1/models
* Gemini 系:GET /v1beta/models
* Anthropic 系:如上游支持模型列表端点则探测
* 在 Dashboard 中可视化展示探测结果:每个上游有哪些模型可用
- 智能识别"同一模型"的不同命名
不管渠道商给模型加了什么前缀、后缀、命名空间,代理能自动识别出核心模型身份并归类为同一模型。
期望能覆盖但不限于以下常见命名变体:
┌─────────────────────┬─────────────────────────────┬─────────────────┐
│ 变体类型 │ 示例 │ 应识别为 │
├─────────────────────┼─────────────────────────────┼─────────────────┤
│ 供应商前缀 │ anthropic/claude-opus-4-6 │ claude-opus-4-6 │
├─────────────────────┼─────────────────────────────┼─────────────────┤
│ 渠道商标签前缀 │ [ant]-claude-opus-4-6-count │ claude-opus-4-6 │
├─────────────────────┼─────────────────────────────┼─────────────────┤
│ 渠道代号前缀 │ rc-claude-opus-4-6-high │ claude-opus-4-6 │
├─────────────────────┼─────────────────────────────┼─────────────────┤
│ 命名空间前缀 │ models/gemini-2.5-pro │ gemini-2.5-pro │
├─────────────────────┼─────────────────────────────┼─────────────────┤
│ 功能后缀 │ gpt-4.1-chat │ gpt-4.1 │
├─────────────────────┼─────────────────────────────┼─────────────────┤
│ latest/preview 后缀 │ gemini-2.5-pro-latest │ gemini-2.5-pro │
└─────────────────────┴─────────────────────────────┴─────────────────┘
- 请求时自动路由并替换模型名
* 用户请求 claude-opus-4-6 → 代理找到最优上游 → 自动将模型名替换为该上游的真实名称 → 转发请求
* 响应中的模型名替换回用户请求的原始名称(保持现有的 "Response echoes original alias" 行为)
安全约束(非常重要)
核心原则:宁可返回错误,绝不路由到错误的模型。
绝不允许的情况:
┌─────────────────┬──────────────────┬──────────────────────────┐
│ 用户请求 │ 错误路由到 │ 原因 │
├─────────────────┼──────────────────┼──────────────────────────┤
│ claude-opus-4-6 │ claude-opus-4-5 │ 子版本不同,是不同的模型 │
├─────────────────┼──────────────────┼──────────────────────────┤
│ claude-opus-4 │ claude-sonnet-4 │ 模型级别不同 │
├─────────────────┼──────────────────┼──────────────────────────┤
│ gpt-4.1 │ gpt-4.1-mini │ 模型变体不同 │
├─────────────────┼──────────────────┼──────────────────────────┤
│ gemini-2.5-pro │ gemini-2.5-flash │ 模型级别不同 │
└─────────────────┴──────────────────┴──────────────────────────┘
子版本等价性问题:
有些情况下,不同的子版本写法可能指向同一个模型(比如 4-6 可能等于 4-0609),但也可能不是。代理不应该自行猜测,建议:
* 默认严格模式:子版本字面不同即视为不同模型
* 提供可选配置(如 version_aliases)让用户手动声明哪些子版本是等价的
* 匹配不到时返回清晰的错误信息,列出可用的相似模型及差异原因,方便用户排查
理想的错误提示:
No exact match for model "claude-opus-4-6"
Similar models found:
├─ upstream_a: claude-opus-4-0609 (sub-version mismatch: "6" ≠ "0609")
├─ upstream_b: claude-opus-4 (no sub-version, available as fallback)
└─ upstream_c: claude-sonnet-4-6 (tier mismatch: sonnet ≠ opus)
Tips:
• Use "claude-opus-4" to match any sub-version of opus-4
• Add version_aliases config to treat "6" and "0609" as equivalent
配置对比
当前方式(繁琐,容易出错):
{
"upstreams": [
{
"id": "official",
"api_key": "sk-ant-xxx",
"providers": ["anthropic"],
"model_mappings": {
"claude-opus-4-6": "claude-opus-4-0609",
"claude-sonnet-4-6": "claude-sonnet-4-20250514"
// 每个模型都要手动映射...
}
},
{
"id": "relay_a",
"api_key": "sk-yyy",
"providers": ["anthropic"],
"model_mappings": {
"claude-opus-4-6": "anthropic/claude-opus-4-6",
"claude-sonnet-4-6": "anthropic/claude-sonnet-4-6"
// 又要写一遍...
}
},
{
"id": "relay_b",
"api_key": "sk-zzz",
"providers": ["anthropic"],
"model_mappings": {
"claude-opus-4-6": "[ant]-claude-opus-4-6-count",
"claude-sonnet-4-6": "[ant]-claude-sonnet-4-6-count"
// 再写一遍...
}
}
]
}
期望方式(简洁,自动化):
{
"auto_discovery": {
"enabled": true,
"refresh_interval_secs": 3600
},
"upstreams": [
{ "id": "official", "api_key": "sk-ant-xxx", "providers": ["anthropic"] },
{ "id": "relay_a", "api_key": "sk-yyy", "providers": ["anthropic"] },
{ "id": "relay_b", "api_key": "sk-zzz", "providers": ["anthropic"] }
]
// 零 model_mappings,填 Key 即用
}
补充说明
* 此功能应与现有的手动 model_mappings 兼容共存:手动配置的优先级高于自动匹配,方便用户覆盖个别特殊情况
* 探测到的模型列表如果能在 Dashboard 中可视化展示(哪个上游有哪些模型、自动归类结果),对用户排查问题会非常有帮助
* auto_discovery 应默认关闭(enabled: false),避免影响现有用户
价值总结
* 用户体验:从"每个上游手动配 N 条映射"变成"填 Key 即用",配置量减少 90%+
* 错误减少:消除因手动配错映射导致的 No available upstream configured 错误
* 维护成本:新模型发布或新增渠道后无需改配置,自动生效
* 差异化优势:据我了解,目前同类网关工具(One API、New API 等)都不具备自动模型发现和智能匹配能力,Token Proxy
如果实现了这个功能将是一个重要差异化卖点
Feature Request: 智能模型自动发现与匹配(Auto Model Discovery & Smart Matching)
背景
Token Proxy 作为多上游 API 网关,核心价值之一就是让用户统一管理多个渠道。但目前模型名称的映射完全依赖用户手动配置
model_mappings,这在实际多渠道场景下非常痛苦。
问题描述
痛点 1:同一模型在不同渠道命名不统一
实际使用中,我有多个上游渠道(官方直连、中转站、镜像站),同一个模型在不同渠道的名字千奇百怪:
Claude 系列示例:
┌──────────┬─────────────────────────────┐
│ 渠道 │ claude-opus-4-6 的实际名称 │
├──────────┼─────────────────────────────┤
│ 官方直连 │ claude-opus-4-0609 │
├──────────┼─────────────────────────────┤
│ 中转站 A │ anthropic/claude-opus-4-6 │
├──────────┼─────────────────────────────┤
│ 中转站 B │ [ant]-claude-opus-4-6-count │
├──────────┼─────────────────────────────┤
│ 中转站 C │ claude-opus-4 │
├──────────┼─────────────────────────────┤
│ 镜像站 D │ rc-claude-opus-4-6-high │
└──────────┴─────────────────────────────┘
GPT 系列示例:
┌──────────┬────────────────────┐
│ 渠道 │ gpt-4.1 的实际名称 │
├──────────┼────────────────────┤
│ 官方直连 │ gpt-4.1-2025-04-14 │
├──────────┼────────────────────┤
│ 中转站 A │ openai/gpt-4.1 │
├──────────┼────────────────────┤
│ 中转站 B │ gpt-4.1-chat │
└──────────┴────────────────────┘
Gemini 系列示例:
┌──────────┬─────────────────────────────────────┐
│ 渠道 │ gemini-2.5-pro 的实际名称 │
├──────────┼─────────────────────────────────────┤
│ 官方直连 │ models/gemini-2.5-pro-preview-05-06 │
├──────────┼─────────────────────────────────────┤
│ 中转站 A │ google/gemini-2.5-pro │
├──────────┼─────────────────────────────────────┤
│ 中转站 B │ gemini-2.5-pro-latest │
└──────────┴─────────────────────────────────────┘
痛点 2:维护成本随渠道和模型数量爆炸增长
痛点 3:用户不知道渠道商给模型起了什么名字
很多中转站的模型命名没有文档说明,用户只能通过 /v1/models 接口去查,然后对着一长串列表手动找对应关系,非常低效。
期望功能
一句话概括:只填 API Key,不配任何 model_mappings,代理自动识别并正确路由。
不管渠道商给模型加了什么前缀、后缀、命名空间,代理能自动识别出核心模型身份并归类为同一模型。
期望能覆盖但不限于以下常见命名变体:
┌─────────────────────┬─────────────────────────────┬─────────────────┐
│ 变体类型 │ 示例 │ 应识别为 │
├─────────────────────┼─────────────────────────────┼─────────────────┤
│ 供应商前缀 │ anthropic/claude-opus-4-6 │ claude-opus-4-6 │
├─────────────────────┼─────────────────────────────┼─────────────────┤
│ 渠道商标签前缀 │ [ant]-claude-opus-4-6-count │ claude-opus-4-6 │
├─────────────────────┼─────────────────────────────┼─────────────────┤
│ 渠道代号前缀 │ rc-claude-opus-4-6-high │ claude-opus-4-6 │
├─────────────────────┼─────────────────────────────┼─────────────────┤
│ 命名空间前缀 │ models/gemini-2.5-pro │ gemini-2.5-pro │
├─────────────────────┼─────────────────────────────┼─────────────────┤
│ 功能后缀 │ gpt-4.1-chat │ gpt-4.1 │
├─────────────────────┼─────────────────────────────┼─────────────────┤
│ latest/preview 后缀 │ gemini-2.5-pro-latest │ gemini-2.5-pro │
└─────────────────────┴─────────────────────────────┴─────────────────┘
安全约束(非常重要)
核心原则:宁可返回错误,绝不路由到错误的模型。
绝不允许的情况:
┌─────────────────┬──────────────────┬──────────────────────────┐
│ 用户请求 │ 错误路由到 │ 原因 │
├─────────────────┼──────────────────┼──────────────────────────┤
│ claude-opus-4-6 │ claude-opus-4-5 │ 子版本不同,是不同的模型 │
├─────────────────┼──────────────────┼──────────────────────────┤
│ claude-opus-4 │ claude-sonnet-4 │ 模型级别不同 │
├─────────────────┼──────────────────┼──────────────────────────┤
│ gpt-4.1 │ gpt-4.1-mini │ 模型变体不同 │
├─────────────────┼──────────────────┼──────────────────────────┤
│ gemini-2.5-pro │ gemini-2.5-flash │ 模型级别不同 │
└─────────────────┴──────────────────┴──────────────────────────┘
子版本等价性问题:
有些情况下,不同的子版本写法可能指向同一个模型(比如 4-6 可能等于 4-0609),但也可能不是。代理不应该自行猜测,建议:
理想的错误提示:
配置对比
当前方式(繁琐,容易出错):
{
"upstreams": [
{
"id": "official",
"api_key": "sk-ant-xxx",
"providers": ["anthropic"],
"model_mappings": {
"claude-opus-4-6": "claude-opus-4-0609",
"claude-sonnet-4-6": "claude-sonnet-4-20250514"
// 每个模型都要手动映射...
}
},
{
"id": "relay_a",
"api_key": "sk-yyy",
"providers": ["anthropic"],
"model_mappings": {
"claude-opus-4-6": "anthropic/claude-opus-4-6",
"claude-sonnet-4-6": "anthropic/claude-sonnet-4-6"
// 又要写一遍...
}
},
{
"id": "relay_b",
"api_key": "sk-zzz",
"providers": ["anthropic"],
"model_mappings": {
"claude-opus-4-6": "[ant]-claude-opus-4-6-count",
"claude-sonnet-4-6": "[ant]-claude-sonnet-4-6-count"
// 再写一遍...
}
}
]
}
期望方式(简洁,自动化):
{
"auto_discovery": {
"enabled": true,
"refresh_interval_secs": 3600
},
"upstreams": [
{ "id": "official", "api_key": "sk-ant-xxx", "providers": ["anthropic"] },
{ "id": "relay_a", "api_key": "sk-yyy", "providers": ["anthropic"] },
{ "id": "relay_b", "api_key": "sk-zzz", "providers": ["anthropic"] }
]
// 零 model_mappings,填 Key 即用
}
补充说明
价值总结
如果实现了这个功能将是一个重要差异化卖点