Skip to content

智能模型自动发现与匹配(Auto Model Discovery & Smart Matching) #219

@Guaranteep

Description

@Guaranteep

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,代理自动识别并正确路由。

  1. 自动探测上游可用模型
 * 代理启动时(及可选定期刷新)自动调用各上游的模型列表接口
 * OpenAI 系:GET /v1/models
 * Gemini 系:GET /v1beta/models
 * Anthropic 系:如上游支持模型列表端点则探测
 * 在 Dashboard 中可视化展示探测结果:每个上游有哪些模型可用
  1. 智能识别"同一模型"的不同命名

不管渠道商给模型加了什么前缀、后缀、命名空间,代理能自动识别出核心模型身份并归类为同一模型。

期望能覆盖但不限于以下常见命名变体:

┌─────────────────────┬─────────────────────────────┬─────────────────┐
│ 变体类型 │ 示例 │ 应识别为 │
├─────────────────────┼─────────────────────────────┼─────────────────┤
│ 供应商前缀 │ 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 │
└─────────────────────┴─────────────────────────────┴─────────────────┘

  1. 请求时自动路由并替换模型名
 * 用户请求 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

如果实现了这个功能将是一个重要差异化卖点

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions