什么是适配器架构?为什么接入每一家模型厂商都要单独写一套适配,而不是共用同一个接口?

适配器架构是在聚合平台的统一数据模型与各模型厂商原生接口之间加的一层转换模块,每家厂商各写一个。原因是鉴权方式、请求字段、流式协议、错误码和用量口径几乎厂商各一套,而且会持续变更;把差异关进独立适配器,上游改动才不会波及全站业务。只接一家厂商且不打算更换时,这层架构收益有限。

适配器架构是聚合平台在内部统一数据模型与各模型厂商原生接口之间插入的一层转换模块,每家厂商对应一个独立适配器,而不是所有厂商共用同一段调用代码。它成立的前提是上游接口在鉴权、字段、流式协议、错误码和用量口径上存在实质差异;如果只接一家厂商、也不考虑更换,直接调用原生 SDK 反而更简单。 适配器至少要承担五类职责:接口契约统一、请求字段映射、鉴权与凭证管理、流式响应解析、错误与用量的归一化。契约层定义平台内部自用的请求与响应对象,业务代码只认这一套;映射层把内部对象翻译成厂商要求的 JSON 结构,再把返回结果翻回来。这五类职责缺任何一类,差异就会漏到上层业务代码里。 所谓“OpenAI 兼容”只覆盖主流程,不覆盖边缘情况,这是每家厂商仍需独立适配的第一个原因。字段级方言包括 system 消息是否允许放在列表中间、tool_calls 的参数是不是字符串、finish_reason 的取值集合、流式分帧里的结束标记怎么写。真正让线上出问题的往往不是主流程,而是空内容返回、参数校验失败、限流与内容拦截这些分支。 鉴权方式的差异单独构成一个适配点,因为凭证的形式和生命周期完全不同。有的厂商用固定 Bearer 密钥,有的要求 AK/SK 加时间戳签名,有的先拿 appid 和 secret 换一个会过期的访问令牌。适配器要负责令牌缓存、到期前刷新以及并发请求下的刷新去重,否则流量高峰会出现一批请求同时撞上凭证失效。 流式协议是差异最集中、也最容易出线上事故的一层。不同厂商的服务端推送在事件命名、心跳行、增量 JSON 是否跨帧拆分上各不相同,有的把错误塞在流中间返回而不是用状态码表达。适配器必须做增量解析、半截 JSON 缓冲和断流收尾。漏掉收尾逻辑,用户看到的就是内容截断,或者同一次调用被多计一次费。 能力差异要靠适配器里的能力声明层显式记录,而不是散落在业务代码的 if 判断里。同一个厂商的不同模型,在工具调用、结构化输出、多模态输入、上下文长度、是否支持推理模式上并不一致,而且会随版本变化。把这些写成可查询的元数据之后,路由层才能按“是否支持工具调用”筛通道,模型下线或改名只改元数据,不动业务代码。 模型厂商接口会持续变更,这是必须做独立适配、而不只是做一次对接的根本原因。变更形态包括新增必填字段、修改默认值、老模型下线、限流策略收紧、错误码扩展。适配器架构的价值在于把变更的影响面收敛到一个模块加一组回归用例,而不是让改动顺着调用链扩散到计费、订单和前端展示。 独立适配的成本结构分成一次性开发和持续维护两部分,选型时最容易被低估的是后者。一次性部分是把主流程打通,通常集中在字段映射、流式解析和凭证接入;持续部分包括上游每次变更后的回归验证、凭证与配额管理、灰度与回滚。数量级上,新增一家厂商的主要工作量在测试用例与灰度,而不是写几行字段映射。 三种常见实现方式各有适用边界:共享网关加厂商适配器、每家厂商独立微服务、以及只做一层兼容代理。共享网关加适配器把通用逻辑如鉴权限流、路由、计费与厂商差异分开,适合接入厂商多、需要容灾切换的场景;独立微服务隔离性最好但运维成本高;只做兼容代理最省事,代价是边缘情况和厂商专有能力处理不了。 适配器还决定计费和对账能不能对上,因为用量字段的口径厂商之间并不统一。有的把缓存命中的输入令牌和未命中的分开计,有的把推理过程产生的令牌单独列,有的只在最后一帧返回用量。适配器要把这些归一化成平台内部的统一计量单位,并保留厂商侧的原始请求标识,否则出现计费争议时无法回溯到单次调用。 落地时最常见的四个失败模式是:把业务逻辑写进适配器、错误码原样透传、能力声明没有版本、缺少回归用例。业务逻辑一旦沉到适配器里,换厂商就等于重写业务;错误码透传会让上层收到无法分类的异常;能力声明不版本化,上游行为变化后没有对照基准;没有回归用例,静默变更往往等到流式场景才暴露出来。 判断要不要引入这层架构有一个简单边界:接入厂商数量、切换频率,以及是否需要容灾路由。只接一家且长期不换,适配器的收益抵不上多一层抽象的成本;一旦需要多厂商并存、按成本或能力路由,或者要求某家故障时自动切换,独立适配就从可选项变成必需品。