AI API线上不稳定?从限流、超时到流式输出的排查保命指南 先说一个我经常在群里被问到的现象本地 Postman 调 AI API 一把过代码单测也全绿结果一部署到线上就开始各种超时、429、断流偶尔还冒出几个Internal Server Error。更难受的是这种不稳定不是一直坏而是“时好时坏”查半天也不知道该甩锅给网络、代码还是模型服务商。做 AI 应用接入这么久我越来越确定一件事本地调通和线上稳定运行中间隔着的不是代码量而是一整条你不可控的链路。很多人以为“线上不稳定”是 API 服务商的问题但根据我的实战经验真正的原因往往是环境差异、限流策略、超时配置、流式连接这几类问题而且大部分在本地根本复现不出来。这篇文章就把我在实际项目中踩过的坑、总结的排查方法和保命配置一次讲清楚。1. 本地调通和线上稳定运行从来就是两回事1.1 本地环境给你的三种“假安全感”我见过太多团队本地联调阶段 Run 一下全通过就开开心心发上线单了。结果灰度一开监控面板上飘红一片。为什么本地测试通过给了这么大“假安全感”因为本地环境和线上生产环境的差异比大多数人想象的大得多。第一本地网络是“独占式”的。你本地调试时DNS 解析通常走本地运营商或者公司内网 DNS延迟低、缓存命中率也高。线上服务器如果在某个云厂商的机房DNS 解析链路完全不一样有的机房公共 DNS 解析海外 API 域名要几百毫秒甚至偶尔解析失败。第二本地没有并发。你自己拿 Postman 调一个请求无论成功还是失败都不涉及并发竞争。但线上哪怕只有几十个用户同时触发对话每个用户可能还会产生多轮请求API 服务商那边的并发配额、频率限制一下子就暴露了。第三本地没有网关。本地直连外网中间没有 Nginx、负载均衡、防火墙、CDN 这些“插手的角色”而线上每一个中间节点都可能改变请求的行为——缓冲、超时、断开、改写请求头都会导致“本地没问题、线上出问题”。我自己踩过最典型的一个坑本地调某大模型平台的接口非常稳定代码一上线到测试服务器就频繁Connection timed out。查了半天最后发现那台服务器的出口 IP 段被 API 服务商的风控系统标记了导致请求时不时被拦截。本地能通线上不能通跟代码一点关系都没有。1.2 遇到线上不稳定先别怀疑代码先看链路做线上问题排查最忌讳的就是一上来就翻代码、加日志东改西改。我现在的习惯是先确认请求链路里每一段的耗时分布再决定要不要动代码。你可以在线上服务器上用 curl 模拟一次 AI API 调用把时间拆开看curl -w dns:%{time_namelookup}s connect:%{time_connect}s tls:%{time_appconnect}s ttfb:%{time_starttransfer}s total:%{time_total}s\n \ -o /dev/null -s https://api.xxx.com/v1/models输出结果能很直观地告诉你问题出在哪一层如果dns时间占了 80%说明 DNS 解析有问题如果connect时间异常可能是防火墙拦截或者网络不通如果ttfb首字节时间很长说明 API 服务商响应慢如果total很长但ttfb正常可能是服务端持续输出时连接被掐断。我在排查“线上偶尔超时”的问题时经常用这个命令比直接翻代码高效得多。另外线上服务器和 API 服务商之间的地理位置也需要注意。有些服务商在国内有多地域入口但如果你的服务器在另一个区域跨地域调用会增加几十甚至上百毫秒的延迟。这类问题可以通过选择同地域的服务商入口或者使用服务商提供的专有接入域名来缓解。2. 限流是线上不稳定最大的“隐身杀手”2.1 看懂 RPM、TPM、并发数三个最容易踩的限流维度几乎每一家大模型 API 服务商都有明确的限流维度但很多想接入的开发者根本不看文档只关心“API Key 能不能调通”。等流量一上来就发现线上开始随机报错状态码是同一个429 Too Many Requests。不同的平台叫法可能略有差异但核心维度就三类RPM每分钟请求数、TPM每分钟 Token 数、并发数同时进行的请求数。RPM 好理解就是每分钟最多发起多少次请求TPM 是指你一分钟内消耗的 Token 总量包括输入和输出并发数是同一时刻允许同时在途的请求数量。这三个不是独立的比如你单次请求的输入很长、输出也长可能一次就吃掉 2000 Token那么 TPM 配额可能几分钟就爆了哪怕 RPM 还没到上限也会被限流。不同平台对免费档和付费档的限流策略差异很大。我粗略整理了一下常见平台的情况平台常见限流维度免费档典型宽松度备注DeepSeekRPM、TPM免费额度期内较宽松并发也有限制通义千问RPM、TPM有基础配额不同模型配额不同智谱GLM并发、Token适中部分模型需实名认证KimiRPM、TPM免费期限制较紧上下文长任务容易吃 TPM讯飞星火并发、QPS免费试用额度有限需要控制并发豆包QPS、Token有免费额度企业版需单独申请OpenRouterRPM、Token按模型区分聚合平台慎用免费模型这里给一个最容易踩的坑你在本地测试时一个 Key 只有你一个人用感觉不到限流。但线上如果所有用户共享一个 Key哪怕并发只有十几个人RPM 也很容易被打满。更麻烦的是很多平台的限流不是简单地返回 429 就完了而是一段时间内持续拒绝你的请求。你要做的是在接入之前就搞清楚这三个维度的数值并且设计好客户端的请求调度。2.2 应对 429 的正确姿势退避重试和请求排队很多线上不稳定其实是客户端自己的重试策略太粗暴导致的。收到 429 或者 5xx立刻重试一遍、再失败再重试这其实是“重试风暴”的起点。服务端本来就限流了你还在反复打雪上加霜。我建议给所有 AI API 调用都加上指数退避重试并且加上随机抖动避免所有请求在同一时刻发起重试。核心逻辑不复杂import random import time def call_with_retry(fn, max_retries5): for attempt in range(max_retries): try: return fn() except RateLimitError: wait_time 2 ** attempt random.uniform(0, 1) time.sleep(wait_time) raise RuntimeError(最终重试失败)如果你是并发场景还要在客户端做信号量控制把同时在途的请求数压到平台允许的并发数以内import asyncio semaphore asyncio.Semaphore(5) # 最多 5 个并发 async def safe_call(api_func): async with semaphore: return await api_func()另外如果是大量低优先级的离线任务比如批量生成摘要强烈建议做成队列而不是直接并发打 API。我自己做过一个批量任务系统核心原则是能排队就别并发能重试就别死磕能错过高峰期就尽量避开。线上稳定性往往是“削峰填谷”的结果而不是单次请求的优劣。还有一个细节很多平台在 429 响应里会带Retry-After头或者x-ratelimit-*系列头告诉你什么时候可以重试、还剩多少配额。你的代码应该主动读取这些字段而不是自己瞎猜重试间隔。3. 超时与流式输出线上“假卡死”和“断流”的根源3.1 超时不是“随便设一个”要分四层设置AI API 和普通 HTTP API 最大的不同在于生成式模型的响应时间不是稳定可控的。你问一个简单问题可能 2 秒就返回了但一个复杂推理任务可能要 60 秒甚至更久。如果超时配置没做好线上就会出现“请求明明在处理但客户端已经放弃了”的尴尬局面。我见过太多人只设了一个整体超时比如 30 秒然后本地测试短问题没问题一到线上遇到长任务就报超时。这里需要把超时分四层设置超时类型推荐值说明连接超时connect5 秒只覆盖 TCP 连接建立时间写入超时write10 秒请求体发送超时读取超时/首包超时read/TTFB60 秒起从发完请求到收到第一个字节整体请求超时非线性 120 秒流式按需非线性任务看模型速度流式任务别设太短如果你是流式输出SSE整体超时的设置要非常小心。因为流式场景下客户端是持续收到data的理论上连接一直有数据在流动。但如果你设置了整体超时 60 秒哪怕服务端已经在正常输出到了 60 秒整个连接也会被客户端掐断前端表现就是“生成到一半突然没了”。流式场景的正确做法是不设整体请求超时而是设置空闲超时idle timeout——也就是两次数据包之间的最大间隔。只要服务端还在持续输出连接就一直有效。如果间隔超过某个阈值比如 120 秒没有新数据再判定为断流。3.2 SSE 流式输出断流线上最隐蔽的一类问题现在接 AI API 做对话类应用几乎都绕不开 SSEServer-Sent Events流式输出。本地调试时你看到数据一段段打印出来一切正常。到了线上前端却经常出现“收到几个字就卡住不动了”的情况而过一会儿又全部展示出来了。这类问题十有八九不是模型的问题而是中间链路把 SSE 流“缓冲”住了。最常见的就是 Nginx 默认开启了proxy_buffering导致后端已经输出的内容被 Nginx 攒到缓冲区直到攒满或者请求结束才一次性转发给前端。前端看起来就是“卡住”了。解决办法是在 Nginx 层面对流式接口关掉缓冲location /api/chat/stream { proxy_pass http://backend; proxy_buffering off; proxy_cache off; proxy_read_timeout 300s; proxy_send_timeout 300s; proxy_set_header Connection ; add_header X-Accel-Buffering no; }除了 Nginx 的缓冲负载均衡层的空闲超时也是一个常见“凶手”。很多云负载均衡默认的空闲超时只有几十秒如果你的 SSE 连接在两次输出之间的间隔超过了这个值LB 就会主动断开连接前端表现为“生成到一半报网络错误”。我建议把这类接口在网关层的 idle timeout 调到 300 秒以上。还有一个前端容易忽略的点SSE 协议里服务端可能会发送注释行比如: keep-alive来维持连接某些实现还会发心跳事件。前端拿到这些数据时不能当普通文本解析否则会出现解析错误。而服务端这边用的若是 FastAPI 这类 ASGI 框架要注意客户端断开时能否及时感知并停止生成不然会产生资源泄漏导致服务越来越慢。这里需要给流式接口增加request.is_disconnected()检查在客户端断开时主动终止生成逻辑。4. 从调通到扛住线上稳定性排查工作流4.1 我的“金字塔排查法”自下而上先外围后内部线上 AI API 不稳定很多人第一反应是改代码、加日志、反复部署搞得自己焦头烂额。我自己采用的是一套“金字塔排查法”从上到下逐层确认。第一层是网络链路层先用 curl 拆时间确认 DNS、TCP、TLS、TTFB 是否正常再看服务商控制台的可用性监控。第二层是网关与负载均衡层看 Nginx 访问日志、LB 的连接断开记录、是否有超时配置生效。第三层是API 服务商状态层确认是不是服务商本身在抖动很多控制台会有状态页或公告。最后一层才是应用代码层看日志里是否有异常堆栈、超时配置、重试逻辑是否合理。为什么要按这个顺序因为线上不稳定最大的特点是“偶发性”如果一开始就去改代码你很难确认改对没有。而且很多问题本身就是外围环境引起的改代码根本没有意义。我自己遇到过一个案例前端一直报 401排查到最后一层才发现是服务器时间和 API 服务商的签发时间偏差太大导致 JWT 校验失败。这种问题你翻一天代码都找不到看链路一分钟就发现了。4.2 线上保命三件套网关、熔断、全链路观测经历过几次线上事故后我给所有接入 AI API 的服务都定了三个“保命配置”缺一不可。第一个保命配置是统一 API 网关入口。所有对外的 AI API 调用不直接打到服务商而是先经过你自己的网关层。网关统一处理鉴权、限流、重试、熔断避免每个服务各自为战。你要是之前没有网关也可以先用简单的反向代理凑合但必须保证策略是集中的。否则 A 服务重试 3 次、B 服务重试 5 次打出去的重试请求互相叠加很容易触发服务商限流。第二个保命配置是熔断器。把 AI API 当成一个可能出故障的外部依赖而不是一个可靠的内部函数。熔断器的核心是当错误率或超时率达到阈值时主动切断后续请求快速失败让系统有机会恢复。推荐的关键参数可以参考错误率连续 30 秒超过 50%熔断 30 秒或者慢调用比例超过 30% 时触发熔断。同时配合降级方案比如把高频问题先用缓存答案兜底而不是让用户面对“加载失败”。第三个保命配置是全链路日志和 Request ID 贯穿。从客户端发起请求到网关、到后端服务、再到 AI API 服务商整个链路用同一个 Request ID 串联起来。一旦线上出问题你能通过这个 ID 快速定位请求到底卡在哪一步。没有这个基础线上排查就像大海捞针。5. 线上 AI API 不稳定的常见问题与排查速查表5.1 常见故障现象、原因与排查动作速查表以下是我在做 AI 应用维护时总结的线上故障速查表。如果你遇到线上 AI API 不稳定先对照症状找方向现象常见原因排查动作本地通线上完全不通出口 IP 被限、DNS 解析失败、防火墙拦截curl 分开测 DNS/TCP/TLS更换出口 IP 测试时好时坏间歇性超时网络抖动、限流前兆、连接池耗尽看耗时分布查看是否接近 RPM/TPM 上限高峰时段大量 429并发超限、TPM 超限客户端加信号量控并发退避重试错峰调度生成到一半断流Nginx buffering、LB idle 超时、SSE 解析问题关缓冲调大空闲超时检查心跳注释行突然出现 401/403Token 过期、服务器时钟偏移、Key 被轮换检查 Server 时间确认密钥管理策略请求耗时从 1 秒变成 5 秒DNS 慢、连接复用失效、TLS 握手频繁开启 HTTP 连接池和 keep-alive使用连接复用偶发 500/502服务商内部错误、网关超时看服务商状态页指数退避重试5.2 一句话避坑心得最后整理几条我个人的“血泪教训”每条背后都对应过一次线上事故送给正在接入 AI API 的读者第一不要在生产环境所有人共用一个 API Key至少按服务拆分 Key方便限流配额分配和问题溯源。第二不要只设一个整体超时流式和非流式要区别对待。第三上线前一定要做压测至少模拟 1.5 倍预期峰值流量跑 30 分钟很多限流和连接池问题在压测阶段就会暴露。第四线上排查时每次只改一个变量改完看监控曲线确认有效再改下一个。第五永远保留现场日志错误响应体别只记状态码服务商返回的error信息里往往藏着真正的失败原因。这些经验都不是从哪个官方文档里看来的而是被线上告警折腾过无数个夜晚之后总结出来的。AI API 调用这件事本地跑通只算完成了 20%剩下 80% 的功夫都在“线上稳定”这四个字里。希望这份梳理能帮你少踩几个坑。