如何为Chat API添加一个新的大模型上游?渠道适配器开发实战教程
2026/8/22 15:08:26 网站建设 项目流程

如何为Chat API添加一个新的大模型上游?渠道适配器开发实战教程

【免费下载链接】chat-apiOpenAI 接口聚合管理,我们致力于提供优质的API接入服务,让您可以轻松集成先进的AI模型至您的产品和服务。项目地址: https://gitcode.com/gh_mirrors/ch/chat-api

Chat API 是一个OpenAI 接口聚合管理平台,它把各家大模型厂商的接口统一封装成 OpenAI 兼容格式,让开发者用一把 Token 就能调用 Gemini、Claude、文心一言等上游模型。如果你想把新的上游(比如 Ollama、Cohere、DeepSeek)接入 Chat API,核心工作就是开发一个渠道适配器(Channel Adaptor):它负责把统一的 OpenAI 请求"翻译"成目标上游的私有协议,再把响应翻译回来。本教程将以真实源码为例,带你走完从定义渠道编号、实现适配器、注册系统到控制台测试的完整流程。

一、先搞懂:渠道适配器在整个项目中扮演什么角色

Chat API 的转发逻辑集中在relay/目录,一次请求的处理链路大致是:

用户请求 → 路由与中间件(router/relay-router.go)→ 选择渠道(middleware/distributor.go)→渠道适配器relay/channel/下的各家子目录)→ 上游模型

每个上游厂商的 API 协议都不同(鉴权方式、请求体字段、流式返回格式各不相同),而 Chat API 对外只暴露统一的 OpenAI 格式。渠道适配器就是中间的"翻译官",所有协议差异都被隔离在适配器内部。

relay/channel/下已经内置了几十种渠道,可以作为现成参考:

适配器目录对接的上游
relay/channel/openai/OpenAI / Azure / 各种 OpenAI 兼容服务
relay/channel/anthropic/Claude
relay/channel/gemini/Google Gemini
relay/channel/baidu/百度文心一言
relay/channel/ollama/Ollama 本地大模型
relay/channel/coze/字节 Coze

💡新手建议:写新适配器前,先找一个和目标上游"协议最像"的现有适配器通读一遍,比看文档快得多。

二、新渠道接入的完整路径:一共要改哪 5 处

步骤文件做什么
① 定义渠道类型common/constants.go新增ChannelTypeXxx编号,并加入ChannelBaseURLs列表
② 映射 API 类型relay/constant/api_type.goChannelType2APIType中把渠道号映射为APITypeXxx
③ 实现适配器relay/channel/ 下新建目录实现Adaptor接口,完成请求/响应转换
④ 注册适配器relay/helper/main.goGetAdaptor的 switch 中返回你的适配器实例
⑤ 控制台配置测试管理后台"渠道管理"添加渠道、填写 BaseURL 与 API Key、点击测试

以渠道编号为例,在 common/constants.go 中可以清晰看到编号是顺序分配的:

ChannelTypeOllama = 33 ChannelTypeAwsClaude = 35 ChannelTypeCoze = 36 // 新增渠道时取下一个未使用的编号即可

同时需要把新渠道的默认 BaseURL 追加到同文件的ChannelBaseURLs数组中,这样前端创建渠道时会自动带出正确的默认地址。

三、适配器接口详解:需要实现的 9 个方法

所有适配器都要实现统一接口,定义在 relay/channel/interface.go:

type Adaptor interface { Init(meta *util.RelayMeta) GetRequestURL(meta *util.RelayMeta) (string, error) SetupRequestHeader(c *gin.Context, req *http.Request, meta *util.RelayMeta) error ConvertRequest(c *gin.Context, meta *util.RelayMeta, request *model.GeneralOpenAIRequest) (any, error) ConvertImageRequest(request *model.ImageRequest) (any, error) DoRequest(c *gin.Context, meta *util.RelayMeta, requestBody io.Reader) (*http.Response, error) DoResponse(c *gin.Context, resp *http.Response, meta *util.RelayMeta) (aitext string, usage *model.Usage, err *model.ErrorWithStatusCode) GetModelList() []string GetChannelName() string }

各方法的职责可以这样记忆:

  • Init:初始化,比如按模型名选择不同协议版本
  • GetRequestURL:根据meta.Mode(对话/向量化/图像生成等,定义见 relay/constant/relay_mode.go)拼出上游完整 URL
  • SetupRequestHeader:设置鉴权头(Bearer、AK/SK 签名等)
  • ConvertRequest/ConvertImageRequest:把 OpenAI 请求体转成上游私有格式
  • DoRequest:发送 HTTP 请求(一般直接调用通用辅助函数)
  • DoResponse:解析上游响应,回填 token 用量usage(这是计费的关键)
  • GetModelList/GetChannelName:返回模型清单与渠道名称

📌 其中DoRequest几乎不需要自己写,直接复用 relay/channel/common.go 中的DoRequestHelper即可,它会自动处理 URL 拼接、请求头设置和代理转发(配合common/client/proxy.go的代理能力)。

四、以 Ollama 为例:写出一个最小可用适配器

Ollama 适配器(relay/channel/ollama/)是代码量最少的完整样例,非常适合新手仿写。它的目录结构就是新渠道的"标准模板":

  • adaptor.go—— 实现Adaptor接口
  • constants.go—— 定义ModelList模型清单
  • model.go—— 定义上游的请求/响应结构体
  • main.go—— 响应解析(流式与非流式)

① 核心逻辑只有几十行,看 relay/channel/ollama/adaptor.go 的两个关键方法:

func (a *Adaptor) GetRequestURL(meta *util.RelayMeta) (string, error) { fullRequestURL := fmt.Sprintf("%s/api/chat", meta.BaseURL) if meta.Mode == constant.RelayModeEmbeddings { fullRequestURL = fmt.Sprintf("%s/api/embeddings", meta.BaseURL) } return fullRequestURL, nil } func (a *Adaptor) SetupRequestHeader(c *gin.Context, req *http.Request, meta *util.RelayMeta) error { channel.SetupCommonRequestHeader(c, req, meta) req.Header.Set("Authorization", "Bearer "+meta.APIKey) return nil }

② 用结构体描述上游协议,在 relay/channel/ollama/model.go 中:

type ChatRequest struct { Model string `json:"model,omitempty"` Messages []Message `json:"messages,omitempty"` Stream bool `json:"stream"` Options *Options `json:"options,omitempty"` }

③ 在ConvertRequest中做字段映射,把统一的GeneralOpenAIRequest(定义于 relay/model/general.go)逐字段转换成ChatRequest④ 在DoResponse中按meta.IsStream分支处理流式/非流式响应,并把prompt_eval_count/eval_count换算为usage,保证账单准确。

⚠️ 注意:如果上游的 token 计费口径与 OpenAI 不同,建议在 relay/util/model_mapping.go 中配置模型映射,而不是在适配器里硬编码。

五、把新渠道注册进系统

适配器写好后,还差两步注册:

① 在 relay/helper/main.go 的GetAdaptor中注册——这是系统"根据 API 类型找到适配器"的唯一入口:

case constant.APITypeOllama: return &ollama.Adaptor{}

② 在 relay/constant/api_type.go 中完成"渠道号 → API 类型"的映射,并新增对应的APITypeXxx常量。

小技巧:如果你的目标上游兼容 OpenAI 协议,则无需新写适配器!直接在控制台创建"OpenAI"类型渠道、填入它的 BaseURL 即可,这正是 relay/channel/openai/compatible.go 支持的能力。

六、在控制台添加并测试你的新渠道

代码改完、服务重启后,进入管理后台的"渠道管理"页面:

操作步骤:

  1. 点击右上角"添加渠道",类型选择你新增的渠道类型
  2. 填写上游BaseURLAPI Key(本地模型如 Ollama 通常无需 Key)
  3. 在"模型"栏粘贴你的模型清单(来自适配器的ModelList
  4. 点击"测试"按钮验证连通性,成功后开启渠道并配置分组与权重

测试通过后,该上游的模型就会出现在用户侧的模型列表中,统一以 OpenAI 兼容格式对外服务 🎉

七、最佳实践与避坑清单

  • 流式响应是最容易踩坑的部分:不同上游的 SSE 结束标记不同([DONE]vsdone: true),务必参考 relay/channel/ollama/main.go 中StreamHandler的逐行解析方式
  • 错误码要规范:统一用model.ErrorWithStatusCode返回,让上游 4xx/5xx 能被正确透传并计入渠道健康度
  • 计费别漏DoResponse中一定要填充usage,否则该渠道请求无法统计 token 消耗(计费逻辑见 relay/util/billing.go)
  • 渠道测试失败会触发自动禁用:如果你的上游限流严格,测试接口要选轻量模型
  • 参考学习路径:简单渠道看 relay/channel/ollama/,复杂渠道(多协议分支)看 relay/channel/ali/ 和 relay/channel/coze/

小结

为 Chat API 添加新的大模型上游,本质就是**"4 处代码 + 1 次测试"**:

  1. common/constants.go 中分配渠道编号
  2. relay/constant/api_type.go 中映射 API 类型
  3. relay/channel/ 下新建目录实现Adaptor接口
  4. relay/helper/main.go 中注册适配器
  5. 控制台添加渠道并测试

掌握这套适配器开发流程后,你就能把任意协议的大模型服务接入 Chat API,让平台的能力随需求无限扩展。

【免费下载链接】chat-apiOpenAI 接口聚合管理,我们致力于提供优质的API接入服务,让您可以轻松集成先进的AI模型至您的产品和服务。项目地址: https://gitcode.com/gh_mirrors/ch/chat-api

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询