ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

大模型的回答是怎么一个字一个字蹦出来的?前端流式输出解析

大模型的回答是怎么一个字一个字蹦出来的?前端流式输出解析 我们正处在一个特殊的时代节点——Agent 开发时代。AI 正越来越像人一步步走向 AGI。作为前端工程师新的命题出现了如何把工作拆分把 AI 擅长的交给 Agent我们负责审核不擅长的我们接管。举个小例子项目工程初始化完全没必要从 0 手写一个 Vue 项目src/App.vue、index.html一堆文件直接到 GitHub 拉一个模板项目交给 Agent 去搭就行。而要跟大模型打交道流式输出Streaming就是绕不开的第一课。这篇文章带你彻底搞懂它。一、开发态的底气Vite 热更新在聊流式输出之前先说一个开发阶段的好东西——热更新Hot Reload它来自 Vite。传统开发模式下每次改完代码都要刷新浏览器才能看到效果。但刷新页面有个致命问题页面状态会丢失。Vue / React 里密密麻麻的数据状态表单填了一半、列表滚到中间、弹窗打开了……全没了得重新来一遍。热更新做的是另一件事有了它改代码时页面状态稳稳保留开发体验丝滑得不行。这是现代前端工程化的基础也是我们能愉快调试流式输出代码的前提。二、流式输出的本质二进制流 SSE2.1 服务器返回的是什么一句话stream 返回的就是二进制流。具体来说它是一个Uint8Array——无符号 8 位整数数组每个数在0-255之间。这就是网络世界里最原始的数据形状一个个字节。字节不是字符一个中文字如中在 UTF-8 里占 3 个字节所以必须安排编码才能还原成我们能读的字符串。这就是TextDecoder的活儿。2.2 ReadableStream一根水管浏览器原生提供了ReadableStream对象可以把它想象成一根水管服务器那头开水龙头数据一滴一滴流过来浏览器这头可以一边接一边处理不用等整桶水装满这就是为什么大模型能边生成边显示——模型每算出一个 token最小的语义单元就立刻顺着管子推给浏览器用户即时看到。2.3 SSE数据长什么样流式输出用的是SSEServer-Sent Events格式。服务器推过来的原始文本长这样规则就三条每条消息以data:开头消息之间用空行两个\n分隔最后一条固定是data: [DONE]表示流结束注意流式里内容字段叫delta增量不是非流式里的message。三、实战Vue 3 调用 DeepSeek 实现流式对话3.1 技术栈一览技术角色Vue 3script setup组合式 API逻辑组织更聚合ref创建响应式数据数据变页面自动更新fetch浏览器原生 HTTP 客户端无需 axiosReadableStreamgetReader()逐块读取响应体TextDecoder字节流 → 字符串SSE 按行解析提取每一段增量内容3.2 数据状态设计用三个ref搞定整个页面的状态为什么用 ref普通变量改了 Vue 不知道页面不会变。ref()把值包装成响应式引用对象RefImplxxx.value一改页面上绑定它的地方会局部热更新不用碰 DOM。3.3 发请求fetch DeepSeek API几个要点API Key 从哪来import.meta.env.VITE_DEEPSEEK_API_KEY是 Vite 的环境变量注入。项目根目录放一个.env文件写VITE_DEEPSEEK_API_KEYsk-xxx。变量名必须以VITE_开头Vite 才会暴露给前端既安全又方便多环境切换。Authorization: Bearer xxx是 REST API 标准认证格式Bearer 空格 Token。JSON.stringify必不可少——HTTP 只能传字符串/二进制传不了 JS 对象。messages遵循 OpenAI 格式每条消息有rolesystem/user/assistant和content。四、流式核心边接边显示这是全文最关键的部分。分三步走。第一步拿到读取器吸管第二步准备工具buffer 为什么必须存在这是 SSE 解析的核心坑。一个 chunk 末尾可能是data: {conten下一个 chunk 开头才是t:你好}。如果本轮解析失败就丢掉内容直接缺失。必须把半截存进 buffer下一轮拼上再解析。第三步循环读取 解析 追加关键点逐个说await reader.read()会在这里暂停等待直到下一块数据到达。这就是边生成边显示的底层机制——模型不吐数据代码就停在这儿等。done: doneReading是解构时重命名避免和外层done变量冲突。content.value delta每次追加一个字Vue 响应式系统自动更新{{ content }}绑定的节点页面就一个字一个字蹦出来。try/catch 兜底半截 JSON解析失败不报错存进 buffer 等下轮拼上再试保证内容不丢。非流式分支对比非流式时服务器等全部算完一次性返回完整 JSON注意字段是message不是delta。五、页面双向绑定让数据流起来v-model双向绑定。输入框打字 →question.value自动变JS 里改question.value→ 输入框也跟着变。复选框的v-model绑定的是布尔值。clickupdate点击触发请求函数。{{ content }}插值语法content一变就自动重渲染。整条数据链路用户输入 → v-model → question.value → fetch 请求 → 流式读取 → content.value delta → {{ content }} 自动更新全程不碰 DOM改数据就行——这就是 Vue 数据驱动视图的魅力。六、样式Flex 弹性布局一统江湖Flexbox 是现代布局首选比 float/position 简单太多。100vh让容器撑满屏幕rem做移动端等比例适配。总结一图看全流程一句话记住流式输出 ReadableStream逐块读 TextDecoder解码 SSE 按行解析 ref响应式追加。掌握这条链路你就拿住了大模型时代前端的入场券。Agent 时代已来热更新让开发丝滑流式输出让交互即时。这些不是炫技而是新时代前端的日常。下一站我们继续探索如何用 LangChain 把大模型的能力变成真正可用的 Agent。资料展示下面是我整理的AI大模型 学习资料和工具包 预览适合收藏后按主题逐步学习
返回列表