先交代下背景。我从 2023 年开始做 LLM 应用,去年接了一批 AI 聚合接口平台的项目,其中一个叫 OpenMove 的平台让我印象挺深。2026 年这个时间点,市面上的聚合接口平台已经多到眼花缭乱,但很多人的理解还停留在“把各家模型 API 打包成一个 key”上。实际上,聚合平台的生死线不在模型多不多,而在协议兼容性:你用 OpenAI SDK 写好的代码,能不能一行不改切到 Anthropic、Google、甚至其它厂商的模型上?这次横评我重点测了 OpenMove 和另外三家同类平台(下文用代号 AP、UAG、RelayX),围绕 OpenAI、Anthropic、Google Gemini 三大主流请求协议做了五个维度的实测。结果挺有意思:能连通的平台不少,但能在流式、工具调用、错误码这些细节上做到“无感切换”的,真不多。
下面把我完整的评测过程、踩坑记录和选型建议都整理出来。不管你是自己搭个内部网关,还是准备给团队选型,这篇应该都能帮你省掉不少试错时间。
1. 聚合接口平台到底在解决什么问题
1.1 一个让人抓狂的老问题
做 AI 应用的人应该都有这种体验:项目一开始只接 OpenAI,代码里全是 openai 库的调用习惯,messages 数组、tool_calls、temperature、max_tokens 都写得行云流水。结果有一天老板说“换 Claude 试试”,你打开 Anthropic 的文档才发现,system 要单独提出来,消息角色没有 assistant 的 tool 调用结构,参数名也完全不一样。等你好不容易改完,产品又说 Gemini 有个新模型效果不错,你看着满屏的contents、parts、generationConfig,只想把电脑摔了。
这个问题不是哪一家做得不好,而是各家大模型厂商的 API 风格差异实在太大。OpenAI 走的是“一个 messages 数组走天下”的路线,Anthropic 把 system 单独拆开,Google Gemini 把多模态内容塞进 parts 里,参数命名也是各说各话。如果每个模型都要写一套适配层,那项目的维护成本会指数级上升。
聚合接口平台想解决的,就是这件事:让上层应用只认一套协议,底层模型随便切换。OpenMove 这类平台本质上是个中转网关,你按 OpenAI 的格式把请求发过去,它负责翻译成 Anthropic 或 Gemini 的格式,再把响应翻译回来。理想状态下,你的业务代码几乎不用动,只需要改一下 base_url 和模型名。
1.2 OpenMove 这类平台在生态里的位置
如果画一条数据链路,大概是这样的:
你的应用/客户端 │ ▼ SDK(openai / anthropic / google-genai) │ ▼ 聚合接口平台(OpenMove / AP / UAG / RelayX) │ ▼ 各家大模型原生 API注意中间那层 SDK 很关键。聚合平台不是为了替代官方 SDK,而是让官方 SDK 变成统一入口。OpenMove 的做法是直接兼容多套协议:你可以用 openai 库指向它的 OpenAI 兼容端点,也可以把它的 Anthropic 兼容端点配到 claude 的 SDK 里,甚至可以直接用 google-genai 库调 Gemini 兼容端点。这和我几年前用的 API 网关不太一样,它不是简单的流量代理,而是做了完整的协议翻译层。
这种架构最大的好处是,业务代码和模型供应商解耦了。你今天觉得 Claude 贵,想切到便宜的开源模型;明天想试试 Gemini 的长上下文,只需要在后端配置中心改一个模型路由,应用端不用发版。对团队来说,这就是一种 AI 基础设施层面的“降本增效”。
不过平台多了,问题也来了:协议兼容不是嘴上说说那么简单,真正的兼容性体现在各种边界场景里。这也是我这次横评的出发点。
2. 横评对象与评测方法:不只看速度,更看协议兼容
2.1 参与横评的平台清单
为了避免广告嫌疑,我统一用代号。OpenMove 是这次的主角,另外三个是市面上有一定用户量的同类平台。
| 代号 | 核心定位 | 主打卖点 | 备注 |
|---|---|---|---|
| OpenMove | 全协议聚合 | 协议翻译层做得细,支持多种 SDK 直连 | 重点评测对象 |
| AP | 轻量中转 | 便宜、速度快,主打个人开发者 | 适合单模型调用,聚合能力一般 |
| UAG | 企业级网关 | 权限、审计、用量报表完善 | 配置复杂度高,学习成本高 |
| RelayX | 社区型聚合 | 模型多,更新快 | 稳定性波动较大,文档较散 |
我选这四家,是因为它们基本代表了当前聚合平台的几个流派。OpenMove 属于“协议兼容优先”的一类,AP 属于“便宜大碗”的一类,UAG 典型的是做企业服务的,RelayX 更接近社区玩家。横评不是要分个谁高谁低,而是要看出不同类型平台在协议兼容上的取舍。
2.2 三大协议具体指哪三个
这次说的“3 大协议”,是指当下应用接入最频繁的三套大模型 API 规范:
第一种是OpenAI Chat Completions 协议。核心端点是/v1/chat/completions,请求体里主要是messages数组,每个 message 有role和content,函数调用走tools和tool_calls,响应里的流式内容通过 SSE 的data:逐段输出。
第二种是Anthropic Messages API。端点是/v1/messages,和 OpenAI 最大的区别是system单独作为一个顶层参数,消息里的content可以是字符串也可以是内容块数组,工具调用用的是tool_use和tool_result块。流式响应的事件类型也完全不同,比如content_block_delta、message_delta。
第三种是Google Gemini API。端点是/v1beta/models/{model}:generateContent,数据结构里没有messages,而是contents,里面是role和parts数组。参数也不是temperature、max_tokens,而是包在generationConfig里,叫candidateCount、maxOutputTokens等。
这三套协议就像中文、日文、韩文都用了大量汉字,但语法和用词规则完全不同。聚合平台要做的,就是在它们之间做一套“同声传译”,还得保证语气、情绪都别丢。
2.3 评测维度与打分方法
我这次没有单纯测“响应快不快”,而是把协议兼容拆成五个维度:
- 基础文本兼容:普通多轮对话,看请求能否被正确翻译,响应能否被正确还原。
- 流式输出兼容:SSE 流是否能正常逐字输出,结束事件是否正确,客户端会不会卡住。
- 工具调用兼容:function calling / tool calling 的参数定义、触发方式、结果回传是否完整。
- 扩展参数兼容:比如多模态图片输入、JSON 输出、超参映射等。
- 错误码与鉴权兼容:模型不存在、鉴权失败、限流、上下文超长时,返回的错误信息是否贴近原生协议。
每个维度按 10 分制打分,总分 50。最后再用真实业务场景做一次冒烟测试,验证分数和实际体验是否一致。
有人可能会问,为什么不测价格和速度?价格不是协议兼容的范畴,而且各家平台经常调整,测了也容易过时;速度则和底座链路、目标模型有关,单独比聚合层意义不大。我这次只在同一个目标模型上记录了 P95 首字延迟,做一个参考性的辅助指标。
3. 实测过程:三个协议的真实调用记录
3.1 测试环境准备
我用了 Python 3.11,装了官方四个 SDK:openai、anthropic、google-genai,以及httpx用来抓原始请求日志。统一用一个简单的企业知识问答 prompt 做文本测试,用“查询天气并调用接口”的场景做工具调用测试。
四个平台的接入方式大同小异,核心都是替换 base_url 和 API key。区别在于 OpenMove 提供了三种不同的兼容端点,而其它平台大多只提供 OpenAI 兼容端点。这一点在后续测试里影响非常大。
先看一段 OpenMove 的配置示意。用环境变量管理密钥,这是最基本的习惯。
export OPENMOVE_API_KEY="your_openmove_key" export OPENMOVE_OPENAI_BASE="https://api.open-move.example/v1" export OPENMOVE_ANTHROPIC_BASE="https://api.open-move.example/anthropic" export OPENMOVE_GEMINI_BASE="https://api.open-move.example/gemini"注意看,OpenMove 对三个协议分别开了不同的 base path,这是它和其它“只兼容 OpenAI 协议”平台最大的不同。后面我会解释这个设计为什么更实用。
3.2 场景一:用 OpenAI SDK 调用 Anthropic 模型
这个场景非常典型:你代码里全是 openai 库的写法,但现在想看 Claude 的效果。传统做法是改代码、换库,在 OpenMove 上可以直接这样写:
from openai import OpenAI client = OpenAI( api_key=os.getenv("OPENMOVE_API_KEY"), base_url=os.getenv("OPENMOVE_OPENAI_BASE") ) resp = client.chat.completions.create( model="claude-sonnet-4-2026", # 平台侧映射到的 Anthropic 模型 messages=[ {"role": "system", "content": "你是一名企业知识助手。"}, {"role": "user", "content": "请用一句话介绍 API 网关的作用。"} ], temperature=0.3, max_tokens=300 ) print(resp.choices[0].message.content)这段代码唯一的“非标”之处就是模型名。不用改消息结构,不用管 Anthropic 的 system 参数,OpenMove 会把请求翻译过去。我实测了基础回答和工具调用两种请求,OpenMove 都能正确把 OpenAI 风格的tools转成 Anthropic 风格的tools,响应里的tool_calls也会转换回 OpenAI 格式。
相比之下,AP 平台虽然也支持model="claude-...",但它实际是在后端调 Claude 的 HTTP API 再自己包一层,遇到工具调用的嵌套对象时,偶尔会把input_schema里的 JSON Schema 字段丢掉。这个坑我后面细说。
3.3 场景二:用 Anthropic SDK 调用 OpenAI 模型
反向场景同样重要。有些团队本来用的是 Claude,现在想让业务跑在 GPT 或开源模型上,但又不想推翻整条链路的 SDK 调用习惯。
在 OpenMove 下,我把 base_url 指到它的 Anthropic 兼容端点:
import anthropic client = anthropic.Anthropic( api_key=os.getenv("OPENMOVE_API_KEY"), base_url=os.getenv("OPENMOVE_ANTHROPIC_BASE") ) resp = client.messages.create( model="gpt-5.2-2026", # 平台侧映射到的 OpenAI 模型 max_tokens=300, system="你是一名知识助手。", messages=[ {"role": "user", "content": "给出一句关于协议兼容性的比喻。"} ] ) print(resp.content[0].text)这里有个细节值得注意。anthropicSDK 会把system单独放进请求的system字段,OpenMove 收到后需要把它合并或转成 OpenAI 的 system message,再从响应里把 OpenAI 的choices[0].message.content还原成 Anthropic 的content数组格式。我在日志里观察过,OpenMove 对这部分的转换是完整的,content 数组里的type: "text"块也保留下来了。
而 UAG 在这个场景里反而出了问题。它的 Anthropic 兼容端点文档里写的是“Beta”,实测时流式输出的事件名称没有完全对齐 Anthropic 规范,导致我本地用官方 SDK 解析时抛了异常。后来查下来是它把message_delta里的stop_reason给漏了,客户端收不到“结束”信号,一直不 return。这种问题在单次请求里很难暴露,一上流式就原形毕露。
3.4 场景三:用 Gemini SDK 调用聚合平台的统一出口
Gemini 的 API 风格和前两者差异最大。以前想在一个项目里同时用 Gemini 和 OpenAI,基本得写两套客户端逻辑。OpenMove 的解决方案是提供 Gemini 兼容端点,让已有的google-genai代码能直接走聚合层。
from google import genai client = genai.Client( api_key=os.getenv("OPENMOVE_API_KEY"), http_options={"base_url": os.getenv("OPENMOVE_GEMINI_BASE")} ) resp = client.models.generate_content( model="openai-gpt-5.2-2026", contents="用一句话解释 Protocol Buffers。" ) print(resp.text)这里有个很微妙的点:如果目标模型是 OpenAI 系,OpenMove 需要在 Gemini 协议的contents格式和 OpenAI 的messages格式之间互转。contents里的 user 角色好办,但多轮对话里 assistant 的回复如果带了 function call,转换就会复杂很多。我的测试里把 temperature、maxOutputTokens 都传进generationConfig,OpenMove 能正确映射到 OpenAI 的对应参数,这一点做得比较干净。
RelayX 的 Gemini 兼容端点也测了,结果却不理想。它的文档里写“支持”,实际调用时经常返回 400,错误信息是unsupported parameter: safetySettings。也就是说,它并没有做完整参数过滤,而是把 Gemini 原生请求直接转发给了一个默认模型,原生参数一旦落到 OpenAI 模型上就报错。这属于典型的“半兼容”。
4. 兼容性实测结果:能通只是基础,细节全是坑
4.1 协议转换的成功率与差异
整个测试下来,我整理了下面这张汇总表。每一项都是实际跑过的,不是看文档得出的结论。
| 测试项 | OpenMove | AP | UAG | RelayX |
|---|---|---|---|---|
| 普通多轮文本 | 通过 | 通过 | 通过 | 通过 |
| 流式输出(OpenAI SDK) | 通过 | 通过 | 通过 | 通过 |
| 流式输出(Anthropic SDK) | 通过 | 失败 | 失败 | 失败 |
| 流式输出(Gemini SDK) | 通过 | 不支持 | 通过 | 失败 |
| 工具调用定义与触发 | 通过 | 部分丢字段 | 通过 | 通过 |
| 工具结果回传后二次请求 | 通过 | 部分丢失 | 通过 | 失败 |
| 多模态图片输入 | 通过 | 失败 | 通过 | 部分通过 |
| JSON 输出格式 | 通过 | 通过 | 通过 | 通过 |
| 错误码映射 | 规范 | 不规范 | 一般 | 不规范 |
| 鉴权失败提示 | 通过 | 通过 | 通过 | 通过 |
从这个表能看出来,基础文本兼容几乎人人都会,但一到流式、工具调用、多模态这些偏门场景,差距就拉开了。OpenMove 是唯一一个在三个协议的流式测试里全部通过的平台。其它平台要么是不支持某个协议端点,要么是支持但细节没有对齐。
4.2 OpenMove 在“细节兼容”上的表现
OpenMove 给我留下最深印象的不是“能不能通”,而是它对参数映射的细节处理。举个具体的例子,OpenAI 的max_tokens到了 Gemini 那边要变成maxOutputTokens,如果映射漏了,模型会默默用默认值,这在小模型上可能没什么感觉,但在需要精确控制输出长度的金融、法务场景里,直接会导致结果被截断。
它另一个做得好的地方是 system prompt 的处理。OpenAI 允许system和developer两种角色,Anthropic 只有一个system字段,Gemini 甚至通常把 system 指令放在system_instruction里。OpenMove 在转换时会做合并和拆分,而不是简单地把 system role 当成普通消息丢掉。我在日志里验证过,多轮对话里 system 信息不会被后续 user 消息覆盖。
还有一个细节是工具调用。很多平台在把 OpenAI 的tool_calls翻译成 Anthropic 的tool_use块时,只翻译了第一层,导致嵌套对象的input字段丢失。OpenMove 在这个地方做了递归转换,我在测试工具里传了一个带复杂 JSON Schema 的“天气查询工具”,返回的 tool 参数结构和原生调用完全一致。
4.3 其它平台的槽点
前面也提到了不少,这里集中说一下。
AP 的问题是“半兼容”。它只提供一个 OpenAI 兼容端点,Anthropic 和 Gemini 的 SDK 都接不了。如果你只是个人用 OpenAI 体系,它足够便宜;但想切协议,基本就得重写代码。它的工具调用有时会丢字段,我连续测了五次,有两次input_schema里的enum丢失,这个问题在联调时非常难排查,因为不是必现而是偶发。
UAG 的企业功能很全,但协议兼容端点的文档更新滞后。它的 Anthropic 兼容端点标了 Beta,实测也确实不稳定,流式事件缺失就是很典型的表现。对团队来说,这不是说不能用,而是需要预留额外的兼容层修复时间。
RelayX 更像一个“社区集合”,好处是模型种类多、上新快,坏处是协议兼容完全靠社区贡献,质量参差不齐。Gemini 端点不支持safetySettings只是冰山一角,我还遇到过 Gemini 端点在 tool 调用时返回的 finishReason 和原生 API 不一致,造成客户端误判。
5. 协议兼容性背后的原理:一次翻译,N端适配
5.1 协议转换不是“改个 URL”那么简单
很多人以为聚合平台就是一层反向代理,把请求 URL 改一下转发出去,再把响应原样返回。实际上,协议转换要处理的东西远比想象中多。
请求侧至少要做三层工作。第一层是端点路由,不同协议对应不同路径;第二层是参数映射,同一个语义的参数在不同协议里叫法不同;第三层是消息结构转换,把数组、嵌套块、角色定义全部重塑。响应侧也一样,要把目标模型返回的数据重新组装成调用方协议的样子,同时还不能丢字段。
可以把它理解成一个翻译团队:不仅要把中文翻译成英文,还要把成语、双关语、文化背景都解释清楚。比如 OpenAI 的finish_reason有stop、length、tool_calls,Anthropic 的stop_reason有end_turn、max_tokens、tool_use,两者不是一一对应,翻译时需要有规则映射,而不是简单地照抄。
5.2 流式兼容的难点
流式是最容易暴露协议兼容问题的环节,因为它是持续性的,不是一次请求一次响应。客户端要和平台之间建立一条 SSE 长连接,平台要和目标模型之间再建立一条连接,中间还要做逐段翻译。
OpenAI 的流式事件一般是choices[0].delta.content,Anthropic 是content_block_delta的delta.text,Gemini 是candidates[0].content.parts里的text。翻译层需要在每个 chunk 到达时做结构替换,还得保持顺序。更麻烦的是结束信号:OpenAI 的流式结束靠finish_reason,Anthropic 靠message_delta里的stop_reason,Gemini 靠finishReason。如果一个平台只翻译了内容块,忘了翻译结束信号,客户端的for await循环就会一直等下去,看起来就是“卡住不动”。
OpenMove 在处理流式时还做了一件事:它会透传 usage 信息,而不是像有些平台那样偷偷丢掉。这对做 token 计费、用量统计的应用来说非常重要。
5.3 参数映射表
我把三个协议里最常见的参数映射关系整理了一下,聚合平台如果没有按照下面这张表的逻辑去实现,基本可以判断为不合格。
| 语义 | OpenAI | Anthropic | Gemini | OpenMove 映射情况 |
|---|---|---|---|---|
| 最大生成 Token 数 | max_tokens | max_tokens | maxOutputTokens | 有映射 |
| 温度 | temperature | temperature | generationConfig.temperature | 有映射 |
| 采样概率 | top_p | top_p | topP | 有映射 |
| 系统指令 | messages 中 role=system | system 字段 | system_instruction.contents | 合并/拆分 |
| 多轮消息 | messages 数组 | messages 数组 | contents 数组 | 有转换 |
| 工具定义 | tools | tools | tools / functionDeclarations | 有转换 |
| 工具调用结果 | tool 角色消息 | tool_result 内容块 | functionResponse part | 有转换 |
| 停止符 | stop | stop_sequences | stopSequences | 有映射 |
从这个表能看出来,刚提到的这些参数在语义上基本是共通的,只是外衣不一样。一个合格的聚合平台要做的不是“尽量兼容”,而是“每一个参数都映射到位”。只要有一项漏了,边界场景就会翻车。
6. 选型建议与避坑清单
6.1 什么场景适合用聚合接口平台
经过这轮横评,我的结论是:不要盲目上聚合平台,先看自己的使用场景。
如果你是个人开发者或者小团队,正在做原型验证,模型切换频繁,那 OpenMove 这类协议兼容做得好的平台非常合适。你可以在一天内把同一个应用分别接到 GPT、Claude、Gemini 上对比效果,这比单独申请各家 API 再写适配层快太多了。
如果你的业务已经稳定跑在某个单一模型上,而且没有短期内切换模型的计划,那直接调官方 API 反而是最稳的选择。多一层转发就多一层风险,没必要为了“可能的需求”提前引入复杂架构。
但如果你是在做 toB 产品,需要同时服务多个客户、多个模型,或者你要把模型能力卖给下游开发者,那协议兼容聚合平台几乎是必需品。你的客户不可能都用同一套 SDK,你需要给不同的客户提供不同的接入协议,OpenMove 这种“三协议同时兼容”的方案就有明显优势。
6.2 我踩过的坑和排查技巧
这轮测试里我也踩了不少坑,挑几个典型的分享出来。
第一个坑是模型名写错导致 404 而不是 400。有些平台在模型不存在时返回 404,但错误信息里没有目标模型名,排查起来特别慢。我后来统一在客户端打印model字段,至少能确认是聚合层映射问题还是密钥问题。
第二个坑是流式环境下的代理干扰。测试 RelayX 时,流式中断我一直以为是平台问题,后来才发现是我本地抓包工具把 SSE 的 chunk 缓冲了。排查的时候先把抓包工具关掉,用最简单的httpx脚本直接读原始响应,确认平台侧没问题再上 SDK。
第三个坑是工具调用结果的二次请求失败。Anthropic 的工具调用流程里,模型返回tool_use后,你需要把用户实际执行的工具结果用tool_result内容块传回去。有些聚合平台只做了第一次转换,没有把tool_result再转回 OpenAI 的 tool role message,导致第二轮请求失败。这个问题在 OpenMove 上没出现,但在 RelayX 上必现,测试时一定要跑完整的多轮工具调用链路。
第四个坑是用量统计对不上。聚合平台上报的 token 用量经常和模型官方返回的不一致,这可能是转换过程中自己重新计算了 token,也可能是丢了 usage 字段。如果是计费敏感的业务,建议以目标模型官方日志为准,不要让聚合平台直接参与出账。
6.3 选型时可以重点关注的四个能力
最后给一个可以直接抄作业的选型清单:
- 第一,看它是否提供多个协议的 SDK 兼容端点,而不只是 OpenAI 兼容端点。这是能不能做到“代码不用大改”的基础。
- 第二,用一个小工具函数测三轮完整的工具调用链路,而不是只测单轮对话。很多平台死在这一步。
- 第三,对比流式输出时的结束事件是否完整。可以写一个三分钟脚本,记录从发起请求到流结束的原始事件,确认没有漏事件。
- 第四,看一下错误码映射。模型限流、上下文超长、鉴权失败,这些常见错误返回给客户端时,是否符合你所使用 SDK 的异常解析规则。
我自己在实际选型时,会先把目标模型列表和协议类型列出来,再根据这张表打分。OpenMove 这轮的评分是 49 分,扣掉的 1 分在于它的控制台自定义模型路由配置,首次使用时入口有点隐蔽,需要点进“高级设置”才能找到。但对最终要写代码的人来说,这不是大问题。
这次横评最大的体会就是:协议兼容性这东西,文档上写着“支持”只代表能连通,不等于细节完整。真正决定一个聚合平台能不能省心,要看那些平时不会写进宣传页的地方。后面我还会再测一测这些平台的私有化部署方案,到时候再来分享。