渠道管理与 model_mapping

专栏:new-api 源码拆解 · 第 5 / 12 篇
new-api渠道model mapping

:::info 学习目标 完成本篇后你能够:逐字段解读 Channel 结构并说出每个字段被哪个模块消费;配置 model_mapping 实现链式模型重定向;理解渠道测试为什么比”ping 上游”更可信。 前置:第 4 篇完成。预计时长:50 分钟。 :::

:::note 本章术语速查(新手建议先读)

  • 渠道(Channel):一个上游 AI 服务商的接入配置(密钥+模型列表+优先级)。
  • model_mapping(模型重定向):把请求里的模型名映射成上游真实模型名,如 my-gpt → gpt-4o。
  • 多 key 模式:一个渠道配多把密钥轮着用,坏一把只禁一把。
  • 熔断/自动禁用:上游持续出错时自动把它下线,恢复后再启用。
  • 环检测:配置 A→B、B→A 这种循环映射时主动报错,防止死循环。 :::

渠道(Channel)是网关对”一个上游 API”的抽象:一把密钥、一组模型、一个优先级、一套改写规则。model/channel.go 的 Channel 结构是整个选路与转发体系的数据基础——每个字段都被下游某个模块消费,本篇按”字段 → 消费方”的方式读它。

Channel 字段与消费方全景

// model/channel.go:23-60(节选;为易读省略了指针标记与 gorm 标签,以源码为准)
type Channel struct {
    Type              int    // 渠道类型(OpenAI=1、Azure=3、Anthropic=14、Gemini=24、
                            //   DeepSeek=43、Aws=33、VertexAi=41…constant/channel.go 约 45 种)
    Key               string // 上游密钥,支持逗号分隔多 key(ChannelInfo 记录多 key 状态)
    Status            int    // 启用 / 手动禁用 / 自动禁用
    Weight            int    // 同优先级内的加权随机权重
    Priority          int    // 优先级,重试分档的依据
    Models            string // 提供的模型列表(逗号分隔)
    Group             string // 所属分组(逗号分隔多个)
    ModelMapping      string // model_mapping:模型名重定向 JSON
    StatusCodeMapping string // 上游状态码 → 网关状态码映射
    AutoBan           int    // 出错时是否允许自动禁用
    Setting           dto.ChannelSettings // system_prompt、透传、代理等开关
    ParamOverride     string // 渠道级请求参数覆盖(第 6 篇)
    HeaderOverride    string // 请求头覆盖
    OtherSettings     string // 多 key 状态等
}
图表(newapi-channel-management.md)

Ability 表:路由索引的持久形态

渠道与模型、分组的映射关系,除了进内存缓存,还落在 abilities 表里(model/ability.go):以 Group × Model × ChannelId 为联合主键,带 Enabled/Priority/Weight 字段。它是路由索引的持久形态:渠道缓存的全量重建(第 10 篇)数据源就是它;未启用内存缓存时,选路直接查这张表。渠道增删改时 new-api 会同步重建 abilities 行——管理台里改渠道”秒级生效”,底层是这张表先变、缓存再跟上。

多 key 模式:一把渠道,多把钥匙

Key 字段支持逗号分隔多把 key(ChannelInfo.IsMultiKey 记录状态,MultiKeyStatusList 记录每把 key 的健康状态),轮询策略可选。精妙之处在于故障隔离:自动禁用触发时,多 key 渠道只禁用出错的那把 key(UpdateChannelStatus 携带 usingKey),而不是整个渠道——对”从某平台批量采购的 key 池”是刚需:一把 key 被上游限流,其余 key 继续服务,管理员只需要补一把新 key。

model_mapping:链式重定向 + 环检测

model_mapping 让渠道把请求的模型名重定向为上游的真实模型名(如把 gpt-4o 映射到某中转站的 gpt-4o-2024-11-20)。它由 Distribute 中间件放入上下文(middleware/distributor.go:667),实际应用在 relay/helper/model_mapped.go——支持链式重定向(A→B→C 连续映射)且带环检测:

// relay/helper/model_mapped.go:26-67(节选)
currentModel := info.OriginModelName
visitedModels := map[string]bool{ currentModel: true }
for {
    mappedModel, exists := modelMap[currentModel]
    baseModel := hostreasoning.BaseModelName(currentModel)
    if (!exists || mappedModel == "") && baseModel != currentModel {
        mappedModel, exists = modelMap[baseModel]   // 退回基础模型名再试
    }
    if exists && mappedModel != "" {
        if visitedModels[mappedModel] {             // 环检测
            return errors.New("model_mapping_contains_cycle")
        }
        visitedModels[mappedModel] = true
        currentModel = mappedModel
        info.IsModelMapped = true
    } else { break }
}

两个细节:链式映射支持”中转站套中转站”的现实场景;baseModel 回退让带版本后缀的模型名(gpt-4o-2024-11-20)能命中为基础名配置的映射。环检测的存在说明有人真的配出过 A→B→A——好的防御性代码都长这样。

渠道测试:走一遍完整 relay 链路

controller/channel-test.gotestChannel 不是简单 ping 上游,而是用 httptest 构造虚拟请求完整走一遍 relay 链路——鉴权上下文、渠道选择、适配器转换、计费结算全部真实执行(buildTestRequest 构造请求、流式/非流式响应分别校验、settleTestQuota 结算测试消耗)。这意味着”渠道测试通过”等于”真实请求可以工作”,测试置信度远高于裸探活。渠道测试也接进了后台定时任务(第 10 篇的 RegisterScheduledSystemTasks),可按频率自动巡检。

与其他模块的联系

  • → 渠道缓存(第 10 篇):渠道增删改后由 SyncChannelCache 周期重建 group2model2channels 索引;
  • → 选路(第 7 篇):Priority/Weight/Group 是选路算法的输入;
  • → relay(第 6 篇):ParamOverride/HeaderOverride/Setting 在请求序列化后、转发前应用;
  • → 计费(第 8 篇):渠道本身不参与定价(定价按模型与分组),但 ChannelUsedQuota 记录每个渠道的消耗,用于成本核算。

常见踩坑

  1. model_mapping 配了但没生效——选路按原模型名匹配,映射发生在渠道选中之后;先确认渠道的 Models 列表含原模型名;
  2. 多 key 渠道一把 key 失效全渠道被禁——检查版本(单 key 禁用是多 key 模式的核心能力);
  3. 渠道测试通过但真实请求失败——对比测试请求与真实请求的模型名/参数差异,ParamOverride 常是变量;
  4. 一个渠道塞几百个模型——选路索引膨胀、加权随机被稀释,按模型族拆渠道更健康。

随堂练习(带验收标准)

  1. 配置一个渠道 + model_mapping(把 my-gpt 映射到真实模型),验收:请求 my-gpt 成功返回且日志显示映射后的名字;
  2. 配置链式映射 A→B、B→C,验证最终请求 C;再配 A→B、B→A 触发 model_mapping_contains_cycle 错误;
  3. 创建一个多 key 渠道,掺入一把坏 key,触发自动禁用。验收:只有坏 key 被禁,渠道仍可用;
  4. 用渠道测试功能测一个配错 key 的渠道。验收:测试失败信息能定位到鉴权层(而非超时)。

← 返回文章列表