SEO技术

SEO技术

Products

当前位置:首页 > SEO技术 >

LLM流式输出原理是什么?

96SEO 2026-08-03 20:57 3


从从等待到流式来看,LLM 流式输出的原理、协议与工程实践

打开任何一个 AI Chatbot——ChatGPT、Claude、DeepSeek——你输入一个问题。它不像传统网页那样转圈等 几秒 接下来啪地一下弹出全部回答。相反,文字像打字机一样一个字一个字地往外蹦。

这不是动画效果,也不是前端做了一个“打字机 CSS 动画”。

LLM流式输出原理是什么?

这是 HTTP 协议层的一条水流:LLM 服务端每生成一个 token。就通过一条长连接推给客户端,客户端收到一段就渲染一段。

第三十五天我们写了一个 Vue 前端来消费 DeepSeek 的流式 API。但这篇文章不止于“怎么在前端调 stream 接口”——我们要从 HTTP 协议栈的最底层一路往上,把流式输出的完整技术链路拆解清楚。不过,因为面试官不会只问你 stream: true 怎么写。他会追问:

这些问题,我们一个个回答。

一、为什么需要流式输出:从 Transformer 推理说起

推理为什么慢

大语言模型的主要是 Transformer 架构。它在生成文本时采用自回归解码每次预测下一个 token。接下来把新 token 拼回输入,再预测下一个——像一个接龙游戏。

输入:"今天的天气"
→ 预测下一个 token:"真"
→ 把"真"拼回去:"今天的天气真"
→ 预测下一个 token:"好"
→ 把"好"拼回去:"今天的天气真好"
→ ...直到预测出 

每个 token 都要跑一次前向传播,涉及数十亿参数的矩阵运算。这就是 LLM 推理慢的根本原因——不是一次慢,而是要重复很多次。

使用者痛点:当模型需要生成上百个 token 时总耗时往往超过 10 秒。远超使用者耐心阈值,导致页面卡死或直接关闭。

使用者的等待容忍度

  • <0.5 秒使用者感觉“瞬间”。
  • 0.5–1 秒使用者注意到延迟,但思维不会中断。怎么说呢,
  • 1 秒使用者开始分心、切 tab、怀疑是否卡死。

痛点示例:如果不做流式输出。一个复杂问题可能要等 10 秒以上——这远超使用者耐心极限,导致高跳出率。

流式设计的主要洞察

第一个 token 的出现时间比总耗时关键得多。

流式输出不减少总耗时但它改变了感知性能使用者在第 .5 秒 就看到第一个字。大脑立刻知道“它在工作”,等待焦虑瞬间消失。说起来,

非流式:
→ 一次性返回全部文字
从流式来看。→ 逐字流出 → → 结束
↑ 使用者在这里就安心了

痛点对策:通过实现 TTFT 最小化,让使用者感受到即时反馈,从而明显提高留存率和满意度。

二、HTTP 协议层:流式传输的基建

Content-Length 的问题

传统 HTTP 响应需要先知道完整体积才能发送:

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 123
{"choices":}

L​LM 必须边生成边发送。却在生成完之前根本不知道总长度,这直接导致阻塞。

痛点:If server waits for full response before setting Content‑Length,client experiences a long “blank” period.

Transfer-Encoding: chunked

Transfer-Encoding: chunked 为“未知长度但需要逐步发送”的场景提供了方法:

HTTP/1.1 200 OK
Content-Type: text/event-stream
Transfer-Encoding: chunked
7\r
Hello\r
6\r
World!\r
0\r
\r
  • chunked encoding = 快递公司允许把大包裹拆成多个小包分批寄出。
  • SSE = 每个小包里装的具体格式。

痛点:If upstream proxy buffers chunks before forwarding,“real‑time” feel disappears.

从 curl 看原始流

curl -N -X POST https://api.deepseek.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $DEEPSEEK_API_KEY" \
-d '{
"model": "deepseek-v4-flash"。"messages":,"stream": true
}'

-N 参数让 curl 不缓冲,直接打印每个 SSE 块:

data: {"id":"...","choices":}
data这方面,{"id":"...","choices":}
至于data,{"id":"...","choices":}
data的观点是,

三、SSE 协议详细说明

什么是 SSE

SSE是 HTML5 标准的一部分,定义在 W3C EventSource spec 中。它允许服务端通过单向 HTTP 长连接持续向客户端推送数据。

  • SSE 出现于 2009 年,比 WebSocket 更早;但直到 LLM 流式输出兴起才
  • SSE 天然兼容所有 HTTP/HTTPS 基础设施,无需额外握手。

SSE 协议格式

规则说明
字段前缀 含义
data:事件内容
event:自定义事件类型
id:事件 ID。用于自动重连
retry:服务器建议的重连间隔毫秒
空行 标记一次事件结束
以 ":" 开头的行 注释,客户端忽略

A typical SSE event example:

id: abc123
从event来看,message
data的观点是,{"token":"你"}
从data来看,{"token":"好"}
两行 `data:` 会被客户端拼接为单条消息。

LLM API 中的 SSE 格式

{
说到"id","chatcmpl-xxx","object": "chat.completion.chunk"。"created": 1724000000,"model": "deepseek-v4-flash","choices":
}
从关键字段来看,
  • deltа.content: 本次增量文本。与完整回复里的 .message.content**不同**。
  • `finish_reason`: 为 `"stop"` 时表示生成结束,通常伴随 ``。
  • `index`: 当 `n> 1` 时区分不同候选答案。

为什么是 SSE 而不是 WebSocket

< td >Coding complexity
维度 SSE WebSocket
通信方向 单向:服务端 → 客户端 双向:服务端 ↔ 客户端
协议层 纯 HTTP,无需升级握手 / td>需要 Upgrade 到 websocket 协议 / td>
基础设施兼容性 / td>穿透所有 HTTP/HTTPS Proxy、CDN、负载均衡器 / td>部分代理不支持。需要特殊配置 / td>
连接建立成本 / td>普通 HTTP 请求就可以完成握手 / td>必须额外进行 Switching Protocols 握手 / td>
自动重连机制 / td>EventSource 原生自动重连 / td>需自行实现 reconnect logic / td>
  • SSE 完全匹配 LLM 流式需求:“一次请求,持续推送”。老实说,
  • The 双向特性和额外握手会带来 **过度设计** 与 **维护成本**。老实说,
  • SSE 在防火墙/公司网络中更友好。不易被拦截或降级,<\/ul>  面试要点 : 当被问到 “ChatGPT 为什么用 SSE 而不是 WebSocket”。不要只说 “单向就够了”,要展开说明 **协议简洁性** 、 **代理友好** 、 **原生自动重连** 与 **实现成本低** 四个维度。其实,

    EventSource vs fetch + ReadableStream
    • `EventSource`只能发 GET 请求且不支持自定义 Header;而 LLM API 必须 POST 并携带 Authorization Header。
    • `EventSource` 自动重连机制对 LLM 对话不友好——重连后无法带上上下文。实际工程中几乎都采用 `fetch` + `ReadableStream` 手动消费 SSE。<\/ul> javascript const es = new EventSource // ❌ 无法满足 LLM 要求 // 正确姿势 const resp = await fetch(endpoint。{ 至于method,'POST',headers:{'Content-Type':'application/json','Authorization':`Bearer ${apiKey}`},body:JSON.stringify });

      四、服务端:LLM 如何 token‑by‑token 生成并推送

      自回归解码与流式写入

      L​LM 推理引擎在每一步产生 token 后通过回调或 generator 将 token 抛给上层框架;框架再把 token 包装成 SSE 格式写入响应体,实现“边算边传”。下面分别展示 Python FastAPI 与 Node.js Express 的实现方式。

      python from fastapi import FastAPI from fastapi.responses import StreamingResponse import json,asyncio app = FastAPI async def generate_tokens: # 实际调用模型推理引擎,此处模拟 for token in : chunk = { "choices": } yield f"data:{json.dumps} " await asyncio.sleep # 模拟计算耗时 yield "data: " @app.post async def chat_stream: return StreamingResponse( generate_tokens)。media_type='text/event-stream',headers={ 'Cache-Control':'no-cache','Connection':'keep-alive','X-Accel-Buffering':'no' # 禁止 nginx 缓冲,否则会失去实时性 } ) javascript // node_express_example.js app.post=>{ res.setHeader;res.setHeader;res.setHeader;res.setHeader;
      const tokens =;for{
      const chunk = JSON.stringify({
      choices:
      });res.write,await new Promise);}
      res.write,res.end;

      });

      Pain point:: 若忘记禁用代理缓存。即使后端已经逐块写入,前端仍会等到缓存满后才收到数据,体验退化为非流式。

      从stream来看,true 到底改变了什么

Body  传输方式  客户端处理  TTFB 
stream:false   stream:true   
响应头     Content‑Type: application/json     Content‑Type: text/event-stream    
 一次性完整 JSON                         Chunked SSE 事件序列                
 一次性发送           Transfer‑Encoding: chunked          
 response.json           response.body.getReader + 手动解析          
 必须等全部 Token 完成后才返回首字节           首 Token 完成即返回 ⇒ TTFT 大幅下降          

主要 API 链路

``javascript const response = await fetch(endpoint。{ 说到method,'POST',headers:{ 'Content-Type':'application/json','Authorization':Bearer ${apiKey}` },body的观点是,JSON.stringify({ model这方面,'deepseek-v4-flash',messages:,stream:true // 告诉服务器开启 SSE 流模式 }) });

// 第一步先:拿到可读流 const reader = response.body.getReader;

// 接下来:创建 TextDecoder const decoder = new TextDecoder;

// 然后:循环读取并处理 let buffer = '';while{ const {done,value}=await reader.read;if break,怎么说呢,

// 将 Uint8Array 转成字符串。同时保留未完成字符
buffer += decoder.decode;按理说,// 按行切分 – 注意最终一行可能是不完整的
const lines = buffer.split;老实说,buffer = lines.pop||'';// 保存残余片段
for{
if) continue;const raw=line.slice.trim;// 去掉 “data:” 前缀
if return;// 流结束标记
try{
const chunk=JSON.parse;
const txt=chunk.choices?.,.delta?.content||'';不过,// 将 txt 累加到 UI 中。例如 Vue state.push
}catch{
console.warn;// 保持稳健,不抛异常终止整个读取循环
}
}

}

// 循环结束后处理可能残留在 buffer 中的数据 if){ // 一样尝试解析剩余部分…}

Pain point:: 若省略 decoder.decode,中文或 Emoji 等多字节字符会出现乱码;若不做 buffer 合并。会因 TCP 分片导致 JSON 无法完整解析,引发崩溃。

为什么 TextDecoder 要加 { stream:true }

  • 多字节 UTF‑8 字符可能跨越两个 TCP 包。例如中文 “好” 编码为 E5 A5 BD;若第一包只收到 E5 A5没有 { stream:false } 会直接抛出替换字符。而 { stream:true } 会保存未完成序列,下次解码时拼接恢复完整字符。

javascript const enc=new TextEncoder;话说回来,const bytes=enc.encode;// const part1=bytes.slice;// const part2=bytes.slice;//

const dec=new TextDecoder;console.log);// '' console.log);// '好'

最终一段数据的处理

即使 reader.read 返回 {done:true}仍有可能携带最终一块 payload。循环退出后必须检查 buffer 中残留内容并完成一次解析。

javascript if{ const line=buffer.trim;if){ const raw=line.slice.trim;if{ const chunk=JSON.parse;content+=chunk.choices?.,.delta?.content||'';} }

  • AbortController :让使用者随时取消正在进行的对话。
  • 错误分类 :HTTP 错误 | 网络中断 | SSE 解码错误,并给出对应恢复策略。
  • 断点续传 :短回答直接全局重试;长回答缓存已生成内容并放进 messages 重启,以期续写。
  • 背压 :浏览器内部已基于 TCP 流控处理,一般无需手动干预;若渲染逻辑非常耗时可考虑将解析搬至 Web Worker。
  • 代理配置 :nginx 使用 proxy_buffering off 或响应头 X‑Accel‑Buffering:no;话说回来,设置足够大的 proxy_read_timeout;话说回来,Cloudflare/AWS ALB 相应调高 idle timeout。
  • HTTP/ vs HTTP/1. :HTTP/ 的多路复用让同一连接可以并发多个请求,提高整体吞吐;怎么说呢,但某些老旧 CDN 对长连接支持不足,需要监测兼容性。<\/ul>
  • Pain point 示例:: 在生产环境未关闭 nginx 缓冲导致 “第一次 token 延迟30秒”,经排查发现是默认 proxy_buffering on;添加 proxy_buffering off; 或响应头即解决。

  • Agent 工具调用透明化 :每一步工具调用都可以使用一样的 SSE 格式实时推送,让人类观察 AI 思考过程并及时干预。
  • css 至于data。{\"type\":\"thinking\",\"content\":\"正在搜索…\"} 再看data,{\"type\":\"tool_call\"。\"tool\":\"search\",\"args\":{\"query\":\"…\"}} data的观点是,{\"type\":\"tool_result\",\"tool\":\"search\"。\"result\":\"找到12条结果\"} ...

  • RAG 与流式结合 :检索阶段快速返回后立即进入模型流水线进行长文本生成;也可以探索 Speculative Streaming —— 在检索尚未完成时先返回模型猜测出的首句,以进一步压缩感知延迟。其实,
  • MCP 与大文件读取 :虽然 MCP 本身基于 JSON-RPC。不强制使用流,但可以把“大文件读取”实现为分块返回,从而避免一次性占满内存。
  • <\/ul>

    基础层

  • **为什么要用流式输出?** —— 自回归解码导致总耗时长,TTFT 是决定使用者是否继续的关键指标。话说回来,
  • **HTTP 层如何实现?** —— 用 Transfer-Encoding:\ chunked 每个 chunk 即为 SSE 行。
  • 格式怎样?** —— text/event-stream data的观点是,\ …支持 `.id`,`.event`。`.retry`.
  • 对比层

  • **SSE vs WebSocket?** — 单向数据流场景下 SSE 更轻量、更兼容公司网络;按理说,WebSocket 属于过度设计。怎么说呢,
  • **EventSource vs fetch+ReadableStream?** — EventSource 不支持 POST 与自定义 Header。而 LLM API 必须 POST 并携带 Authorization,所以只能使用 fetch+ReadableStream。
  • 实现层

  • **ReadableStream 怎么用?** — `.getReader`,循环 `.read`。用 `.TextDecoder`,管理 buffer 并按行解析 SSE。其实,
  • **为何要做 buffer 管理?** — TCP 分片随意切割,会导致 JSON 被截断;没有 buffer 会产生解析错误甚至崩溃。
  • **TextDecoder 的 `.decode`**: 保证多字节字符跨包仍能正确拼接。老实说,
  • 高阶层

  • **如何取消正在进行的流?**: 使用 AbortController + reader.cancel 捕获 AbortError。
  • **网络中断后如何续传?**: 短回答直接全局重试;按理说,长回答缓存已得内容并放进 messages 重启。对话状态保持一致但会产生额外 Token 消耗。
  • **nginx/Egress Proxy 如何配置才能真正做到实时?**: 加 `X‑Accel‑Buffering:no`,`proxybuffering off`。增大 `proxyread_timeout`.
  • **哪些场景不适合使用流式?**: 必须保证事务原子性的操作、小体积一次性返回的数据还有不支持 Stream API 的嵌入设备。
  • L​LM 流式输出看似只是前端“把接口改成 stream”。实则是一条横跨 **硬件算力 → Transformer 推理 → HTTP Chunked Transfer → SSE 协议 → 浏览器 ReadableStream → UI 渲染** 的完整技术链路,每一步都有潜在「卡顿」或「丢失」风险,需要有针对性的工程措施来消除。

    • User Experience 层: Pain point:: 超过 ~1 秒无反馈,即出现高跳出率。SOLUtion:: 实现可靠且低延迟的首 Token 推送。


    标签: 流式

    SEO优化服务概述

    作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。

    百度官方合作伙伴 白帽SEO技术 数据驱动优化 效果长期稳定

    SEO优化核心服务

    网站技术SEO

    • 网站结构优化 - 提升网站爬虫可访问性
    • 页面速度优化 - 缩短加载时间,提高用户体验
    • 移动端适配 - 确保移动设备友好性
    • HTTPS安全协议 - 提升网站安全性与信任度
    • 结构化数据标记 - 增强搜索结果显示效果

    内容优化服务

    • 关键词研究与布局 - 精准定位目标关键词
    • 高质量内容创作 - 原创、专业、有价值的内容
    • Meta标签优化 - 提升点击率和相关性
    • 内容更新策略 - 保持网站内容新鲜度
    • 多媒体内容优化 - 图片、视频SEO优化

    外链建设策略

    • 高质量外链获取 - 权威网站链接建设
    • 品牌提及监控 - 追踪品牌在线曝光
    • 行业目录提交 - 提升网站基础权威
    • 社交媒体整合 - 增强内容传播力
    • 链接质量分析 - 避免低质量链接风险

    SEO服务方案对比

    服务项目 基础套餐 标准套餐 高级定制
    关键词优化数量 10-20个核心词 30-50个核心词+长尾词 80-150个全方位覆盖
    内容优化 基础页面优化 全站内容优化+每月5篇原创 个性化内容策略+每月15篇原创
    技术SEO 基本技术检查 全面技术优化+移动适配 深度技术重构+性能优化
    外链建设 每月5-10条 每月20-30条高质量外链 每月50+条多渠道外链
    数据报告 月度基础报告 双周详细报告+分析 每周深度报告+策略调整
    效果保障 3-6个月见效 2-4个月见效 1-3个月快速见效

    SEO优化实施流程

    我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:

    1

    网站诊断分析

    全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。

    2

    关键词策略制定

    基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。

    3

    技术优化实施

    解决网站技术问题,优化网站结构,提升页面速度和移动端体验。

    4

    内容优化建设

    创作高质量原创内容,优化现有页面,建立内容更新机制。

    5

    外链建设推广

    获取高质量外部链接,建立品牌在线影响力,提升网站权威度。

    6

    数据监控调整

    持续监控排名、流量和转化数据,根据效果调整优化策略。

    SEO优化常见问题

    SEO优化一般需要多长时间才能看到效果?
    SEO是一个渐进的过程,通常需要3-6个月才能看到明显效果。具体时间取决于网站现状、竞争程度和优化强度。我们的标准套餐一般在2-4个月内开始显现效果,高级定制方案可能在1-3个月内就能看到初步成果。
    你们使用白帽SEO技术还是黑帽技术?
    我们始终坚持使用白帽SEO技术,遵循搜索引擎的官方指南。我们的优化策略注重长期效果和可持续性,绝不使用任何可能导致网站被惩罚的违规手段。作为百度官方合作伙伴,我们承诺提供安全、合规的SEO服务。
    SEO优化后效果能持续多久?
    通过我们的白帽SEO策略获得的排名和流量具有长期稳定性。一旦网站达到理想排名,只需适当的维护和更新,效果可以持续数年。我们提供优化后维护服务,确保您的网站长期保持竞争优势。
    你们提供SEO优化效果保障吗?
    我们提供基于数据的SEO效果承诺。根据服务套餐不同,我们承诺在约定时间内将核心关键词优化到指定排名位置,或实现约定的自然流量增长目标。所有承诺都会在服务合同中明确约定,并提供详细的KPI衡量标准。

    SEO优化效果数据

    基于我们服务的客户数据统计,平均优化效果如下:

    +85%
    自然搜索流量提升
    +120%
    关键词排名数量
    +60%
    网站转化率提升
    3-6月
    平均见效周期

    行业案例 - 制造业

    • 优化前:日均自然流量120,核心词无排名
    • 优化6个月后:日均自然流量950,15个核心词首页排名
    • 效果提升:流量增长692%,询盘量增加320%

    行业案例 - 电商

    • 优化前:月均自然订单50单,转化率1.2%
    • 优化4个月后:月均自然订单210单,转化率2.8%
    • 效果提升:订单增长320%,转化率提升133%

    行业案例 - 教育

    • 优化前:月均咨询量35个,主要依赖付费广告
    • 优化5个月后:月均咨询量180个,自然流量占比65%
    • 效果提升:咨询量增长414%,营销成本降低57%

    为什么选择我们的SEO服务

    专业团队

    • 10年以上SEO经验专家带队
    • 百度、Google认证工程师
    • 内容创作、技术开发、数据分析多领域团队
    • 持续培训保持技术领先

    数据驱动

    • 自主研发SEO分析工具
    • 实时排名监控系统
    • 竞争对手深度分析
    • 效果可视化报告

    透明合作

    • 清晰的服务内容和价格
    • 定期进展汇报和沟通
    • 效果数据实时可查
    • 灵活的合同条款

    我们的SEO服务理念

    我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。

    提交需求或反馈

    Demand feedback