层级模型映射
这是本站与普通「固定映射」中转最大的差别:按档位匹配,而不是按完整模型名匹配。
为什么要层级匹配
Claude Code 等客户端会发送带版本号的模型名,例如:
claude-sonnet-4-5-20250929
如果只能精确匹配,上游每发一个新版本,映射就失效一次。层级匹配只配 「档位 → 目标模型」,新版本自动落到同一档位。
档位
| 档位 | 含义 |
|---|---|
fable | 最新、最具体的档位(最高优先级) |
opus | 高档 |
sonnet | 中档 |
haiku | 低档 / 快档 |
default | 兜底,永远最后 |
优先级:fable > opus > sonnet > haiku > default。fable 未配置时降到 opus。
匹配规则
- 精确匹配优先:渠道的
model_mapping里写死的模型名先命中。 - 层级匹配只作 fallback:精确匹配不到时才走档位。
- 档位用包含匹配,不要求前缀——
claude-sonnet-4-5-20250929中间的sonnet也能命中。 - 按配置顺序,先命中先用;同档位多条规则取首条。
为什么必须是包含匹配
档位词经常出现在模型名中间(如 claude-sonnet-4)。若用前缀匹配,
这类名字永远匹配不上,映射会静默失效。
配置示例
{"tier": "opus", "target": "MiniMax-M3.1-Flash"}
{"tier": "sonnet", "target": "MiniMax-M3.1-Flash"}
{"tier": "haiku", "target": "MiniMax-M3.1-Flash"}
也支持 {model} 占位符做「同族换版本」:
{"tier": "opus", "target": "deepseek-v4-opus-{model}"}
{model} 会被替换成原始模型名(去掉匹配到的档位词)。
存在哪里
在渠道的 settings 字段(ChannelOtherSettings),键名为 model_tier_mapping。
三个部署坑
- 必须是 JSON 字符串,不能传对象——后端字段是
string, 传对象会报cannot unmarshal object into Go struct field。 UpdateChannel拒绝带status字段的请求,PUT 前要 pop 掉。- 渠道有 60 秒以上内存缓存,改完要等
SYNC_FREQUENCY或轮询数据库确认落库。
当前实际配置
线上走的是精确映射
当前承载渠道配的是精确 model_mapping(每个档位名逐条对应目标模型),
而不是层级映射。两者的优先级关系是:精确匹配命中时,层级映射不再介入。
当前渠道的精确映射:
| 请求模型名 | 实际转发到 |
|---|---|
claude-opus-4-5 | MiniMax-M3.1-Flash |
claude-opus-4-8 | MiniMax-M3.1-Flash |
claude-sonnet-4-6 | MiniMax-M3.1-Flash |
MiniMax-M2.5 | MiniMax-M3.1-Flash |
MiniMax-M3.1-Flash | 不改写(原样转发) |
MiniMax-M3 | 不改写(原样转发) |
层级映射能力仍在代码里(relay/helper/model_tier_mapping.go),作为精确匹配
未命中时的兜底;新增带版本号的模型名时,走的就是这条路径。
对你意味着什么
- 你按档位付费,实际承载模型可能不同 → 见 模型说明
- 上游换承载模型时,你的代码不用改
- 想确认某档位实际跑什么,看控制台「模型说明」页