返回 AI 资讯
技术社区CNode

用 Node 调大模型 API 时,「返回 200」不等于成功:我们怎么测 AI 中转站的流式稳定性

利益相关:文末的 Folkbench 是我们自己做的。 很多人在 Node 服务里接大模型都会走中转站。我们自己踩过一个很典型的坑:健康检查只看 res.status === 200 ,结果有的中转站在上游 429/401 的时候也返回 200,SSE 流到一半直接塞一个 data: [DONE] ,甚至把 {"error": ...} 当成模型的回答流出来。监控一片绿,线上用户却在抱怨「话说到一半就断了」。 后来我们判断「成功」的标准改成了这样: // 一个最小的判断:流式请求必须同时满足这几条,才算成功 le…

内容摘要

利益相关:文末的 Folkbench 是我们自己做的。 很多人在 Node 服务里接大模型都会走中转站。我们自己踩过一个很典型的坑:健康检查只看 res.status === 200 ,结果有的中转站在上游 429/401 的时候也返回 200,SSE 流到一半直接塞一个 data: [DONE] ,甚至把 {"error": ...} 当成模型的回答流出来。监控一片绿,线上用户却在抱怨「话说到一半就断了」。 后来我们判断「成功」的标准改成了这样: // 一个最小的判断:流式请求必须同时满足这几条,才算成功 let gotFirstChunk = false, gotDone = false, parseErrors = 0; const t0 = performance.now(); let ttft = null; for await (const line of readLines(res.body)) { // 按 SSE 的事件边界解析,不要按网络分包猜 if (!line.startsWith('data:')) continue; const payload = line.slice(5).trim(); if (payload === '[DONE]') { gotDone = true; break; } try { const evt = JSON.parse(payload); if (evt.error) throw new Error('error-in-stream'); // 混在流里的报错,不能当成输出 if (!gotFirstChunk) { gotFirstChunk = true; ttft = performance.now() - t0; } } catch { parseErrors++; } } const ok = res.status === 200 && gotFirstChunk && gotDone && parseErrors === 0; 另外几条经验: 首字耗时(TTFT)和总耗时分开记。 我们遇到过总耗时 4 秒左右、首字却要 12 秒的情况,只看总耗时根本发现不了。 看 P95/P99,不看平均。 高峰期的问题都在尾部。 至少连续测 3~7 天 ,重点看晚上 21:00~01:00。 重试要设预算。 只对能安全重复的请求重试;鉴权失败、参数错误不要重试。 完整的指标和失败分类写在这里:https://folkbench.com/blog/ai-api-relay-stability-guide?utm_source=luntan&utm_campaign=cnode 我们把这些测试结果公开在 Folkbench 上,按模型比较各家中转站。还是 Beta,欢迎拍砖。

资讯来源

CNode

原文链接

打开原文