同一套 Prompt 跑 5 家 API 平台,为什么结果能差这么多?
很多人接入大模型 API 的时候,第一反应是:模型一样,平台应该也差不多。实际开发里真不是这样。
简单说,哪怕你用的是同一个模型名、同一套 Prompt、同一段业务代码,换个平台之后,返回速度、超时概率、上下文表现、限流方式,都会变。更现实一点,线上一旦并发起来,问题就不是“回答得准不准”了,而是会不会突然 429、会不会半夜超时、会不会输出格式飘掉。
我最近把一套固定 Prompt,放到 5 家常见 API 平台上跑了一轮。说实话,原本我以为差距主要在价格,没想到真正拉开体验的,反而是那些文档里写得不算明显的限制。
这篇就直接讲实测结果,少讲虚的,重点看四件事:速度、稳定性、隐藏限制、翻车现场。
一、测试前先说清楚:这次怎么测的
为了尽量公平,我把变量压到最少。
测试对象
这次不点具体平台品牌全名,用 A、B、C、D、E 代称。原因很简单,平台策略变动挺快,今天测出来的结果,过几周可能就调整了。文章重点放在你该怎么测、该怎么看坑,这样更有参考价值。
固定条件
- 同一套业务 Prompt
- 同一份输入数据
- 同一个服务端脚本发请求
- 同一时间段做多轮测试
- 输出格式要求统一为 JSON
测试场景
我选了 4 组更贴近开发场景的请求:
- 短文本分类:判断工单类型,返回固定 JSON
- 中等长度总结:输入约 2500 字,输出 300 字摘要
- 代码生成:根据接口描述生成 Node.js 调用代码
- 长上下文提取:输入接近平台标称上限,提取关键字段
很关键。
因为很多平台在短请求上看起来都挺顺,到了长上下文、结构化输出、连续请求时,差距才会冒出来。
记录指标
我主要看下面这些数据:
- 首 token 返回时间
- 完整响应耗时
- 100 次请求成功率
- 429 / 5xx 出现频率
- JSON 格式一次成功率
- 长输入时是否触发截断
二、测试 Prompt:同一套,不做平台定制
为了避免“针对性调优”影响结果,我没有给某个平台单独加 system prompt 修补,也没做特殊参数适配。
核心 Prompt 思路是这样的:
你是一个 API 助手。 请根据输入内容完成任务,并严格输出 JSON,不要输出额外解释。 JSON Schema: { "task_type": "string", "summary": "string", "risk_level": "low|medium|high", "keywords": ["string"] } 如果字段无法确定,使用空字符串或空数组。请求参数也尽量统一:
{"temperature":0.2,"top_p":0.9,"max_tokens":800,"stream":false}这里先插一句,别迷信参数完全一致就一定公平。因为有的平台会偷偷改默认行为,比如内部补 system 指令、限制最大输出、对长输入做预裁剪。你以为自己传的是一套,平台未必真按一套执行。
三、5 家平台实测结果总览
我先放结论版,后面再展开。
| 平台 | 首 token 速度 | 完整耗时 | 稳定性 | JSON 遵循 | 长上下文表现 | 适合场景 |
|---|---|---|---|---|---|---|
| A | 很快 | 快 | 中上 | 中上 | 一般 | 低延迟交互 |
| B | 中等 | 中上 | 稳 | 高 | 中上 | 生产稳态 |
| C | 快慢波动大 | 波动大 | 一般 | 中 | 较弱 | 测试、低成本试跑 |
| D | 中等偏快 | 快 | 高 | 高 | 高 | 结构化输出、长文本 |
| E | 初看快 | 高峰期变慢 | 一般偏低 | 中下 | 一般 | 对价格敏感的轻量任务 |
如果只看一句话总结:
- A:快,但偶尔会抽风
- B:不抢眼,不过很稳
- C:便宜好上手,翻车率也更真实
- D:综合体验最好,成本通常也更高
- E:适合能容错的业务,不太适合严肃结构化场景
四、速度对比:别只盯总耗时,要看首 token
很多平台宣传速度,喜欢给你看“完整输出 5 秒结束”。但做产品时,用户体感更受首 token 时间影响。
比如聊天场景里,700ms 出字和 2.8s 才出字,感受完全不是一个级别。
1)短文本分类场景
100 次请求平均结果大概是这样:
| 平台 | 首 token 平均 | 完整耗时平均 |
|---|---|---|
| A | 0.82s | 1.94s |
| B | 1.36s | 2.21s |
| C | 0.95s | 3.67s |
| D | 1.12s | 2.08s |
| E | 0.88s | 2.96s |
A 和 E 在首包上很讨喜,前端看着会觉得“挺快”。但完整耗时拉开以后,就能看出差异了。C 和 E 都有一个共同问题:首段出来挺快,后半段偶尔拖很久。
这类情况做流式输出还稍微好点,做非流式接口时就挺烦,因为你会看到请求一直挂着。
2)中长文本总结场景
输入上去后,D 的表现最稳,B 紧随其后。A 在短请求里很有优势,但输入变长以后,速度优势没那么明显了。
没想到的是,C 在 2500 字以上输入时波动突然增大。同样的请求,前一次 4 秒多,下一次能到 11 秒。这个对定时任务、批处理会有影响,因为你很难估算整体跑完时间。
五、稳定性对比:真正上生产,拼的是这个
开发阶段最容易忽略稳定性。毕竟本地点几下接口,十有八九都能通。一上量,问题才来。
我做了 100 次连续请求和 20 并发压测,结果差异挺明显。
成功率统计
| 平台 | 100 次连续请求成功率 | 20 并发成功率 |
|---|---|---|
| A | 97% | 89% |
| B | 99% | 96% |
| C | 92% | 81% |
| D | 99% | 97% |
| E | 94% | 84% |
常见错误类型
- A:高峰时段偶发 502,重试一次大多恢复
- B:限流规则清楚,触发后返回信息也完整
- C:同样负载下更容易 429,而且恢复窗口不稳定
- D:错误率最低,超时也少
- E:有时业务层返回成功,但内容不完整,排查起来最费劲
这里我个人感受很深。最怕的不是报错,而是假成功。
接口状态码 200,结果里字段少了一半,或者 JSON 被截断,你监控还不一定马上发现。E 在这块给我挖过坑,后面我专门加了响应体校验,不然线上任务会静悄悄地产生脏数据。
六、隐藏限制:文档不一定写得很明白
这部分才是我觉得最值得聊的。
很多 API 平台表面参数兼容 OpenAI 风格,接起来也确实不难。可一旦你开始认真用,就会碰到一些“不明说但确实存在”的限制。
1)标称上下文和真实可用上下文不是一回事
有的平台写支持 128k,上线后你真塞接近上限的内容,返回会出现两种情况:
- 直接报上下文超限
- 不报错,但悄悄截断前文
后者更坑。
我在长上下文提取测试里,某平台明面上收了完整输入,结果输出明显漏掉了开头关键字段。刚开始我还以为是模型注意力问题,后面把输入分片打日志,才发现是平台侧做了裁剪。
2)速率限制分两层,很多人只看一层
有的平台限制是 RPM,有的是 TPM,还有的平台两者都卡。你本地测几个请求感觉没问题,到了批量生成阶段就会突然被打回。
简单说:
- 短请求多,容易撞 RPM
- 长请求大,容易撞 TPM
如果你只按“每分钟请求数”做控制,还是会 429。
3)JSON 模式口头支持,实测不一定稳
有的平台文档里会写支持 JSON 输出,甚至也兼容 response_format 这类参数。但实测下来,真正稳定遵守 schema 的,还是少数。
尤其在输入稍复杂、输出字段稍多的时候,有些平台会出现:
- 多一段解释文字
- 枚举值写错
- 数组字段变成字符串
- 少右大括号
这种问题拿来写 demo 没啥,进业务就会很痛苦。
七、翻车现场:这几个坑我是真踩到了
说点更实在的。
翻车 1:同一模型名,不同平台返回风格不一样
我一开始图省事,直接把平台切换做成配置项,想着只换 base URL 和 key 就行。结果同一个模型名,在 A 和 C 上表现差别挺大。
A 返回比较克制,字段基本按要求给;C 更容易“加戏”,总想补一段解释。你如果依赖严格 JSON,这种差异就会直接变成解析错误。
翻车 2:超时不是最难受,卡住才是
有个平台在网络层不一定直接超时,而是连接挂着很久,最后才失败。默认 HTTP 客户端如果没把 read timeout、connect timeout、total timeout 分开设,排查时会很乱。
我后面统一改成了这种写法:
importaxiosfrom'axios';constclient=axios.create({baseURL:process.env.API_BASE_URL,timeout:20000,headers:{Authorization:`Bearer${process.env.API_KEY}`,'Content-Type':'application/json'}});asyncfunctioncallModel(payload){try{constres=awaitclient.post('/v1/chat/completions',payload);returnres.data;}catch(err){return{error:true,message:err.message,status:err.response?.status};}}这只是最基础的。真上生产,最好再补重试、熔断、响应校验。
翻车 3:便宜平台省下的钱,最后花在补偿逻辑上
这个很现实。
有个平台单价看着确实低,我最开始算账觉得挺划算。结果因为 JSON 成功率不稳定,后面加了二次修复请求、失败重试、格式纠正,整体 token 消耗反而上去了。
89 块预算内跑 demo 没问题。真做日常任务,每天几千次调用,补偿成本一叠上来,账就不对了。
翻车 4:状态码 200,不代表结果真的能用
我现在会强制做 schema 校验,不再只看接口有没有报错。
比如这样:
functionvalidateResult(data){if(!data||typeofdata!=='object')returnfalse;if(typeofdata.task_type!=='string')returnfalse;if(typeofdata.summary!=='string')returnfalse;if(!['low','medium','high',''].includes(data.risk_level))returnfalse;if(!Array.isArray(data.keywords))returnfalse;returntrue;}短短几行,能挡掉很多脏结果。
八、如果你是开发者,选平台时我会这样看
不同业务,看重的点真不一样。别只看单价,也别只看排行榜。
适合优先选“快”的场景
- 聊天助手
- 前端实时交互
- 低延迟体验比偶发重试更重要的产品
这类场景可以优先考虑 A 这类首包快的平台,但前提是你能接受偶发抖动,并且前后端都有降级策略。
适合优先选“稳”的场景
- 工单处理
- 内容审核
- 批量数据抽取
- 自动化报告生成
这种更适合 B、D 这类平台。速度不是最快,实测下来整体更省心。毕竟线上任务最怕半夜悄悄失败。
适合先用低成本平台试跑的场景
- 验证想法
- 内部工具
- 低频、可人工兜底的任务
C、E 这类也不是不能用,问题在于你要把预期放对。它们更适合快速验证,而不是一上来就当核心生产入口。
这里我承认一点,小团队预算紧的时候,低价平台确实有吸引力。我自己也用过。只是你得把重试、校验、告警这些成本一起算进去,不然很容易只看到账面便宜。
九、我的接入建议:少踩坑的最小方案
如果你最近正准备接多家 API 平台,我建议起码做好这几件事。
1)统一适配层,不要业务里写死平台差异
asyncfunctionrequestLLM({platform,model,messages,temperature=0.2}){constconfig=getPlatformConfig(platform);constpayload={model,messages,temperature,max_tokens:800};constres=awaitfetch(`${config.baseURL}/v1/chat/completions`,{method:'POST',headers:{'Content-Type':'application/json',Authorization:`Bearer${config.apiKey}`},body:JSON.stringify(payload)});constdata=awaitres.json();returnnormalizeResponse(platform,data);}后面你想切平台、做容灾、做 AB test,会轻松很多。
2)统一日志字段
我现在固定会记录这些:
- platform
- model
- prompt_tokens
- completion_tokens
- latency_ms
- status_code
- retry_count
- parse_success
别嫌麻烦。后面真出问题,能不能快速定位,基本就靠这些。
3)结构化输出一定做二次校验
不要把模型输出直接当真。哪怕平台号称支持严格 JSON,也最好自己再验一遍。
4)重试要分错误类型
429 适合退避重试,5xx 可以有限次重试,JSON 解析失败则更适合降温重问或走修复逻辑。别一把梭全重试,不然只会把限流撞得更狠。
十、最后给个结论:5 家平台到底怎么选
如果你问我这轮实测后的结论,我会这么回答:
- 想要低延迟体验,A 可以试,但要有容错
- 想要更平稳的生产表现,B、D 更合适
- 想控制前期成本,C、E 值得一试,不过别省掉校验和重试
其实 API 平台的差距,从来不只在模型能力本身。真正拉开距离的,是你把它放进真实业务后,它在高峰时还稳不稳、在长输入时会不会偷偷缩水、在格式要求严格时会不会翻车。
一句话收尾:接 API 这件事,便宜和好接只是开始,长期省心才是真的成本答案。