96SEO 2026-08-09 19:21 2
面试官看了一眼你的项目:"AI 对话为什么能像打字机一样逐字输出?"
这个问题像剥洋葱——每剥一层都有追问。你说用了 SSE,他问为什么不用 WebSocket。你说 HTTP 分块传输,他问半个中文字被截断了怎么办。话说回来,你说状态管理,他问 LLM 每秒出 个 token,React 跟得上吗。

要回答好这个问题,比较合适的方法就是沿着代码的执行方法走一遍。数据从使用者敲下回车到屏幕上跳出第一个字,到底经过了哪些代码?每一行代码解决了什么问题?其实,
打开 Chat.tsx使用者输入文字后点击"发送"按钮。按钮的 type="submit" 触发表单的 onSubmit 事件:
// Chat.tsx
const onSubmit = => {
e.preventDefault;if ) return,怎么说呢,handleSubmit;// 把事件交给 AI SDK 处理
};
handleSubmit 是 useChatbot 返回的,而 useChatbot 来自 @ai-sdk/react
// hooks/useChatBot.ts
export const useChatbot = => {
return useChat({
再看api。'/api/ai/chat',onError: => console.log
})
}
User Pain Point:
就这几行代码。useChat 帮我们做了三件事:
messages{ role: "user",content: "你好" }{ },使用者的消息立刻显示来。User sees ir message appear instantly;AI is still thinking—three dots spin.
B先看它是怎么把请求转发给 DeepSeek 的:
// mock/chat.js
const response = await fetch('https://api.deepseek.com/v1/chat/completions',{
method的观点是,'POST'。headers: {
'Content-Type': 'application/json','Authorization': `Bearer ${process.env.VITE_DEEPSEEK_API_KEY}`
说到},body,JSON.stringify({
从model来看,'deepseek-chat',messages,stream: true // ← 关键:告诉 DeepSeek 我要流式输出
})
});其实,User Pain Point:`stream:true` 决定返回方式。不加它,DeepSeek 会返回完整 JSON;加上它会拆成碎片,用 SSE 推送。B如果写成 `streaming:true` 就会被忽略,从而导致没有打字机效果——前端等待几秒才一次性显示文本。拿到 DeepSeek 的流式响应后接下来是实时翻译。DeepSeek 返回的是 SSE 格式,每一片数据长这样:
至于data,{id:"xxx",choices:}
至于data。{id:"xxx",choices:}
data这方面,前端用的是 @ai-sdk/react,它不认识 SSE,它有自己的“”——Vercel AI SDK Data Stream 协议。再看格式是这样的,
// Vercel AI SDK Data Stream 示例
从:"你"来看。"好"
mock 要做的是把 SSE 的 `data.choices.delta.content` 取出来并包上一层 `:` 的外壳:
// mock/chat.js — 主要转换
const data = JSON.parse);// 去掉 "data: " 前缀
const content = data?.choices,.?.delta,说起来,.content;// 取出这次产生的字
if {
res.write}
`);// 翻译成 AI SDK
}
`res.write` 在收到每行时立即执行,没有任何蓄水。
至于第三站,前端的流式消费
B数据被逐片推送到浏览器后AI SDK 的 `processDataStream` 函数开始工作。老实说,主要原因简化后是这样:
// @ai-sdk/ui-utils — processDataStream
async function processDataStream {
const reader = stream.getReader;// 拿到流的“遥控器”
const decoder = new TextDecoder;// 字节 → 文本解码器
let buffer = '';while {
const { done,value } = await reader.read;// 读一块数据
if break;
buffer += decoder.decode;// 字节转文字
const lines = buffer.split;按理说,// 按换行切分
buffer = lines.pop || '';// 最终一段留着,下次拼
for {
const { type。value } = parseDataStreamPart;if { // line=':"你"' → type='text',value='你'
onTextPart;// 回调:把新字追加到消息里
}
}
}
}
当 onTextPart 被调用时AI SDK 把新收到的字拼接到 assistant 消息里的 content 并触发一次 React 的 更新。React 检测状态变化并重新渲染
中 于是页面出现新的字符。
四、两个必须处理的边界情况
一行数据被切成两半
TCP 是流式协议,它不关心你的数据边界。例如 DeepSeek 推送了一行:
// 深度示例
data的观点是。{\"choices\":}
如果网络层将其拆为两块:
从第一块来看,“data:{\"delta\":{\"content\":\"你”
第二块这方面,“好\"}]}
”,第一块解析会报错。按理说,再看我们使用,
// 保留未完成的一行以备后续拼接
buffer = lines.pop || '';
此方法确保只处理已完整结束的新行。
一个中文字被切成两半
A UTF‑8 中文字符占三字节。如果 TCP 切分在中间,直接解码会乱码。解决办法是让 TextDecoder 持续缓存未完成多字节序列:
// 解码时告诉它还有更多数据来临,decoder.decode;
五、每次收到一个字就渲染?那页面早卡死了
BLLM 每秒生成约30~60个 token。如果每个 token 都触发一次 setState,就会频繁渲染导致卡顿。
B打开 AI SDK 的 triggerRequest 源码,它采用 throttle 调整:
// @ai-sdk/react — triggerRequest 内部实现
const throttledMutate = throttle;// 收到新 token 时:
throttledMutate;其实,
Throttle 类似节拍器。只允许在固定时间窗口内执行一次 mutate。说起来,窗口通常几十毫秒。让 UI 更新频率从每秒30~60次降至约5~6次同时保持“实时感”。
六、为什么选这套技术方法?
SSE vs WebSocket
-
D WebSocket 是双向通信;说起来,SSE 是单向推送。对话场景仅需要单向推送,所以 SSE 更合适。
-
D 不需要 HTTP Upgrade 握手;浏览器原生支持自动重连且兼容 HTTP/1.x 与 HTTP/2/HTTP/3。
-
D 配置简单,仅需三行响应头即可开启流式:
-
D Content-Type 设置为 text/plain;charset=utf‑8;
-
D Transfer-Encoding 为 chunked;
-
D x-vercel-ai-data-stream 标识协议版本 v1;
以上三条就可以完成全流程,无需额外框架或代理。按理说,
User Pain Point:
"我想使用 WebSocket 能否提高性能或实现双向聊天?" → SSE 已足够满足大多数需求;话说回来,若确实需要双向。可在同一接口内部同时监听 SseEventSource 与 WS,但通常成本高于收益。
为什么不用原生 fetch 手写流解析?
User Pain Point:
"是否真的必要引入第三方 SDK?我更喜欢自己控制所有细节。" → A 像大模型交互这种业务场景常见模式已被封装成熟组件;老实说,引入 SDK 可显著降低 bug 风险和维护成本。并让团队专注业务逻辑,而非底层细节。
标签:
打字机
-
上一篇:
我为何感到被时代遗忘?
-
下一篇:
Headroom:AI Agent如何实现上下文压缩?
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback