一次用户请求通常包含八个阶段:

1.业务请求进入:校验用户身份、租户、套餐、功能权限、请求大小。

2.上下文组装:System Prompt用户输入、历史消息、RAG证据、工具schema、输出格式约束。

3.Token预算预估:估算输入Token,预算输出Token,决定是否裁剪历史、压缩上下文或换小模型。

4.模型网关路由:选择模型、供应商、区域、超时参数、重试策略、限流桶。

5.供应商API调用:同步返回或流式返回,可能经过SSE、WebSocket或普通HTTP响应体。

6.响应解析:处理delta、finish reason、tool call、usage、拒答、结构化JSON、异常中断。

7.状态回写:保存完整回答、增量片段、Token用量、调用成本、失败原因和业务状态。

8.观测与告警:记录traceId、providerRequestId、TTFT、总耗时、重试次数、429次数、解析失败率。

名词解释:

delta:流式返回中的“增量内容”。模型不是一次性返回完整文本,而是一小段一小段吐出,每段就是delta。

finish reason:模型停止生成的原因。常见值:stop正常结束、length达到长度限制、tool_calls需要调用工具、content_filter被安全策略截断。

tool call:模型请求调用外部工具/函数。

usage:本次调用的用量统计,包括输入token、输出token、总token,用于计费和监控。

traceld:链路追踪ID,用来把一次请求在多个服务之间的日志串起来,方便排查问题。

providerRequestId:模型供应商侧生成的请求ID。

429次数:收到HTTP [429 Too Many Requests]的次数,表示请求过频、超过限流或额度限制。


同步返回与流式返回的对比

对比项 同步返回 流式返回
首字延迟 高,需要等完整结果 低,收到第一个片段即可展示
端到端总耗时 取决于完整生成时间 通常仍取决于完整生成时间
前端体验 像提交表单后等待结果 像聊天软件逐字出现
后端实现 简单,拿到完整字符串再处理 复杂,需要处理增量事件、取消、断流
结构化解析 简单,完整JSON一次解析 需要缓存完整内容,或使用增量解析器
适合场景 短文本、后台任务、严格事务 聊天、写作、报告生成、长回答
不适合场景 用户强交互的长回答 强事务、必须一次性校验完整结果的链路

流式输出常见的承载方式

方式 核心特点 适合场景 边界
SSE(Server-Sent Events,服务器发送事件) 浏览器原生EventSource,服务端到客户端单向推送,格式是text/event-stream(SSE的标准MIME类型) 文本聊天、模型增量输出(Streaming)、状态通知 单向通信;复杂双向控制需要额外HTTP请求
WebSocket(一种建立在TCP之上的长连接协议) 双向长连接,客户端和服务端都能随时发消息 实时语音、多人协作、需要频繁取消或插话 连接管理更复杂,网关、鉴权、心跳(ping、pong)都要自己管好
HTTP chunked(HTTP分块传输编码) HTTP/1.1的分块传输机制,响应体分块发送 后端到后端流式代理、低层传输 它不是传输机制,不是应用事件协议;HTTP/2之后有自己的流式机制

HTTPChunked属于底层传输机制;SSE属于应用层协议,通常基于HTTP+Chunked实现;WebSocket属于独立协议,建立之后不再是普通HTTP。

SSE的优势是简单,SSE是服务端到客户端的单向数据流。WebSocket适合更实时、更复杂的交互。HTTPchunked更底层,很多服务端框架在没有Content-Length的情况下会用分块响应,它能实现“边写边发”,但不会定义事件类型、重连语义、消息边界,业务层仍然要自己设计协议。

补充:

delta字段的来源是:模型在流式生成时,每次只返回“新增的那一点内容”。

TCP是一种网络传输协议,全程Transmission Control Protocol,即传输控制协议。它负责在两台机器之间建立一条可靠连接:客户端 ⇄ 服务器。TCP核心特点:面向连接(三次握手)、可靠传输、有序传输、流式传输。

Content-Length:提前告诉客户端“总共要发多少字节”,适合一次性响应。

Transfer-Encoding: chunked:提前不知道总长度,边生成边发送。

SSE:建立在 HTTP 之上的事件流格式,通常借助 Chunked 实现实时推送。

ChatGPT 的流式输出本质上就是:Chunked + SSE + delta。


SSE 协议的事件边界

SSE不是按TCP包、HTTP Chunk来划分消息的,而是按空行(\n\n)来划分一个完整事件。因为 TCP/HTTP 流只是连续字节,事件边界用来告诉客户端“一条消息到这里结束,下一条消息从这里开始”。SSE 的事件边界是空行 \n\n,正文换行必须转义成 \\n 或拆成多行 data:,不能直接裸换行。


流式异常的四类场景

1.用户取消

用户关闭页面、点击停止生成、切换会话,都应该触发取消。后端也要同时取消:到供应商API的请求/正在解析的响应流/后续TTS、工具调用、落库任务/还没提交的增量缓存。

2.超时

·连接超时:连不上供应商

·TTFT超时:连接上了,但迟迟没有第一个事件

·总时长超时:一直有输出,但超过业务可接收时间

TTFT超时通常指向模型排队、上下文过长或供应商抖动;总时长超时可能只是用户让模型写太长。

3.断流

断流就是本应持续传输的数据流,在完成之前意外中断了。常见原因:网络问题、网关超时、服务崩溃、429限流、客户端主动取消。发现断流后,先确认不是正常结束,再记录 traceId 等上下文,尝试自动重试或续传,同时统计和排查根因。

4.重连

重连后是否能从断点续传,取决于你的服务端是否保存了事件序号、增量片段和供应商调用状态。多数情况下,供应商侧流已经断掉,无法真正从 Token 级别续上。

更稳妥的做法:服务端为每个流式响应生成messageId和递增sequence;已发送片段写入短期缓存;前端重连时先补发已缓存片段;如果供应商流已结束或已失效,提示用户重新生成,而不是假装无缝续写。

大模型API的重试有两个特殊点:

1.请求贵:失败请求也可能消耗配额,甚至已经消耗了部分token

2.输出非确定:即使prompt一样,第二次返回也可能和第一次不同

错误类型对照表

类型 示例 是否建议重试 处理方式
网络瞬断 连接重置、DNS抖动、读超时 可以 指数退避+抖动,限制最大次数
供应商5xx 500、502、503、504 可以 短暂重试,超过阈值切换模型或降级
供应商过载 Anthropic 529、类似 overloaded 错误 可以 慢重试,必要时熔断该供应商
429限流 RPM、TPM、RPD、并发限制超出 谨慎 优先看Retry-After和限流头,排队或降级
流式中断 未收到正常结束事件 视场景 用户可见任务不自动重试,后台任务可幂等重试
400参数错误 Schema不合法、字段缺失、上下文超限 不建议 修请求,不要重试同一payload
401/403鉴权错误 API Key无效、权限不足 不建议 告警并停用对应key
安全拒答 内容策略拒绝 不建议 进入业务拒答流程
解析失败 JSON不完整、字段类型错误 可有限重试 带失败原因二次修复,最多1-2次

注:

DNS(Domain Name System,域名解析系统)负责把域名转换成IP地址。

DNS抖动就是解析偶尔失败/解析变慢/返回不同节点。

连接重置:TCP连接已经建立,但被一方强制断开。可能原因:服务端重启、负载均衡切换、网络设备中断。

读超时:请求已经发出去,但在规定时间内没有收到响应。

指数退避:重试时等待时间逐渐增加。

HTTP 5xx 表示:服务端出错,不是你的请求有问题。

500 Internal Server Error:服务器内部异常。

502 Bad Gateway:网关错误。

503 Service Unavailable:服务不可用。

504 Gateway Timeout:网关超时。

降级:主模型不可用时切换备用方案。

供应商过载:服务还能工作,但负载太高。

熔断:发现某个供应商连续失败,暂时停止请求它。

429限流:请求太频繁,被限制。

RPM(Requests Per Minute):每分钟请求数。

TPM(Tokens Per Minute):每分钟Token数。

RPD(Requests Per Day):每天请求数限制。

并发限制:同时执行的请求数限制。

400参数错误:请求格式有问题。

Payload:请求体(Request Body)。

抖动(Jitter)的核心是不要让所有请求在同一时间点一起重试。

生产里加两条硬约束:最大重试次数、总体截止时间

幂等 Key 是客户端给一次“业务操作”生成的唯一 ID。去重机制就是服务端保存“已经处理过的 Key”。


常见限流策略对比

策略 适合场景 优点 缺点
固定窗口 简单后台任务、管理接口 实现简单,容易统计 窗口边界容易突刺
滑动窗口 用户级请求限制 边界更平滑 实现和存储成本更高
令牌桶 模型调用、token预算 支持一定突发,工程上常用 参数需要调优
漏桶 严格平滑出流量 输出稳定,适合保护供应商 突发体验差
并发信号量 流式生成、长任务 能限制同时占用连接 不控制单个请求token成本
优先级队列 多租户、多套餐 能保护高优先级请求 需要处理饥饿和超时

用户级:滑动窗口+日token上限

租户级:令牌桶+月度预算

模型级:令牌桶+并发信号量

供应商级:全局令牌桶+熔断器

流式请求:并发信号量+总时长限制


HTTP429表示请求过多。后端处理429时,建议:

1.读取Retry-After或供应商rate limit header:有明确恢复时间就尊重它

2.标记限流维度:是请求数打满,还是token打满,还是日配额耗尽

3.短请求可排队:例如后台摘要任务可以进延迟队列。

4.用户交互请求少重试:用户等不起时,直接提示稍后再试或切换轻量模型。

5.供应商连续 429 时熔断:不要让所有请求继续撞墙。


方式 约束强度 工程价值 风险
普通自然语言 几乎没有 适合展示型回答 不适合程序解析
Prompt 要求 JSON 简单、跨模型 容易混入解释文本或缺字段
JSON Mode 通常能保证语法是 JSON 不一定符合业务字段 Schema
JSON Schema 明确字段、类型、必填、枚举 不同供应商支持子集不同
Structured Outputs 更强 供应商在解码或 SDK 层增强约束 受模型、SDK、Schema 子集限制
Function Calling / Tool Use 面向动作 适合让模型选择工具和参数 不是最终自然语言答案的万能替代

结构化输出失败后兜底:

1.本地校验:用JSON Schema、Jackson、BeanValidation校验字段和类型

2.轻量修复:只让模型修复格式,不重新生成业务内容

3.降级Scheam:复杂对象拆成多个小对象,或先分类再抽取字段

4.人工或规则兜底:高价值订单、金融、医疗、法务场景不要完全依赖自动修复


面试高频问题

1.模型API调用的完整链路是什么

一次调用从业务请求进入开始,先做用户、租户、权限和参数校验;然后组装System Prompt、用户输入、历史消息、RAG证据、工具定义和输出Schema;接着估算Token预算,经过网关模型做路由、限流、超时、重试和供应商选择;供应商返回同步结果或流式事件后,后端解析增量、校验结构化输出、落库状态和usage;最后把TTFT、总耗时、错误码、重试次数、Token成本写入观测系统。

2.Streaming为什么能改善体验

Streaming 让模型边生成边返回,用户可以更早看到第一个 Token,因此降低 TTFT。它不保证总生成时间变短,也不天然减少 Token 成本。后端需要额外处理取消、超时、断流、重连、半成品 JSON 和增量落库。

3.SSE和WebSocket怎么选

如果只是服务端向浏览器推模型文本,SSE 更简单,天然适合单向增量输出;落地时别忘了 text/event-stream 对换行与事件边界敏感,以及反向代理缓冲会把「流式」攒成「批量」。如果客户端也要频繁向服务端发数据,例如语音流、实时控制、多人协作、插话打断,WebSocket 更适合。HTTP chunked 更偏底层传输机制,业务层仍要自己定义消息边界和事件类型。

4.哪些大模型API错误可以重试

网络瞬断、连接重置、部分5xx、504、供应商过载通常可以有限重试;429 要结合 Retry-After、限流头、排队和降级处理;400 参数错误、401/403 鉴权错误、内容安全拒答通常不能重试。结构化解析失败可以做 1-2 次格式修复,但不要无限重试。

5.为什么大模型调用必须做幂等

因为重试、用户重复点击、网关超时都会让同一个业务请求被执行多次。没有幂等 Key,就可能重复落库、重复扣费、重复发通知。正确做法是用业务消息 ID 生成幂等 Key,把多次模型调用 attempt 挂在同一条业务消息下,只允许一个 attempt 成为最终结果。

6.限流为什么不能只按QPS(Queries Per Second,每秒请求数)

因为大模型 API 的成本和压力主要由 Token 决定。一个 500 Token 请求和一个 80K Token 请求都是 1 次请求,但资源消耗差异很大。生产限流要同时看 RPM、TPM、并发数、上下文大小、最大输出和租户预算。

7.JSON Mode 和Structured Outputs区别

JSON Mode 更关注“输出是合法 JSON”,但不一定符合你的业务 Schema。Structured Outputs 或 JSON Schema 约束更强,可以要求字段、类型、必填项、枚举等结构。Function Calling 或 Tool Use 更适合让模型产出工具调用参数。不同供应商支持的 Schema 子集不同,落地前要查官方文档并写兼容层

8.流式结构化返回怎么处理

不要一边收到 delta 一边直接 JSON.parse() 完整对象。更稳的做法是:增量阶段只展示文本或记录片段,等收到正常结束事件后拼成完整内容,再做 Schema 校验。若供应商支持结构化流式事件或 SDK accumulator,可以使用官方累积器;否则自己维护 buffer、sequence 和结束状态。

9.模型网关是稳定性入口。路由、限流、重试、幂等、观测全在这里收口。没有网关的团队,每个业务模块各自处理 API Key 和重试逻辑,短期省事,长期一定出事故。

结构化返回是数据契约。JSON Schema、Structured Outputs、Tool Use 解决的是"让下游系统能稳定消费模型输出",而不是"让输出看起来像 JSON"。

没有观测就没有稳定性。TTFT、usage、attempt、providerRequestId、parse failure rate——线上排查时少任何一个字段,都会让你多花几倍时间定位问题。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐