开发 AIGC 应用、Codex 类代码助手或 Agent 智能体时,模型能力只是系统上限,API 基础设施决定的却是可用下限。一次请求可能遇到首包延迟升高、SSE 中途断流、429 Rate Limit、渠道配额耗尽、模型别名失效,也可能在 Failover 后重复计费。只比较单次响应速度,无法回答"哪个方案更适合生产"。
本文把评测对象分为三类:直接连接模型供应方;自建 LiteLLM、One-API、New-API 等开源项目;接入提供统一协议的云端中继。评测覆盖协议损耗、并发性能、长文本、多模态兼容、故障恢复、IT 运维成本和综合性价比。需求中列出的 DeepSeek-V3/R1、Claude 3.5 Sonnet、GPT-4o/Codex API、Qwen2.5-Coder 与 Flux API 均按历史或控制台路由别名理解,不把名称等同于 2026 年长期固定的模型版本、能力或可用区域。
必须先说明数据边界:没有同一批有效 API Key、相同账户配额、统一地域和真实账单,就不能发布供应商排行榜。本文的策略对比数据来自固定种子的本地故障注入回放,用于验证路由算法,不代表任何厂商实测成绩;真实模型表提供可复现的填表方法。这样的白皮书可能少一点戏剧性,却能避免把网络时段、账户等级和模型差异误写成平台结论。
一、核心参数解析与 API 中继架构机制初探
LLM Gateway 位于应用与多个模型端点之间,典型职责包括协议归一化、鉴权隔离、模型别名解析、Token 预算、并发整形、路由选择、Failover、日志审计与费用归因。它不是简单的反向代理。普通 HTTP 代理只需把请求转发到固定上游,而大模型网关还要理解请求是否可重试、流式事件是否完整、工具调用是否允许切换模型,以及同一会话能否跨路由保持语义一致。

一条请求的端到端时延可拆为:
T_{total}=T_{dns}+T_{connect}+T_{tls}+T_{queue}+T_{gateway}+T_{provider}+T_{stream}
开启 HTTP/2、Keep-Alive 和连接池后,DNS、TCP、TLS 成本通常能被摊薄;真正容易被忽略的是 T_queue 与 T_gateway。当网关的并发信号量耗尽,请求还未抵达供应方便已排队。若日志只记录上游耗时,IT 运维会误判模型变慢。每条 Trace 至少应记录接收时间、入队时间、出队时间、上游连接时间、首个 SSE 事件时间和最后事件时间。
SSE 不是普通 JSON 响应
流式接口使用 text/event-stream 时,网关必须按事件边界增量转发,不能等待完整响应后再统一输出。对 Chat Completions 风格响应,需要合并 choices[].delta.content 和增量 tool_calls;对其他响应族,则要保留其事件类型、调用 ID 和结束语义。若网关擅自把未知事件压成文本,Codex 或 Agent 可能看到内容,却丢失工具调用。
中继还可能转换 Header,但转换必须最小化。Authorization、组织或项目标识、幂等键、请求 ID、超时预算和内容类型都应有明确白名单;不能把客户端内部密钥转发给错误供应方,也不能在日志中记录完整 Bearer Token。对于 OpenAI API 协议兼容端点,兼容应定义为"通过契约测试的字段集合",而不是"路径长得像 /v1"。
| 架构 | 优势 | 主要损耗 | 主要风险 |
|---|---|---|---|
| 供应方直连 | 路径短、故障边界清晰 | 客户端需分别适配 | 密钥分散、缺少统一治理 |
| 自建开源网关 | 规则可控、数据边界清楚 | 部署、升级和轮值成本 | 配置漂移、单点故障 |
| 云端统一中继 | 接入快、跨模型协议集中 | 多一层网络与信任边界 | 能力与 SLA 需逐项验证 |
| 混合架构 | 兼顾主路由与退出能力 | 设计和测试最复杂 | 双系统语义不一致 |
评测网关开销时,应使用同一个 Mock Provider 回放相同 SSE 序列,分别测直连与经过网关的 P50、P95、P99,而不是拿两个真实模型的自然波动做差。应关注 gateway_overhead = TTFT_gateway - TTFT_direct、事件间隔抖动和断流率。只有当测试输入、连接复用和事件数量一致,损耗结论才成立。
网关自身还应拆成控制面和数据面。控制面负责路由配置、密钥引用、价格表、能力目录与策略发布,不应位于每个 Token 的热路径;数据面负责鉴权、限流、选路和流式转发。若每个 SSE 事件都同步查询数据库或远程策略服务,TPS 越高,网关抖动越明显。可通过配置快照和本地只读缓存降低热路径依赖,但每条日志必须带 policy_version,否则无法复盘某次请求为何选中某条路由。
数据面基线还应包含内存与文件描述符。长连接会让低 CPU 网关先耗尽连接池、Socket 或缓冲区;若代理对每个流缓存完整正文,输出越长,内存峰值越高。压测时应同时采集活动连接、待获取连接数、事件循环延迟、RSS、GC 暂停和上游连接复用率。只有延迟曲线和资源曲线同时稳定,才能说明网关具备横向扩展价值。
二、高并发环境下的 API 响应延迟与吞吐量实测
大模型性能不能只用"接口耗时"描述。首包延迟(TTFT)衡量用户多久看到第一个 Token;每秒 Token 数(TPS)衡量开始生成后的输出速度;端到端时延还受输出长度影响。对代码助手,TTFT 往往比最终耗时更影响交互感;对离线批处理,吞吐、成功率和单位 Token 成本更重要。
建议压测采用固定请求集:短问答、4K Token 代码上下文、32K 长文档和工具调用各占一定比例;输出长度设上限;每个路由先预热,再按 1、4、16、32、64 并发逐级升压。压测工具必须读取完整流,否则连接在首包后立即关闭,会高估供应方吞吐并掩盖中途断流。
真实供应商对比表应按同一时间窗填写,下面不预填虚假数字:
| 路由别名 | 请求集版本 | 并发 | TTFT P50/P95 | TPS P50 | 成功率 | 429 占比 | 中途断流率 |
|---|---|---|---|---|---|---|---|
deepseek-chat-prod |
bench-v1 |
待测 | 待测 | 待测 | 待测 | 待测 | 待测 |
claude-code-prod |
bench-v1 |
待测 | 待测 | 待测 | 待测 | 待测 | 待测 |
gpt-codex-prod |
bench-v1 |
待测 | 待测 | 待测 | 待测 | 待测 | 待测 |
qwen-coder-prod |
bench-v1 |
待测 | 待测 | 待测 | 待测 | 待测 | 待测 |
"待测"不是缺陷,而是实验诚实性。模型名称、账户配额与区域都可能变化,只有路由解析结果、响应头、请求 ID 和采集时间一起归档,数据才有解释力。
一个可复用的异步压测骨架
以下脚本保留 SSE 完整读取、分阶段计时和并发信号量。生产使用时还需加入脱敏、Token 解析器与指标输出;API_KEY 只从环境变量读取。
python
import asyncio
import json
import os
import time
import httpx
URL = os.environ["BENCH_URL"]
KEY = os.environ["API_KEY"]
async def one(client, sem, request_id):
payload = {
"model": os.environ["MODEL_ALIAS"],
"messages": [{"role": "user", "content": "解释这段代码的并发风险"}],
"stream": True,
"max_tokens": 512,
}
async with sem:
start = time.perf_counter()
first = None
events = 0
async with client.stream(
"POST", URL, json=payload,
headers={"Authorization": f"Bearer {KEY}", "X-Bench-Id": request_id},
) as response:
response.raise_for_status()
async for line in response.aiter_lines():
if not line.startswith("data:") or line == "data: [DONE]":
continue
first = first or time.perf_counter()
json.loads(line[5:].strip())
events += 1
end = time.perf_counter()
return {
"ttft_ms": None if first is None else (first - start) * 1000,
"total_ms": (end - start) * 1000,
"events": events,
}
async def main(concurrency=16, total=100):
sem = asyncio.Semaphore(concurrency)
timeout = httpx.Timeout(connect=5, read=120, write=20, pool=5)
async with httpx.AsyncClient(timeout=timeout, http2=True) as client:
rows = await asyncio.gather(*[
one(client, sem, f"bench-{i:04d}") for i in range(total)
], return_exceptions=True)
print(rows)
asyncio.run(main())
TPS 计算必须使用实际输出 Token 数,而不是 SSE 事件数,因为一次事件可能包含多个 Token,也可能只包含控制字段。错误率也不能只统计非 200:HTTP 200 后断流、缺少结束标志、JSON 不完整和工具调用参数无法解析,都属于失败。高质量 IT 运维面板应同时呈现传输成功率与业务可用率。
压测模式也会改变结论。闭环压测由上一请求完成后再发送下一请求,系统变慢时负载会自动下降,容易掩盖排队崩溃;开放环压测按固定到达率发送,更接近真实高峰,却必须限制本地队列,防止压测机自身成为瓶颈。建议两者都做:闭环寻找单用户交互延迟,开放环寻找容量拐点。
还要避免 coordinated omission,即"系统卡住时压测器也停止发请求,从而漏记本应到达的慢请求"。报告应给出目标到达率、实际发送率、完成率和丢弃率,并把客户端排队时间计入端到端时延。P95 从 2 秒升到 8 秒而请求量下降一半,并不代表系统仍可用。
下面是一条建议的脱敏抓包记录。它把路由、策略、阶段时延和终态放在同一行,同时不暴露 Prompt 与密钥:
text
ts=2026-08-07T03:21:44Z trace_id=tr_7f2a bench_id=bench-0412
route=route-a policy=fastest-v3 attempt=1 http=429 retry_after_ms=900
queue_ms=18 connect_ms=42 ttft_ms=null output_tokens=0 final=rate_limited
模型输出质量也会污染 TPS 对比。某一路由每秒生成更多 Token,却需要更长、更重复的答案,业务效率未必更高。对代码场景可加入编译通过率、测试通过率和补丁接受率;对问答可加入事实检查与格式合规率。最终使用 有效吞吐 = TPS × 质量通过率 × 请求成功率,比单独比较 Tokens-Sec 更接近交付价值。
三、异构 API 鉴权与 Codex 代码补全场景下的长文本稳定性
Codex 类代码助手的请求具有长上下文、低延迟、多轮状态和工具调用四个特征。它可能上传仓库片段、诊断日志和补丁上下文,输出又需要边生成边展示。网关若只按普通聊天设计,最容易在大小限制、读超时、事件转换和调用 ID 上出错。
鉴权测试应覆盖三条路径:供应方直连、通过网关转发、由桌面客户端或 IDE 生成。抓包时只记录密钥指纹,不记录明文;检查最终 URL、HTTP 方法、Authorization 是否恰好一个 Bearer 前缀、代理是否删除或重复 Header,以及响应中的请求 ID。大量 invalid_api_key 并非密钥本身错误,而是 Key 与 Base URL 属于不同账户体系,或客户端把完整 /v1/chat/completions 再拼接了一遍。
长上下文不是只调大 timeout
长请求至少有连接、写入、首包、读空闲和总截止时间五个阶段。统一使用一个 600 秒超时,既无法定位瓶颈,也会让队列堆积。建议分别配置:连接 3--5 秒、写入随请求体大小调整、首包按模型类别设置、流式读空闲按心跳或 Token 间隔设置、总截止时间由调用链预算决定。
当 Context 超限时,不应盲目 Failover 到另一路由。新路由若上下文窗口、工具 Schema 或系统指令语义不同,重试仍会失败,甚至产生不同答案。正确流程是先由 Token 估算器在网关入口拒绝明显超限请求,再按内容优先级压缩:保留系统约束、当前任务、相关代码和工具结果,删除重复日志与无关历史。所有压缩都应产生 context_manifest,记录哪些片段被保留或丢弃。
| 测试项 | 注入方式 | 通过标准 |
|---|---|---|
| 8/32/64K 上下文阶梯 | 固定代码语料逐级扩展 | 无静默截断,超限返回明确分类 |
| SSE 中途断开 | 第 N 个事件后关闭连接 | 状态标记为未知或失败,不拼接伪完整答案 |
| 工具调用增量 | 拆分函数名和 JSON 参数 | 按调用 ID 合并,参数可解析 |
| 客户端取消 | 首包后主动断开 | 上游取消可观测,费用账本保留 |
| 超时后重试 | 注入首包延迟 | 仅幂等请求重试,共享总截止时间 |
工具调用是 Codex 稳定性的分水岭。Chat Completions 的工具结果通常需要关联供应方返回的 tool_call_id;其他响应协议可能使用 call_id。内部 Job ID、Trace ID 不能替代这些协议标识。网关可归一化展示字段,但回传上游时必须保存原始调用关联,否则会得到 400 错误或把结果绑定到错误工具。
长文本测试还要覆盖请求体字节数。Token 数未超限,不代表 Nginx、WAF、框架解析器和日志代理都能接收同样大小的 UTF-8 JSON;Base64 图片更会把请求体放大。应执行 1、2、4、8、16 MiB 的 Size Ladder,逐层记录谁返回 413,以及限制发生在 CDN、反向代理还是应用。修改限制后,从外到内逐级复测,避免只放大最外层却仍被内层解析器拒绝。
取消语义同样影响成本。用户在 IDE 中停止生成后,客户端断开不一定等于上游任务取消。网关应监听连接关闭,调用供应方支持的取消机制,并在账本中记录"客户端已离开、上游是否停止、已输出多少 Token"。若无法确认取消成功,状态应为 accepted_unknown,而不是伪装成零成本失败。
代码上下文还涉及数据治理。发送前应排除 .env、私钥、凭据、个人数据和无关大文件;审计日志保存内容哈希、文件类型和大小,不保存源码全文。多租户缓存键必须包含租户、模型路由、系统指令版本和权限版本,防止相同 Prompt 命中另一项目的结果。稳定性评测若忽略数据隔离,即使延迟再低也不能进入生产。
四、复杂多模态模型混合调度的接口兼容性解剖
"兼容 OpenAI 协议"常被错误理解为所有模型共用同一 JSON。文本、视觉、图像生成、语音合成和视频任务在输入、输出与生命周期上差异巨大。文本可以同步流式返回;Flux API 或其他图像路由可能先返回异步任务 ID;TTS 返回二进制音频;视觉输入可能使用 URL、Base64、文件引用或供应方资产 ID。一个万能转换器若没有能力清单,只会把错误延迟到上游。
网关应为每个路由维护 Capability Manifest:支持的请求族、模态、上下文上限、文件大小、流式语义、工具调用、结构化输出、异步任务、回调、安全策略与计费单位。路由前先做硬过滤,确认能力满足,再讨论价格和速度。将不支持图片的廉价文本路由选为第一候选,只会制造无意义 400 与重试成本。
json
{
"route": "image-generation-prod",
"request_family": "image_task",
"modalities": ["text", "image"],
"async": true,
"inputs": {
"prompt": "string",
"reference_images": "asset_ref[]",
"width": "integer",
"height": "integer"
},
"outputs": {
"task_id": "string",
"status": ["queued", "running", "succeeded", "failed"]
}
}
兼容性评测不应只判断 HTTP 200。建议为文本、图像、语音各建立金丝雀样本,对请求 Schema、最终出站 JSON、响应类型和资产完整性做断言:文本必须能还原结束原因;图像任务必须轮询到终态并验证 MIME、尺寸和哈希;音频任务必须验证采样率、时长和容器。若网关把图像错误页保存为 .png,状态码成功也不能算通过。
| 模态 | 典型契约差异 | 常见故障 | 应记录的证据 |
|---|---|---|---|
| 文本/代码 | SSE、工具调用、结构化输出 | 事件丢失、JSON 参数破碎 | request ID、事件序列、finish reason |
| 视觉理解 | 远程 URL、Base64、文件 ID | 图片不可达、MIME 错误 | 资产哈希、大小、读取结果 |
| 图像生成 | 异步 Task、尺寸、Seed | 轮询超时、回调乱序 | Task 状态史、输出哈希 |
| TTS/ASR | 二进制、采样率、语言 | 内容类型错、音频截断 | 时长、编码、转写校验 |
多模态路由的降级必须显式。例如图像模型不可用时,可以返回"任务暂不可执行",却不能静默切换到只支持文本的模型并生成图片描述;TTS 失败时也不能把文本 JSON 当音频返回。降级的首要目标是语义正确,其次才是请求不报错。
Schema 版本应成为路由条件。客户端发送 request_schema=v3 后,网关只能选择通过 v3 契约测试的适配器;若供应方新增字段,先进入影子解析与兼容测试,再升级生产映射。对未知字段应采取保留、拒绝或显式丢弃三种策略之一,并写入日志,不能悄悄吞掉。很多"模型不听指令"其实是中继层删除了参数。
资产服务则需要独立谱系。上传图片或音频时生成内容哈希、MIME、尺寸、租户、来源和过期时间;上游返回新资产后建立父子关系。这样才能判断一次 Flux API 编辑究竟使用了哪张参考图,也能在临时链接过期后重放测试。多模态评测的最小证据包应同时包含请求 Schema、出站映射、状态事件、资产哈希和最终人工验收结论。
五、异常链路处理与智能调度策略验证
本章只把智能调度作为十个维度中的一个实验变量。我们建立三条匿名路由:A 速度快、价格高、限流概率较高;B 便宜且相对稳定、速度较慢;C 位于两者之间。固定随机种子为 20260807,回放 1200 个请求,并在第 400--519 个请求期间给 A 额外注入 16% 限流。每次成功响应模拟约 520 个输出 Token。
| 匿名路由 | 基准 TTFT | 抖动标准差 | 模拟 TPS | 每百万输出 Token 成本 | 基础错误率 | 基础 429 率 |
|---|---|---|---|---|---|---|
| A | 620 ms | 180 ms | 70 | 6.0 | 2.5% | 11.5% |
| B | 980 ms | 260 ms | 54 | 2.4 | 1.8% | 3.5% |
| C | 790 ms | 210 ms | 62 | 4.1 | 2.2% | 6.0% |
四种策略分别为:最低价格始终选 B;最快响应始终选 A;最高成功率按静态错误基线选主路由并允许一次 Failover;综合策略按价格、TTFT 与指数移动错误率打分,允许一次切换。以下是本地回放结果,不是供应商成绩:
| 策略 | 成功率 | 空跑率 | TTFT P50 | TTFT P95 | TPS 中位数 | Failover P95 | 单次成功模拟成本 |
|---|---|---|---|---|---|---|---|
| 最低价格 | 95.58% | 4.42% | 977 ms | 1418 ms | 53.47 | 不切换 | 0.001243 |
| 最快响应 | 85.83% | 14.17% | 608 ms | 892 ms | 69.55 | 不切换 | 0.003118 |
| 最高成功率 | 99.17% | 0.83% | 971 ms | 1413 ms | 53.72 | 414 ms | 0.001318 |
| 综合策略 | 99.25% | 0.75% | 947 ms | 1389 ms | 54.59 | 412 ms | 0.001452 |
回放说明三件事。第一,最快策略确实拥有更低 TTFT,却在突发 429 下产生最高空跑率;第二,最低价格不能等同于最低交付成本,因为失败会占用队列与人工重试;第三,综合策略在该权重与故障模型下改善了成功率,但成本高于最低价格,也没有证明它在所有负载下最佳。改变流量、错误相关性和权重,排名可能变化。
一个可解释的 Token 路由算法应先硬过滤,再计算软分数:
Score_i=w_c\\hat C_i+w_l\\hat L_i+w_e\\hat E_i+w_q\\hat Q_i+w_s\\hat S_i
其中成本、延迟、近期错误、队列深度和语义能力均归一化;分数越低越优。错误 EWMA 需要时间衰减,不能让一次故障永久封禁路由。429、500、超时也应分类:余额不足和权限错误不可重试;短暂 429 可遵循 Retry-After;连接失败可切换;首包超时后的任务是否已被接受则可能未知,不能无脑并发重发。
Failover 不是"失败就换一家"
切换必须满足四个条件:请求具有幂等性或幂等键;候选路由能力等价;仍有总截止时间和重试预算;计费账本能记录每次尝试。对流式请求,一旦已向用户输出内容,再切模型会导致语言和工具状态断裂。更稳妥的策略是中止并标记部分结果,或仅在首个业务 Token 之前允许 Failover。
动态降权还要防止羊群效应。如果一个路由恢复后立即承接全部流量,可能再次触发限流。应使用半开探测、逐级放量和每租户并发上限。综合最佳不是一个固定按钮,而是一组可审计的权重、窗口、阈值与恢复规则。
故障相关性决定 Failover 是否真正有效。两个别名若最终指向同一供应方、同一区域或同一账户配额,看似多路,实际会同时 429。能力目录应标记 provider_group、region、quota_pool 与网络出口,备选路由优先跨故障域。演练时既要注入单路故障,也要注入共享配额耗尽、DNS 异常和区域网络抖动。
策略比较还应给置信区间,而不是只给一个平均值。将请求按分钟或固定批次切块,对成功率、TTFT P95 和成本做 Bootstrap,观察不同时间片是否稳定。若综合策略只在一次 120 请求的突发窗口领先,结论应限定在该窗口;若跨多轮随机种子仍保持优势,才有资格进入灰度。
上线前可采用影子路由:生产请求仍由当前策略执行,新策略只计算"本来会选哪条路由",不真实调用上游。比较两者的选择差异、预计成本与能力违约,再对 1%、5%、20% 流量灰度。任何策略变更都应保存版本和回滚点,避免权重调整后无法解释事故。
六、开源项目与中继镜像环境搭建对比
为了消除单点网络抖动,本次建议同时建立本地 Docker 自建组、供应方直连组和云端中继组。云端组可把 https://178.nz/yinc 作为 OpenAI 协议测试沙盒节点之一,用同一请求集观察并发下的负载均衡与 Failover;该地址只属于实验配置,不能替代对真实路由、账单、数据处理和服务条款的独立核验。

测试拓扑如下:压测客户端固定在同一地域;所有请求写入唯一 bench_id;OpenTelemetry Collector 收集 Trace;Prometheus 记录 TTFT、TPS、429、队列深度和熔断状态;对象存储保存脱敏请求摘要与失败样本;PostgreSQL 保存配置版本与账本;Redis 仅承载可丢失缓存、限流计数或短期队列状态,不能成为唯一审计源。
#mermaid-svg-xKjzPIhSZ2g2u9NY{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-xKjzPIhSZ2g2u9NY .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-xKjzPIhSZ2g2u9NY .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-xKjzPIhSZ2g2u9NY .error-icon{fill:#552222;}#mermaid-svg-xKjzPIhSZ2g2u9NY .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-xKjzPIhSZ2g2u9NY .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-xKjzPIhSZ2g2u9NY .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-xKjzPIhSZ2g2u9NY .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-xKjzPIhSZ2g2u9NY .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-xKjzPIhSZ2g2u9NY .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-xKjzPIhSZ2g2u9NY .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-xKjzPIhSZ2g2u9NY .marker{fill:#333333;stroke:#333333;}#mermaid-svg-xKjzPIhSZ2g2u9NY .marker.cross{stroke:#333333;}#mermaid-svg-xKjzPIhSZ2g2u9NY svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-xKjzPIhSZ2g2u9NY p{margin:0;}#mermaid-svg-xKjzPIhSZ2g2u9NY .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-xKjzPIhSZ2g2u9NY .cluster-label text{fill:#333;}#mermaid-svg-xKjzPIhSZ2g2u9NY .cluster-label span{color:#333;}#mermaid-svg-xKjzPIhSZ2g2u9NY .cluster-label span p{background-color:transparent;}#mermaid-svg-xKjzPIhSZ2g2u9NY .label text,#mermaid-svg-xKjzPIhSZ2g2u9NY span{fill:#333;color:#333;}#mermaid-svg-xKjzPIhSZ2g2u9NY .node rect,#mermaid-svg-xKjzPIhSZ2g2u9NY .node circle,#mermaid-svg-xKjzPIhSZ2g2u9NY .node ellipse,#mermaid-svg-xKjzPIhSZ2g2u9NY .node polygon,#mermaid-svg-xKjzPIhSZ2g2u9NY .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-xKjzPIhSZ2g2u9NY .rough-node .label text,#mermaid-svg-xKjzPIhSZ2g2u9NY .node .label text,#mermaid-svg-xKjzPIhSZ2g2u9NY .image-shape .label,#mermaid-svg-xKjzPIhSZ2g2u9NY .icon-shape .label{text-anchor:middle;}#mermaid-svg-xKjzPIhSZ2g2u9NY .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-xKjzPIhSZ2g2u9NY .rough-node .label,#mermaid-svg-xKjzPIhSZ2g2u9NY .node .label,#mermaid-svg-xKjzPIhSZ2g2u9NY .image-shape .label,#mermaid-svg-xKjzPIhSZ2g2u9NY .icon-shape .label{text-align:center;}#mermaid-svg-xKjzPIhSZ2g2u9NY .node.clickable{cursor:pointer;}#mermaid-svg-xKjzPIhSZ2g2u9NY .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-xKjzPIhSZ2g2u9NY .arrowheadPath{fill:#333333;}#mermaid-svg-xKjzPIhSZ2g2u9NY .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-xKjzPIhSZ2g2u9NY .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-xKjzPIhSZ2g2u9NY .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xKjzPIhSZ2g2u9NY .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-xKjzPIhSZ2g2u9NY .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xKjzPIhSZ2g2u9NY .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-xKjzPIhSZ2g2u9NY .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-xKjzPIhSZ2g2u9NY .cluster text{fill:#333;}#mermaid-svg-xKjzPIhSZ2g2u9NY .cluster span{color:#333;}#mermaid-svg-xKjzPIhSZ2g2u9NY div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-xKjzPIhSZ2g2u9NY .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-xKjzPIhSZ2g2u9NY rect.text{fill:none;stroke-width:0;}#mermaid-svg-xKjzPIhSZ2g2u9NY .icon-shape,#mermaid-svg-xKjzPIhSZ2g2u9NY .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xKjzPIhSZ2g2u9NY .icon-shape p,#mermaid-svg-xKjzPIhSZ2g2u9NY .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-xKjzPIhSZ2g2u9NY .icon-shape .label rect,#mermaid-svg-xKjzPIhSZ2g2u9NY .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xKjzPIhSZ2g2u9NY .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-xKjzPIhSZ2g2u9NY .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-xKjzPIhSZ2g2u9NY :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 固定请求集
压测 Harness
供应方直连
One-API/New-API 组
LiteLLM 组
云端中继组
Provider Routes
OTel + Prometheus
结果与失败样本
LiteLLM、One-API、New-API 应如何比较
项目能力和版本会持续变化,评测前应锁定镜像 Digest、配置提交哈希、许可证与依赖清单。LiteLLM 常被用于多供应方调用、代理与路由;One-API/New-API 类项目常用于渠道、令牌、配额与兼容接口管理。但不要仅凭项目定位判定胜负,应对当前版本执行同一套契约测试。
| 维度 | 自建开源项目 | 云端中继 | 验收问题 |
|---|---|---|---|
| 上线速度 | 需部署与配置 | 通常较快 | 首个受控路由多久可用 |
| 可定制性 | 源码与规则可控 | 依赖公开能力 | 能否实现租户策略与审计 |
| 数据边界 | 可部署在自有环境 | 需核验处理路径 | Prompt、日志、资产在哪里 |
| 高可用 | 团队自行建设 | 需验证而非假设 | 多区、RTO、RPO 是否有证据 |
| 升级成本 | 自行测试迁移 | 由服务方承担部分 | 协议变化如何通知与回滚 |
| 退出能力 | 数据与配置可掌控 | 依赖导出能力 | 能否在一天内切回直连 |
部署成本不能只算虚拟机。自建组至少需要网关、数据库、缓存、监控、备份、证书、漏洞修复、值班和升级回归。假设一台小规格服务器很便宜,却没有多副本、异地备份和告警,这不叫高可用。云端中继也不能因为免部署就自动获得高分,仍要验证协议覆盖、可观测字段、账单透明度、限额、数据政策和退出方案。
测试配置要以 Git 管理,敏感值由 Secret Manager 注入。每次评测生成 environment_manifest:客户端地域、出口 IP、镜像 Digest、Python/Node 版本、连接池参数、请求集哈希、路由别名解析结果和测试时间。没有这份清单,三个月后无法解释性能变化来自模型、网络还是配置。
高可用验证不能停留在"部署两个副本"。应依次关闭网关实例、Redis、数据库只读副本、单个出口和整个可用区,测量请求丢失、配置恢复和账本一致性。控制面不可用时,数据面应继续使用最后一份已验证配置,但禁止接受需要新密钥或新权限的变更;数据面恢复后再对缺失事件做补偿。
数据库恢复也要测 RPO/RTO。备份存在不等于可恢复,应定期还原到隔离环境,核对路由配置、租户预算、Attempt Ledger 和审计哈希。Redis 若保存限流计数,重启后令牌桶突然清零可能导致流量尖峰,因此需要冷启动限速。一次完整演练的结果应进入选型评分,而不是留在运维口头经验中。
七、极端限流与高频并发场景下的避坑指南
429 Rate Limit 不是单一故障。它可能表示瞬时 RPS/RPM 超限、TPM 超限、并发上限、账户余额不足、日预算耗尽或组织级配额限制。应用必须解析响应体、Retry-After、请求 ID 与可用的限额 Header,再决定排队、降速、切换还是失败。把所有 429 都立即重试,会形成重试风暴。

第一道防线是入口背压。为租户、模型和路由分别设置并发信号量与令牌桶;队列达到上限时快速拒绝,不能无限堆积。第二道防线是重试预算,例如整条调用链最多两次尝试、总等待不超过 12 秒。第三道防线是随机抖动,避免大量请求在同一 Retry-After 时刻同时唤醒。
python
def retry_delay(attempt: int, retry_after: float | None, rng) -> float:
if retry_after is not None:
base = retry_after
else:
base = min(0.5 * (2 ** attempt), 8.0)
return rng.uniform(0.5 * base, 1.5 * base)
def may_retry(status: int, idempotent: bool, attempts_left: int) -> bool:
if not idempotent or attempts_left <= 0:
return False
return status in {408, 429, 500, 502, 503, 504}
Token 滥扣问题通常来自"应用不知道请求到底有没有被接受"。每个尝试都要进入 Attempt Ledger,记录内部请求指纹、幂等键、上游请求 ID、开始和结束时间、首包状态、终态、输入输出 Token 与账单来源。超时后不能简单记为失败,应区分 not_sent、rejected、accepted_unknown、partial_stream 和 completed。只有这五类明确,才能对账与申诉。
| 反模式 | 后果 | 修复 |
|---|---|---|
| 429 立即无限重试 | 放大流量,拖垮所有渠道 | 有界预算、抖动、入口排队 |
| 每个实例独立限流 | 集群总流量击穿上游 | 共享配额或一致性分片 |
| 超时后并发切三路 | 重复生成、重复计费 | 幂等键、单次切换、Attempt Ledger |
| 把余额不足当短暂 429 | 永远重试 | 解析错误语义并熔断 |
| 缓存键不含模型版本 | 返回错误能力或旧答案 | 纳入路由、版本、租户和策略 |
熔断器也不是万能开关。应按路由与错误类型分桶,避免一个租户的错误 Prompt 让全局路由熔断。半开阶段只放少量探测流量,并要求连续成功后逐步恢复。对于 Codex 长任务,负载控制还应考虑预测输出 Token,而不只是请求数;一个 64K 上下文请求与短问答不能占用同样权重。
高并发还要解决队列公平。单一 FIFO 会让一个批量租户占满 Worker,使交互式请求在队尾等待。可以按租户和业务等级采用加权公平队列,并为长任务设置并发槽位;权重决定服务份额,但每个租户仍有硬上限。面板应展示"排队原因"和预计等待,而不是把网关排队误报成模型 TTFT。
成本保护需要在请求进入队列前完成。根据输入 Token、最大输出、模型单价和重试预算估算最坏成本,超过租户余额或任务预算立即拒绝。实际完成后再用供应方用量或本地 Tokenizer 对账。预算检查不能只在首个尝试执行,否则 Failover 可能让一次任务突破上限。
缓存只适合确定边界内的请求。包含工具、个人数据、实时信息或随机采样的请求不应默认缓存;可缓存内容的键必须包含模型与 Prompt 版本、参数、租户、权限和知识库版本。缓存命中也要记录来源时间和失效原因,避免为了降低 429 而返回越权或过期答案。
八、不同 IT 研发团队规模对 API 基础设施选型影响

选型首先取决于团队能承担哪类复杂度,而不是哪张功能表最长。初创团队的主要风险是过早建设平台;中型团队的主要风险是密钥、费用与路由规则散落在多个应用;企业团队的主要风险则是租户隔离、审计、区域合规和退出演练不足。
| 团队形态 | 合适起点 | 必要控制 | 何时升级 |
|---|---|---|---|
| 1--5 人原型团队 | 直连主供应方,封装薄适配层 | 环境变量密钥、预算、基础重试 | 出现第二供应方或稳定性 SLO |
| 5--30 人产品团队 | 托管中继或轻量自建网关 | 团队 Key、费用归因、路由别名、告警 | 多租户、工具调用、跨模态增长 |
| 30--100 人平台团队 | 开源网关加内部控制面 | 策略版本、审计、容量、灰度、回滚 | 多地域和强合规需求 |
| 大型企业 | 混合架构与多出口 | 零信任、数据边界、RTO/RPO、退出演练 | 持续演进而非一次升级 |
初创团队不必第一天部署 Redis、Kafka 和多集群,只需确保业务代码不直接散布供应方 SDK:定义内部请求对象、模型别名和错误分类,保留未来接入网关的边界。中型团队应把 Gateway 从"共用 Key"升级为"租户策略点",每个应用有预算、并发和日志范围。
企业级 Agent 架构还要处理工具权限。模型路由成功不意味着工具调用被授权。Gateway 负责模型与协议,Agent Runtime 负责会话、工具白名单、参数校验和补偿事务,两者不能混为一层。否则为了切模型而修改工具权限,既难审计又扩大攻击面。
组织职责也决定系统能否持续运行。平台团队负责网关 SLO、路由策略和升级;安全团队负责密钥、数据边界与审计;业务团队负责 Prompt、质量集和成本预算;财务负责账单对账。若没有明确的 RACI,429 事故会在供应商、平台和业务之间反复转派。选型报告应把"谁在凌晨处理故障"与功能、价格一起写清楚。
采购或引入开源项目之前,还应完成退出演练:导出模型别名、租户配置、用量账本和审计记录,把 10% 流量切回供应方直连,确认客户端无需大改。无法退出的低价方案会形成未来迁移成本,退出耗时应成为正式评测指标。
选自建还是云端,可用三年总拥有成本评估:
TCO=C_{compute}+C_{storage}+C_{egress}+C_{oncall}+C_{upgrade}+C_{incident}+C_{compliance}
对于缺少平台工程能力的团队,人员与事故成本常高于服务器;对于有严格数据边界和大量稳定流量的企业,自建的可控性可能更重要。正确答案不是"开源一定省钱"或"托管一定稳定",而是把隐性成本和退出成本放进同一张表。
九、典型 AIGC 业务场景适用性与替代方案建议
不同业务对路由目标的权重完全不同。Codex 类交互强调 TTFT、长上下文、SSE 连续性和工具调用;批量内容生成强调成本、吞吐与队列公平;图像、语音任务强调能力匹配、异步状态和资产完整性;面向客户的 Agent 还强调会话一致性与安全策略。
| 场景 | 优先指标 | 适配策略 | 不建议做法 |
|---|---|---|---|
| AI 代码助手/Codex | TTFT、工具调用、长文本成功率 | 会话黏性,首 Token 前有限 Failover | 流式中途静默换模型 |
| 在线客服 Agent | 成功率、P95、策略一致性 | 能力硬过滤,稳定路由,降级模板 | 只按最低价格选择 |
| 批量文本生成 | 单位成功成本、吞吐、公平性 | 队列、批处理、低价路由加截止时间 | 让大租户占满全部并发 |
| AI 绘画/漫剧 | Task 成功率、资产完整性、时长 | 异步编排、状态回调、内容哈希 | 用同步文本协议强行包装 |
| 语音交互 | 首音频延迟、采样率、断流率 | 地域就近、音频契约测试 | 把 HTTP 200 当音频成功 |
代码助手应优先做会话级路由固定。同一轮工具调用中切换模型,可能导致系统指令、工具 Schema 和上下文理解发生变化。仅当首个业务 Token 尚未返回、候选路由能力等价且仍有截止时间时,才允许 Failover。长任务还应把补全、代码审查、仓库问答拆成不同别名,分别设置上下文和成本预算。
批量生成则适合价格感知调度,但不能无限等待最便宜路由。每个任务携带截止时间与质量等级:截止时间宽松的任务进入低价队列;临近截止时间时提升优先级或切换高吞吐路由。所谓 Price-Performance Ratio 应以"成功交付的有效 Token"计算,而不是目录单价。
图像与视频任务建议采用 Saga:创建任务、轮询或接收回调、下载资产、验证哈希、写入业务库;任一步失败都有补偿或重放。若多模态中继不支持关键字段,宁可让该业务直连专用 API,也不要为了"统一入口"牺牲能力。统一的价值在治理,不在把所有 Schema 强行压成一种格式。
场景选型还必须加入质量门。为 Codex 准备真实仓库中的脱敏任务,执行编译、单测和静态检查;为批量文本建立事实、格式与重复率测试;为图片建立尺寸、主体一致性和人工盲评。只有通过质量门的输出 Token 才进入性价比计算。否则低价路由用更多废话完成同一任务,会在账面上便宜、在交付上昂贵。
替代方案也应预先设计。当统一网关不支持某个新模态时,可使用旁路专用适配器,并通过相同的身份、预算和审计控制接入,而不是等待网关强行统一。旁路必须有到期评审日期,防止临时通道永久绕过治理。成熟架构允许受控例外,而不是追求接口形式上的绝对统一。
十、综合性价比评估与最终选型结论
最终选型应把性能、可靠性、兼容、治理、运维、成本和退出能力同时量化。建议先设置硬门槛:关键模态和工具协议必须兼容;租户隔离、日志脱敏与数据位置必须满足要求;成功率与恢复时间达到 SLO。未通过硬门槛的方案,即使价格最低也不进入加权评分。
通过硬门槛后,可采用以下权重示例,但必须按业务调整:可靠性 25%、协议兼容 20%、可观测性 15%、单位成功成本 15%、运维复杂度 10%、性能 10%、退出能力 5%。每项分数都要绑定证据,例如故障注入报告、契约测试结果、账单样本或退出演练,而不是宣传材料。
| 方案 | 适合条件 | 核心优势 | 必须补齐的风险 |
|---|---|---|---|
| 供应方直连 | 单模型、团队小、低复杂度 | 链路清晰、额外损耗低 | 多供应方适配与统一治理 |
| LiteLLM 等自建网关 | 有平台能力、需要定制路由 | 策略可控、数据边界明确 | 高可用、升级、值班与安全 |
| One-API/New-API 类管理层 | 需要渠道、配额和统一入口 | 运营与令牌管理集中 | 当前版本契约和扩展能力需测试 |
| 云端中继 | 上线快、模型种类多 | 减少部分部署工作 | SLA、账单、数据与退出能力需验证 |
| 混合架构 | 企业级、多地域、强韧性 | 保留直连与多出口选择 | 语义一致性与双系统成本 |
本次故障回放不能证明"综合最佳"在所有场景最优,只证明动态错误降权和有限 Failover 在给定流量模型下显著减少了空跑。对于交互式 Codex,可能更愿意为低 TTFT 支付溢价;对于离线 AIGC 批处理,最低单位成功成本更重要;对于受监管企业,数据边界和审计能力甚至高于性能。
一套成熟的评测应形成闭环:冻结请求集与环境清单,先做协议契约测试,再做阶梯并发,随后注入 429、500、超时、断流和配额耗尽,最后执行账单核对与退出演练。每次模型、网关或路由策略升级,都用同一版本化基线回归。只有这样,API Gateway 才不是"把多个 Key 放到一起",而是可测量、可解释、可替换的 AIGC 基础设施。
加权总分还要做敏感性分析。把可靠性权重从 25% 调到 35%,或把成本权重从 15% 调到 30%,观察排序是否改变。如果微小权重调整就让第一名跌到第三名,说明方案没有稳健优势,应保留多供应方或混合出口。报告应公开权重、归一化方法和缺失值处理,避免用一张总分表掩盖主观偏好。
最终决策建议分成"现在、触发条件、退出路径"三列:现在选择满足当前 SLO 的最小方案;当月请求量、模型数、合规等级或事故频率越过阈值时升级;若供应方、价格或协议发生变化,按预演方案退出。这样的结论比永久性的冠军名单更符合 2026 年快速变化的模型生态。
最终建议可以压缩成一句话:小团队先保持适配边界,中型团队建立统一治理,大型团队建设混合控制面;无论选择开源项目还是商业中继,都用真实工作负载、故障注入和单位成功成本说话。性能排行榜会过期,可复现的评测方法才是长期资产。