
先说一个我自己的真实感受今年年初我们团队把内部 AI 能力从“只接一家模型”改成“多模型自由路由”最大的痛点不是模型效果选择而是每一家模型的 API 规范完全不一样。OpenAI 用/v1/chat/completionsAnthropic 用/v1/messagesGoogle Gemini 又是另一套/v1beta/models请求头、消息结构、流式格式、错误码几乎没有一个地方是统一的。改完 OpenAI 的代码再去看 Claude 的文档那种“重新学一门接口语言”的感觉我相信很多同行都体会过。所以 AI 聚合接口平台才在这两年成了刚需。它们的核心价值不是“多一个转发层”而是把背后三套甚至更多的大模型 API 统一成一套规范让业务代码只写一次。再加上统一鉴权、统一配额、统一计费日志运维复杂度一下降了不少。但问题也跟着来了市面上叫得上名字的聚合平台越来越多各家都标榜自己“兼容 OpenAI / Anthropic / Gemini”实际兼容到哪个深度是只做到“能通”还是连流式、工具调用、多模态、参数透传都做全这个如果只看 README根本看不出来。我花了大概两周时间把 OpenMove、LiteLLM开源网关自建、以及另一家商业聚合服务放在一起做了一轮针对三大协议兼容性的实测。这篇文章只做一件事用真实请求把它们的“协议兼容”掰开揉碎看哪些是表面兼容哪些是真能扛业务。1. 聚合接口平台的本质与横评对象1.1 为什么需要聚合层直接对接大模型的三个痛点先复盘一下在没有聚合平台的时候一个中型团队直接对接多家大模型有多麻烦。首先是接口规范OpenAI 的ChatCompletion消息体里用role: system/user/assistant描述会话Anthropic 的 Messages API 虽然也用类似字段但系统提示词要放到顶层system参数里Gemini 又完全不一样人家用contents加parts的结构角色映射直接叫user和model。哪怕你已经封装了一层客户端每次新增模型厂商都得在 SDK 之上再补一个适配器。其次是密钥管理和成本分摊。直接对接多家模型意味着每个平台都有自己的 API Key有的按项目维度开有的按用户维度开密钥散落在不同同事的本地环境变量里。每个月账单对账更是折磨OpenAI 出了多少 token、Claude 出了多少 token、Gemini 又花了多少钱全部要人工汇总。还有限流不同模型的 RPM/TPM 配额完全独立一个请求触发了限流你很难快速判断是哪个上游导致的。聚合层把这些问题集中到一个节点统一 API 入口、统一密钥管理、统一用量账单甚至在多个上游之间做自动故障转移。这也是我一开始决定引入这类平台的根本原因——不是追逐热点是真的被多模型并行开发这件事逼出来的。1.2 这次横评选了哪几个平台为什么是它们市面上做模型聚合的路线大致分成三类这次我刻意各选了一个代表OpenMove商业闭源聚合服务主打多模型接入和统一计费官方声称兼容 OpenAI、Anthropic、Gemini 三种协议有控制台可以做用量分析和模型路由。LiteLLM开源模型网关部署在自己服务器上支持包一层代理把各种上游统一成 OpenAI 格式适合喜欢自托管、数据不过第三方的团队。某商业聚合 SaaS下文简称为“竞品C”同样是商业托管但更侧重企业级功能比如 SSO 登录、审计日志、私有化部署选项。选这三个的原因是它们的部署形态差异足够大一个是纯 SaaS 托管一个是自托管开源网关另一个是本地运行的开源协议转换层。如果这三家都声称兼容三大协议那基本能代表主流聚合平台的整体水平。另一个考虑是很多团队最终会在这三种路线之间纠结所以横评结果可以直接对应到选型决策。我给自己定了一个原则不做“启动盘里所有模型都测一遍”的大而全测试而是聚焦一个真实业务最常遇到的组合——文本对话、流式输出、工具调用、嵌入向量这四个场景覆盖了 90% 的日常调用。2. 三大协议兼容性实测方法论2.1 协议兼容性的三个层级能通、能用、能跑业务做实测之前我先把“兼容”这件事拆成了三个层次避免“能通”和“能跑业务”被混为一谈。第一层是基础连通性也就是请求能发出去、能拿到 200 响应。比如你用 OpenAI SDK 把 base_url 改成聚合平台地址能不能正常完成一次chat.completions.create。这个层次最容易做到因为只要聚合平台在网关层做一个路径转发、把 Authorization Bearer Token 换成自己的 Key 就行绝大多数平台在这一层都不会出问题。第二层是参数映射与字段透传。这一层的差异才是实际业务中真正会踩到的坑OpenAI 请求里的temperature怎么映射到 Anthropic 的temperaturemax_tokens在 OpenAI 是生成的最大 token 数在 Anthropic 的 Messages API 里同样有个max_tokens但却是必填参数——如果聚合层不帮你补默认值OpenAI 客户端发过去的请求在 Anthropic 上游直接就 400 了。response_format、tools、tool_choice、stop这些参数更是重灾区很多参数在不同协议里根本没有一一对应关系聚合层要么做值转换要么直接忽略。第三层是流式协议和高级特性的完整映射。这个是最考验聚合平台功力的地方。OpenAI 的流式返回是data: {json}按行推送Anthropic 的流式则是事件流模式有message_start、content_block_delta、message_delta不同事件类型Gemini 的streamGenerateContent又是另一种 JSON 分段结构。如果聚合层只是“透传上游流式响应”而不管格式转换那客户端用 OpenAI SDK 接收到的流式数据结构就是错的会出现“能拿到 200但流式解析直接报错”或者“流不结束、卡在某个事件上”的诡异问题。工具调用也一样OpenAI 的tool_calls结构、Anthropic 的tool_usecontent block、Gemini 的functionCall是三种完全不同的表达方式不做深层次转换就没法正常触发函数调用。2.2 测试环境与评判标准为了尽量贴近真实业务我做了一个最小可复现的测试项目语言选了 Python用了各家的官方 SDK 做客户端同时把 SDK 的 base_url 指向聚合平台。这样做的好处是能直接检验“SDK 不换、只改 base_url 和 key”这个最理想的迁移方案是否成立。测试环境大概是这样的客户端Python 3.11openai 1.x SDKanthropic 0.x SDKgoogle-generativeai SDK目标模型OpenAI 协议对应 gpt-4o-miniAnthropic 协议对应 claude-3-5-haikuGemini 原生协议对应 gemini-1.5-flash都是低延迟、低成本的走量模型测试场景单轮对话、多轮对话、流式对话、工具调用、文本嵌入评判维度连通性、参数生效性、流式完整性、错误信息可读性、端到端延迟我给自己定的通过标准比较严格流式场景必须能按协议解析出完整的增量内容不能漏 chunk不能出现事件顺序错乱工具调用场景必须能正确返回tool_calls或等价的tool_use结构且参数能被客户端 SDK 正常解析错误场景必须有清晰的错误码和错误说明不能是“上游 500 被吞成 400”这类含糊响应3. 三大协议兼容性实测过程与结果3.1 OpenAI 协议兼容性从 base_url 到高级参数OpenAI 协议是聚合平台的“母语”因为大部分聚合平台自己本身就是用 OpenAI 的接口格式做统一抽象的所以理论上这层兼容性应该最稳。我实测下来也基本符合预期OpenMove、LiteLLM、竞品C 三家的/v1/chat/completions基础调用全部通过单轮对话和简单的多轮上下文都能正确返回。但我测到流式的时候就发现了差异。用 OpenAI SDK 的streamTrue参数做流式对话三家的返回都能被 SDK 正常解析但usage字段的处理方式不一样。OpenMove 在流式结束时带上了完整的usage信息竞品C 需要额外传stream_options: {include_usage: true}才能在流式末尾拿到 token 统计LiteLLM 则默认不带需要在请求里明确开启。这个差异直接影响成本统计的精确性如果团队依赖流式响应里的 usage 做实时计费就得注意聚合平台是否完整透传/生成了这个字段。更值得说的是工具调用function calling这一层。我在测试脚本里定义了一个简单的天气查询工具让模型在合适的时机触发调用。OpenMove 和 LiteLLM 都能正确返回tool_calls结构包括id、type、function.name、function.arguments这些关键字段OpenAI SDK 可以直接从响应里解析出参数。竞品C 在单轮工具调用上也通过了但当我连续做“工具调用 - 返回工具结果 - 模型再次调用工具”这种多轮工具循环时竞品C 偶尔会出现tool_choice失效的现象模型没有按预期继续调用工具而是直接回复文本。排查下来大概率是它的协议转换层对多轮tool消息的角色映射做了简化处理导致上下文里工具结果没有正确传递给上游模型。还有两个细节值得注意。第一个是response_format参数我在测试 JSON Output 模式时OpenMove 可以正确把 OpenAI 的response_format: {type: json_object}映射到 Anthropic 上游的 JSON 约束如果路由到 ClaudeLiteLLM 也能做类似映射但竞品C 是直接透传给上游——如果上游恰好是 Gemini这个参数对方并不认识请求会被忽略但不会报错结果就是模型可能返回非 JSON 文本。第二个是max_tokensLiteLLM 在默认配置下不会帮你补这个参数如果路由到 Anthropic 的 Claude请求会因为缺少必填的max_tokens直接报 400而 OpenMove 会在转发前自动补一个默认值这个对“只改了 base_url 就切换模型”的团队来说差别很大。3.2 Anthropic 协议兼容性头部差异与必填参数的坑Anthropic 的 Messages API 是这次横评里最见真章的部分因为它的鉴权方式、请求结构和流式格式跟 OpenAI 差异太大聚合层要做到“无感兼容”难度最高。先说最基础的鉴权。Anthropic 原生要求两个请求头x-api-key和anthropic-version而 OpenAI 用的是Authorization: Bearer key。在测试中OpenMove 和竞品C 都正确实现了这两种鉴权方式的映射——我用 Anthropic SDK 把base_url指向它们的地址auth_token填自己平台的 Key请求能正常通过。但 LiteLLM 如果配置时只保留了 OpenAI 格式的Authorization头映射用 Anthropic 协议访问时就会在网关层被 401需要在配置里额外做一份鉴权头转换规则。这个对自建用户来说是个典型的配置陷阱。然后是消息结构。Anthropic 的 Messages API 有一个独立的system顶层参数OpenAI 的消息列表里没有这个分层系统提示词就是role: system的一条普通消息。实测三家都能把 OpenAI 的 system 消息正确转成 Anthropic 的顶层system字段但“回退顺序”不一样OpenMove 和 LiteLLM 是优先取第一条 system 消息并合并竞品C 只取第一条 system多条 system 消息会被直接丢弃这会丢上下文。还有一个反向问题如果直接用 Anthropic 协议往聚合平台发请求平台怎么处理system字段这块我测下来三家基本都能原样透传问题不大。流式输出是这一轮差异最大的点。Anthropic 原生流式是一系列事件message_start、content_block_start、content_block_delta、content_block_stop、message_delta、message_stop。我用 Anthropic SDK 的stream: true请求三家都能把上游响应转回 Anthropic 事件流但从事件完整性上看OpenMove 做得最完整message_delta里的usage.output_tokens统计字段一直存在LiteLLM 的事件流偶尔会缺少message_delta中的stop_reason字段导致客户端在判断“模型为何停止生成”时拿不到原因竞品C 则发现一个偶发问题在长回答场景下content_block_delta的delta.text会被拆得比较碎这不算 bug 但会让客户端渲染时更频繁地触发 UI 更新。工具调用在 Anthropic 协议里是tool_use和tool_result这种 content block 结构。我实测三家都能把 OpenAI 格式的tool_calls转成 Anthropic 的tool_use也可以反向转换这个没有问题。但真正的坑在tool_choice的映射Anthropic 的tool_choice支持auto、any、tool三种模式其中any表示必须调用工具OpenAI 没有直接对应的选项只有auto、none、required。测试中发现当用户用 Anthropic 协议发送tool_choice: {type: any}时竞品C 会把any映射成 OpenAI 风格的required这个基本等价能用但 LiteLLM 在某些版本里会把any直接忽略回退到auto导致模型可能不调用工具就回复。这种隐性问题在文档里根本不会写只有实测才能发现。3.3 Gemini 原生协议兼容性路径、安全设置与流式格式Gemini 是这次横评里最“特殊”的一个协议。Google 的生成式 AI 接口跟 OpenAI、Anthropic 都不是一个路数路径是/v1beta/models/{model}:generateContent这种 RPC 风格请求体用的是contents/parts结构而不是messages。所以聚合平台对 Gemini 原生协议的兼容往往不是“做映射”而是“做翻译”。先从最简单的模型列表和基础对话说起。用google-generativeaiSDK 的generate_content做单轮对话三家都能正常返回但方式不太一样。OpenMove 和竞品C 是直接实现了 Gemini 协议的路由SDK 请求发过来后它翻译成内部统一格式再路由到不同上游所以无论最终上游是不是 GeminiSDK 收到的都是 Gemini 风格的candidates结构LiteLLM 则是依赖一个收费很低的“协议转换器”把 Gemini 请求转成 OpenAI 格式再走它的主链路最终返回给 SDK 的也是 Gemini 结构。三种方案效果上都能通但 OpenMove 的翻译做得更彻底连prompt_feedback和安全评级这类 Gemini 特有的字段都会返回。流式接口streamGenerateContent是这次测试里最有戏剧性的部分。Gemini 原生流式返回的candidates数组里content.parts每次增量只包含一小段文本但它的 JSON 结构是不变的只是内容在变。这在聚合层做格式转换时很容易搞错如果只做“按行解析 JSON 再组装成 OpenAI 的 chunk”就必须每个 chunk 都保持完整的candidates结构不能拆坏。实测 OpenMove 在 Gemini 流式转 OpenAI 格式时表现稳定每个 chunk 的索引和完成原因都正确竞品C 在长时间流式输出时出现过两次“chunk 中断”需要客户端自己做超时重试LiteLLM 的 Gemini 流式转换在短文本场景没问题长文本生成到后半段时偶尔会出现字段finishReason提早出现、后面还跟着文本的异常情况OpenAI SDK 解析时会忽略后面的文本导致生成被“截断”。安全设置safetySettings也是 Gemini 协议特有的东西。因为是翻译链路很多平台在转成 OpenAI 格式时会把safetySettings直接丢到extra_body里透传能不能生效完全取决于上游认不认。实测 OpenMove 支持把 Gemini 的safetySettings转发给真正的 Gemini 上游也支持把 OpenAI 风格的moderation类参数映射成 Gemini 的安全档位竞品C 对这一层的支持明显弱一些safetySettings里如果指定了BLOCK_NONE这种挡位它不会帮你做白名单透传可能被上游拒绝LiteLLM 则完全依赖 prompt 模板层面控制没有专门透传安全参数。对内容安全有严格要求的业务这块要单独验证。3.4 三平台三大协议实测结果汇总我把这一轮的关键结果整理成一张表方便对照。测试项OpenMoveLiteLLM竞品COpenAI 基础对话通过通过通过OpenAI 流式对话通过含 usage 统计通过默认不含 usage通过需额外参数OpenAI 工具调用多轮稳定稳定偶发 tool_choice 失效OpenAI JSON 模式路由到 Claude正确映射正确映射部分透传不保证生效Anthropic 基础鉴权通过Automatic 头映射需配置鉴权头转换通过Anthropic 流式事件完整性完整偶缺 stop_reason通过但 text 碎片化Anthropic tool_choice: any正确映射回退为 auto正确映射为 requiredGemini 基础对话通过通过通过Gemini 流式长文本稳定偶发 finishReason 提前偶发 chunk 中断Gemini 安全设置透传支持不支持部分支持错误信息可读性上游错误原样转换含原因常见错误可读部分透传原始 body错误码准确但详情偏少整体看下来OpenMove 在协议兼容深度上确实做得最全尤其是高层级特性的映射比较扎实LiteLLM 胜在开源可定制但默认配置下的协议转换有很多隐藏条件适合有技术精力去调优的团队竞品C 在基础链路可用但高级特性覆盖得不够完整更适合只走 OpenAI 协议的业务。4. 横评之外的实用维度路由、计费与稳定性4.1 模型路由策略不只是“随机选一个上游”协议兼容性是第一关但聚合平台的日常价值更多体现在模型路由策略上。多数平台宣传的“智能路由”并不智能只是根据你配的优先级列表按顺序尝试上游出错就切换下一个。真正拉开差距的是故障转移的粒度是整条请求级别切换还是流式响应中途出错也能切换这个差别很大。我实测时给 OpenMove 配置了两个上游一个主用 Anthropic、一个备用 Gemini然后手动把 Anthropic 的 Key 改成无效值。发现它在请求发出前就会因鉴权失败快速切换但如果是在流式生成到一半时上游突然断连OpenMove 会直接返回给客户端一个错误不会再切换到备用上游重新生成——这个我基本能理解因为流式输出已经给客户端吐了一半内容重试只会造成重复和错乱不是所有场景都适合做“流式中途切换”。LiteLLM 则更依赖配置的retry_policy如果设置合理它是能做请求级重试的但需要自己写清楚什么错误码触发切换。对团队来说路由策略要关注的是能不能“按成本优先”“按延迟优先”“按能力优先”这三类规则灵活调配。我建议在选型时把需求的优先级定清楚如果你就是想让便宜模型先顶上那平台是否支持按模型单价排序就很重要如果你是做客服场景、对延迟敏感那平台有没有就近节点和流式快速响应机制就更关键。而不是被“智能路由”这个营销词带偏。4.2 用量统计与成本分摊聚合平台真正的“记账本”聚合平台除了转发请求还有一个很重要的价值是把多个上游的 token 消耗统一成一份账单。但这个事情做得好不好差别非常大。核心问题是平台统计的 token 数跟上游模型官方账单里的 token 数能不能对上我在测试中对同一个请求分别查看了 OpenMove 控制台的 token 统计、Anthropic 官方后台的 usage 记录发现 OpenMove 的统计基本能做到一致差异在 1%~3% 以内这对于内部成本归因来说足够了。LiteLLM 作为开源网关统计维度也很细能在每次请求里记录model、messages、prompt_tokens、completion_tokens、cost等字段但它更依赖你自己在配置里维护每个模型的单价表如果模型单价没配全成本统计就会是 0 或者错误。竞品C 的统计则偏“平台视角”它统计的是聚合层实际消耗的 token但不会把上游官方账单拉下来做核对差异超过 5% 我遇到过。如果团队有比较强的成本管控需求我建议在接入聚合平台之后先做两周的“双写核对”既看平台统计也看上游官方后台每个 Key 的用量两边一对比就知道平台的统计口径是不是可靠的。另外还要看平台支不支持给每个内部项目单独签发子 Key、子 Key 能不能绑定独立的模型白名单和配额上限这决定了下个月成本异常时你能不能精准定位到是哪个业务线在烧钱。4.3 稳定性、限流与故障转移机制聚合平台作为中间层天然会引入额外的链路跳数所以稳定性考察不能只看它的官网 SLA还要看它在真实故障场景下的表现。我做了两个主动故障注入测试一个是把上游 Key 改成错误的另一个是在转发过程中把上游请求设置成可访问但响应超时。第一种场景下三家都能正确返回 401 错误OpenMove 还会附带更语义化的提示比如“上游模型配置错误请检查 API Key”竞品C 则直接返回一个标准的 401 加上平台自己的请求 ID这个对排查问题也够用。第二种场景更关键。上游响应超时状态下OpenMove 在等待大约 20 秒后会返回一个 504 网关超时错误体里带有具体是哪个上游超时的信息这个对排障很有帮助LiteLLM 的超时阈值可以在配置里自定义但如果没配好默认超时时间会很长导致客户端一直干等。竞品C 的超时策略相对激进大约 10 秒就断开会触发客户端重试但如果是没有实现幂等重试的业务这反而会造成重复请求浪费上游额度。这里提醒一下无论选哪个平台客户端侧的请求超时时间一定要设置得比聚合平台的上游超时时间更长否则会出现“客户端已经放弃但聚合平台还在等上游返回”的悬空请求。限流也是一个隐藏点。聚合平台自身通常有 RPM每分钟请求数限制同时上游模型还有各自的 TPM 限制如果聚合平台不做排队和削峰突发流量会把两层的限流同时打爆。实测 OpenMove 支持在控制台为每个子 Key 设置独立的 RPM/TPM 配额还能设置全局限流策略LiteLLM 也可以通过配置文件做限流但粒度比较粗主要靠 redis 配合实现竞品C 的限流策略则偏“上游透传”它会告诉你上游 429 了但不会主动帮你做请求排队。选型时建议评估一下如果你经常有定时任务或者突发推广流量聚合平台有没有内置的排队、重试和熔断机制这些在故障时比“高可用架构”这些宣传词更实在。5. 常见问题与排查技巧实录5.1 聚合层最常见的失败模式这一轮测试下来我发现聚合平台接入失败的案例虽然五花八门但总结起来就那么几类。我把它们整理成速查表方便遇到问题时快速定位。失败现象可能原因排查方向401 错误聚合平台的 Key 配置错误或鉴权头映射缺失检查请求头里 Authorization / x-api-key 是否正确400 错误参数映射失败或缺必填参数看上游是否是 Anthropic确认 max_tokens 是否补齐404 错误协议路径不对或平台不支持该协议确认路径是 /chat/completions 还是 /messages 还是 /generateContent流式解析报错流式格式转换不完整或事件顺序错乱抓原始流式响应逐个事件对比官方协议格式工具调用失效tool_choice 映射错误或多轮 tool 消息被丢弃检查平台对 tool 消息的角色映射策略响应内容截断流式 chunk 或 finishReason 提前对比长回答的流式输出完整性用量统计偏差大平台统计口径与上游不一致双写核对官方后台与平台统计5.2 一个通用的排查思路从“请求链路”抓到底我自己的排查习惯是遇到聚合平台的问题不要先在业务代码里猜而是把整个请求链路的每一层都记录下来。最基础的一步是抓原始请求和原始响应无论用哪个平台都可以先把 SDK 的调试日志打开或者直接用 curl 按对应协议发一个最小请求看返回结果。比如用 Anthropic 协议访问 OpenMove可以先手动构造一个最简单的请求curl https://api.openmove.com/v1/messages \ -H x-api-key: $OPENMOVE_API_KEY \ -H anthropic-version: 2023-06-01 \ -H content-type: application/json \ -d { model: claude-3-5-haiku, max_tokens: 512, messages: [{role: user, content: 你好}] }如果这个请求直接返回 200说明基础链路是通的问题大概率出在 SDK 层的封装或参数映射上如果返回错误看错误体里的 code 和 message很多平台会带上自己的 request_id拿着这个 id 去控制台查日志能快速定位是网关层的问题还是上游模型的问题。第二步是确认参数映射的边界。比如temperature、top_p、max_tokens、stop这些常用参数在切换协议后到底有没有生效最好的验证办法是故意设置一个非常规值把max_tokens设成 5看输出是不是只生成了一小段把temperature设成 0 和 2故意让模型输出随机性大幅变化。如果两种值的结果没有明显差异那基本可以判断参数在聚合层被忽略了。第三步是抓流式。流式问题最烦人因为它不像普通 HTTP 错误那样有明确的状态码而是“结构不对但状态码 200”。我建议在测试脚本里把流式响应的原始字节流打印出来逐段比对协议格式。用 OpenAI SDK 调试时可以直接看response.text或者往流式回调里打个断点如果用 curl可以这样抓原始流式内容curl -N https://api.openmove.com/v1/chat/completions \ -H Authorization: Bearer $OPENMOVE_API_KEY \ -H content-type: application/json \ -d { model: gpt-4o-mini, stream: true, messages: [{role: user, content: 讲一个短故事}] }看到data: [DONE]之前的每一行确认 chunk 的字段结构是否符合 OpenAI 标准。这一步能帮你判断到底是聚合平台转换的锅还是你自己解析逻辑的锅。5.3 选型之外的一些血泪心得最后说几个这次横评之后我自己的真实感受算不上什么大道理但都是踩过坑之后的记录。第一不要只看“兼容 OpenAI / Anthropic / Gemini”这几个大字一定要问清楚兼容到第几层。很多平台的兼容文档写得天花乱坠但实际只做到了“基础对话能通”流式、工具调用、多模态这些高级特性完全没有按官方协议完整映射。我的建议是把一个最接近生产场景的测试脚本准备好选型时直接拿它跑一遍比看任何文档都靠谱。第二LiteLLM 这类开源网关上限很高但下限也很低。它默认配置下的很多行为其实不够“开箱即用”尤其是 Anthropic 和 Gemini 的协议转换需要你自己调优。如果团队里有懂网关原理的人我挺推荐用它毕竟数据不出内网可控性强如果团队没有专门的中间件负责人更建议选商业平台把精力省在业务侧。第三聚合平台不是越晚接越好也不是越早接越好。我自己的判断标准是当团队开始接第二家模型厂商时就应该引入聚合层。因为第一家模型接入的时候所有代码都是“原生对接”没有任何抽象接第二家时你突然会发现“又要写一套适配”狼狈不堪。这时候引入聚合层重构一次后面接第三家、第四家边际成本就趋近于零了。反而如果一开始就是多模型并行那就更应该把聚合层当成基础设施来建设。我个人现在团队的选择是对外部不可控流量用 OpenMove 这类商业平台靠它的完善协议映射和托管运维省心对内部自研模型和私有化部署场景用 LiteLLM 自建网关把敏感数据留在内网。这个组合目前跑了整整两个季度没有发生因为聚合层导致的线上故障。说到底聚合平台解决的是“接入问题”不是“模型效果问题”模型选型还是得靠业务需求驱动聚合层只是让这件事变得更丝滑。希望这篇横评能帮你少走点弯路尤其在协议兼容性这个文档写得最少、坑却最多的地方。