2026/11/2 13:34:00

AI应用前端工程师三个月进阶路线:流式输出到Agent实战

AI应用前端工程师三个月进阶路线:流式输出到Agent实战 1. 先搞清楚AI 应用前端到底在做什么这两年前端圈最大的变化不是 Vue 出了新版本也不是 React 又改了并发渲染机制而是“AI 应用前端工程师”这个岗位突然冒了出来。打开招聘软件你会看到很多公司 JD 已经不满足于“会写页面、会调接口”而是明确写着“接入过大模型 API”“做过流式输出”“有 Agent 交互产品经验”。如果你还停留在传统前端的舒适区确实该紧张了。这篇文章我整理了近期的招聘趋势同时也结合我过去几个项目的经验梳理出一份三个月学习计划从基础强化、Agent 产品落地再到面试冲刺按周拆解直接照着执行就行。1.1 它和传统前端开发的本质差异很多人以为 AI 应用前端就是把 ChatGPT 的界面抄一抄做一个输入框加一个气泡列表然后调一下大模型接口完事。真做起来会发现完全不是这么回事。传统前端面对的数据结构是确定的用户信息返回一个 JSON订单列表返回一个数组表单提交返回一个成功或失败。你只要关心数据怎么展示、交互怎么处理、状态怎么流转就行。前端工程师可以做到“页面即服务”接口是稳定的数据是闭合的。AI 应用前端面对的是完全不同的东西大模型的输出是一个不断变化的 Token 流。用户看到第一句话的时候第二句话还在生成第三句话可能在响应用户刚才的某个操作。再加上多轮对话、上下文管理、工具调用、知识库引用、思维链展示……数据模型从“确定性返回”变成了“动态生成 被动接收”。这在传统前端里几乎找不到现成的套路需要重新设计状态管理、缓存策略、加载反馈甚至重新思考什么是“加载完成”。更关键的是AI 应用前端的交互模式也从“点击—跳转—反馈”变成了“对话 实时生成 可干预”。用户不再是一个被动接收页面的人而是会打断生成、追问细节、让模型重新作答。前端必须支持“中止生成”“重新生成”“编辑上下文”这类操作。这些交互设计在传统组件库里面没有模板全部要自己摸索。1.2 必须重建的六个核心认知如果只把这篇文章当成一个“学习清单”那你最多学到一半就会迷路。我建议先在心里面把这六个认知建立起来后面的学习才有方向感。流式是默认体验不是加分项。大模型响应用户如果前端等全部生成完再渲染用户等待时间可能超过三十秒。正常的产品设计必须是流式输出Token 出来一个渲染一个让用户感觉“它在打字”。这个体验是 AI 应用前端的基本盘不是可选项。多轮对话就是状态管理。每一轮对话都携带历史上下文前端要维护一个 messages 数组管理 user、assistant、system、tool 四种角色的消息并且随时可能被删除、插入、重发。这和传统表单的状态管理完全是两套思维。不能盲信大模型返回的 Markdown。大模型输出的字符串默认是带格式的存在 XSS 注入的可能有脚本文本会被当作 HTML 执行有截图脚本可以绕过防审系统。必须做渲染层清洗对 HTML 全部 escape对标签白名单处理。上下文长度要可视化。用户不会意识到对话越聊越长前端需要主动展示 token 用量或者在大模型报“超出上下文限制”之前就提示用户精简对话。不要等后端报错才处理。组件设计的核心是“可打断”。AI 生成过程中必须支持中止、重新生成、局部修改。很多团队一开始只做了“发送—接收”的循环上线一星期就被用户要求加“停止生成”按钮。这是产品级的硬需求。不要跟后端抢活。前端不要自己做 RAG检索增强生成不要自己实现大模型调用逻辑。前端要做的是把后端暴露的 EventStream 处理好把渲染做顺。这也是很多新手最容易越界的地方框架不清晰后面协作成本极高。1.3 这个岗位的真实能力模型结合各厂招聘要求和我实际带人的经验我把 AI 应用前端的能力模型拆成四层层级能力要求典型工作内容基础层HTML/CSS/JS/TypeScript 扎实理解 React/Vue 的原理搭页面、写组件、状态管理、路由协议层熟悉 fetch 流式读取、SSE、WebSocket理解事件流对接后端接口处理流式返回与中断产品层能把 AI 特性翻译成交互设计懂得上下文、Token 成本设计对话框、Agent 工作台、知识库展示工程层会做性能优化、长列表渲染、错误恢复、日志上报应对长响应、并发请求、异常断线很多人学得慢是因为直接跳到第二层协议层没搞懂基础层又没打牢。三个月计划的第一步就是先把基础补到不用思考的程度再去碰流式传输。2. 三个月学习计划总览与工具选型三个月听起来不短但如果按天算你每天能投入的时间也就是三到四个小时。我按照这个时间盒做了一个拆分第一月打底第二月玩核心交互第三月做作品集和面试。每个阶段都有明确的输出物不是“学完就行”而是“学完能演示”。2.1 三个阶段的节奏设计与每日时间分配我把学习计划拆成了 12 周每周一个主题周末必须产出一个可跑通的小项目。下面是节奏表第 1 周TypeScript React 基础查漏补缺。别急着碰 AI 相关的内容先把状态管理和组件通信搞熟练。周末产出一个 TodoList要求用 useReducer 管理全部状态。第 2 周网络协议强化。学会 fetch、Axios、EventSource 分别怎么用重点把 ReadableStream 搞明白理解“流”是怎么在浏览器里工作的。周末产出一个小网页从后端拉取一个无限生成的文本流实时渲染到页面上。第 3 周Markdown 渲染与安全处理。学会用 markdown-it 或 react-markdown 渲染富文本再套上 DOMPurify 做安全清洗。周末产出一个“Markdown 预览器”除了渲染之外还要有代码高亮。第 4 周接触大模型 API。注册 DeepSeek、通义、Kimi 等任意一家的开放平台读懂接口文档用 Postman 跑通一次对话请求。周末产出一个命令行版的聊天程序能多轮对话能保存历史。第 5 周完成第一个完整 AI 对话框。把前三周的东西整合起来做出一个带流式输出、Markdown 渲染、代码高亮、中止生成的聊天页面。周末提交这个作品到 GitHub写清楚 README。第 6 周多轮对话与上下文管理。学会把历史消息传给大模型理解 system prompt 的作用前端维护消息数组与 token 计数。周末给聊天页面增加“清空上下文”“显示 token 用量”功能。第 7 周SSE 与 WebSocket 拉起。把第 2 周的流式拉取升级为 SSE 或 WebSocket学会处理断线重连、心跳包、手动中断。周末产出一个实时更新的数据看板。第 8 周Agent 界面初体验。理解 function calling 的基本流程前端展示 Agent 正在调什么工具、拿到了什么结果。周末做一个带工具调用展示的问答页面让用户看到 AI 从查询、检索到回答的完整链条。第 9 周知识库与文件上传场景。做一个带附件上传的对话框上传文件后进入知识库检索答案里要有引用来源的标注。周末做完整的前后端分离 demo。第 10 周性能优化与工程优化。处理长响应页面的卡顿问题用虚拟滚动渲染超长消息列表把打包体积控制在合理范围。周末重构第 5 周的聊天页面对比优化前后的性能。第 11 周做一个完整作品集项目。我建议选“AI 工作流助手”用户输入一句自然语言Agent 拆解成多个步骤并逐步执行。这个项目既有前端交互深度又有产品想象空间面试的时候非常压得住场。第 12 周面试题突击和模拟问答。把前 11 周学到的东西浓缩成十几条知识点当成口头表达练出来。本周末至少做两次模拟面试。每天的时间分配建议上午一个小时学新概念下午两个小时动手写代码晚上半小时记笔记和复盘。周末产出项目不要在学习周期内拖着不写代码只输入不输出三个月后一脸空白。2.2 技术栈选型为什么以 React TypeScript 为主线我接触过用 Vue、用 React、用 Svelte 做 AI 前端的团队各有各的优势但如果你想快速就业和上手我还是建议以 React TypeScript 为主线。原因很简单目前主流 AI 开源项目的前端脚手架绝大多数是 React 写的比如一些知名的对话 UI 库、Agent 工作台模板官方示例基本都有 React 版本社区生态最厚。TypeScript 更是必须的。大模型接口返回的数据结构非常灵活消息角色、工具调用参数、引用片段这些字段如果不用类型约束光靠记忆去写代码早晚要翻车。用 TypeScript 定义 Message、ToolCall、Citation 这样的模型编辑器就能帮你少犯一半的错误。组件库方面我推荐直接用 Ant Design 或 shadcn/ui不要自己在基础组件上浪费时间。但是要注意AI 应用的特殊组件流式文本、Token 统计工具、Agent 执行日志不要套现成的库自己包装更可控。前端组件库是“脚手架”不是“手脚架”产品差异化只能靠自己的封装能力。框架选型上如果你要做 SEO 友好的落地页选 Next.js如果你要做纯后台型工具用 Vite React 就够如果你有团队协作的工程化需求可以看看企业级框架或者内部脚手架。不要一上来就 Next.js它的服务端渲染对流式输出有额外的处理成本新手容易陷进去出不来。2.3 大模型 API 选型与对比学习期间要用到真实的大模型 API选哪家其实不是最重要的关键是理解接口规范。目前国内的主流大模型 API 大多兼容 OpenAI 的接口格式也就是说你学会了messages数组、stream: true参数、delta增量返回这套玩法换任何一家都只是换 base_url 和 key 的事。我给一个对比表格方便你按自己的需求挑厂商接口风格流式支持适用场景DeepSeekOpenAI 兼容好代码能力、中文推理性价比高通义千问OpenAI 兼容好国内生态好工具调用全面KimiOpenAI 兼容好长文本处理适合文档阅读类应用智谱 GLMOpenAI 兼容好国内部署方便Agent 能力不错OpenAI原生最好生态模板最多需要网络条件支持学习阶段我建议先开 DeepSeek 的 API注册即送少量额度文档简洁流式示例多。不要一上来就烧钱调大模型接口先用 mock 数据把前端流式渲染的架子搭好再切换到真实接口效率高得多。3. 第 1 个月打牢 AI 应用前端的地基第一个月是地基工程最枯燥但也最关键。我见过太多从第二个月开始学的人到了第三个月做项目时被 TypeScript 接口报错、状态更新时序、异步渲染这几个问题卡得足足一周。地基不打牢后面补起来更痛苦。3.1 本周目标与里程碑第一个月的目标是“能独立完成一个流式输出的聊天面板”。这个目标包含四个能力点状态管理不乱、网络请求会流式读、Markdown 渲染不崩、用户中止时请求能停。这四个点分别对应第 1 到第 4 周的学习内容。每周结束之后你产出的东西必须能在浏览器里跑起来。不要停留在“敲过一遍代码”的层面要真正理解每一行在干什么。我建议每天花十分钟口头复述一遍当天学过的知识点比如“为什么用 useReducer 管理消息数组而不是 useState”。讲得明白才是真的会了。3.2 必学的核心知识点流式请求、渲染 Markdown、状态管理先说流式请求。大模型接口返回的不是一个完整的 JSON而是多个用换行分隔的数据块。前端代码要做的事是把这些数据块通过fetch拿回来并且不断地读出来、渲染出来。核心代码如下const response await fetch(/api/chat, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify({ messages }), }); const reader response.body?.getReader(); const decoder new TextDecoder(); while (true) { const { done, value } await reader!.read(); if (done) break; const chunkText decoder.decode(value, { stream: true }); // 把 chunkText 按行解析提取 content 字段 onChunk(chunkText); }这里的重点有两个TextDecoder要指定stream: true否则多字节字符比如中文可能被截断成乱码reader.read()是异步的必须放在循环里持续读取直到done为true。很多人把 fetch 当 axios 那么用以为await response.json()就能拿到全量数据这是完全错误的。然后是 Markdown 渲染。大模型返回的文本默认带 Markdown 格式必须渲染成带标题、列表、代码块的富文本。直接用dangerouslySetInnerHTML是不可取的做法输出文本通常经过后端透传可能有脚本片段。正确做法是用解析库 安全清洗npm install react-markdown remark-gfm rehype-sanitizeReactMarkdown remarkPlugins{[remarkGfm]} rehypePlugins{[rehypeSanitize]} {assistantMessage} /ReactMarkdownrehype-sanitize会把script、iframe、onclick这些危险内容全部过滤掉。代码高亮可以再接一个rehype-highlight插件把代码块变成带高亮的precode结构。最后是状态管理。多轮对话天然是一个 reducer 模型因为消息的增删、修改、插入操作非常高频。用useReducer比useState更可控type Message { id: string; role: user | assistant | system | tool; content: string; createdAt: number; }; type ChatState { messages: Message[]; loading: boolean; error: string | null }; function chatReducer(state: ChatState, action: ChatAction): ChatState { switch (action.type) { case add_message: return { ...state, messages: [...state.messages, action.payload] }; case update_message: return { ...state, messages: state.messages.map((m) m.id action.payload.id ? { ...m, content: m.content action.payload.delta } : m ), }; case stop_generating: return { ...state, loading: false }; default: return state; } }注意update_message这个 action它不是覆盖整条消息而是把流式新拿到的delta追加到已有内容后面。流的本质就是“增量”状态管理的每一步也要跟着这个思路走。3.3 实操案例半小时搭一个带流式输出的聊天面板我第一次做这个 demo 大概花了半天主要踩在“流式增量追加”上面。给你还原一下最精简的实现方案一个输入框一个消息列表一个停止按钮。用户输入文字后前端先把用户消息 push 到消息列表然后请求后端接口拿到流式响应后把 AI 的回复追加到列表末尾。追加的方式是每条消息维护一个“正在生成”的标记流式数据来了就重新渲染那一条消息的内容。这里有个小技巧不要每次流式数据到达都更新整个数组否则长列表下会有严重性能问题。正确做法是只更新最后一条消息的 content 字段React 的 diff 机制会自动只重绘那一个节点。还用一个小技巧是加一个loading状态控制“停止生成”按钮的显隐。点击停止时调用AbortController.abort()中断请求const controller new AbortController(); async function fetchStream(messages: Message[]) { const response await fetch(/api/chat, { method: POST, signal: controller.signal, body: JSON.stringify({ messages }), }); // ... 流式读取 } function stopGenerating() { controller.abort(); }中断后axios 和 fetch 的表现不太一样fetch 的AbortController会抛出一个名为AbortError的异常。在异常处理里判断error.name AbortError从而静默结束流程不弹错误提示。这个细节非常影响用户体验我在实际项目里看到过不少团队没处理干净每次用户手动停止都会跳一个刺眼的报错弹窗。3.4 避坑指南第一个月最容易踩的坑我列几个高频的把响应一次性等完才渲染。这是传统接口思维留下的惯性必须强扭过来在阅读流式代码时就养成“边读边渲染”的体感。不做 Markdown 清洗。这是安全底线也会被测试轻易找出漏洞。所有从模型端拿到的内容一律按不可信数据对待。不用类型定义消息结构。多写几行 interface后面做 Agent 部分会省很多事。忽略 AbortError。没有捕获 AbortError用户手动中断后页面上会报错产品体验跌一半。在回调里直接改 state。React 的 state 是 immutable 的永远不要在循环或回调里直接messages[i].content xxx要用 reducer 或 setState 生成新数组。4. 第 2 个月解锁 AI 应用的核心交互第 2 个月开始学习重心从“技术上能跑通”转向“交互上真正好用”。这个阶段你会接触 Agent、知识库、上下文、功能调用等核心概念它们决定了你的 AI 应用前端是“好看的壳”还是“真正能落地的产品”。4.1 从聊天机器人到 AI Agent 的界面进化聊天机器人界面是一个对话框挨着一个对话框用户问一句模型答一句。Agent 应用完全不是这么回事。Agent 接到一个任务后会拆解成多个步骤先查知识库再调用工具再分步推理最后才组织答案。用户需要看到每一步的进展否则会觉得系统“卡死了”或者在“瞎编”。前端要做的是把 Agent 执行过程可视化。我迄今最受好评的方案是在消息气泡上方增加一个“执行流”区域用时间线卡片展示每一步的标题、状态进行中/成功/失败、耗时。Agent 在思考的时候展示一个动态的“思考中”状态调用工具时展示“正在调用查询工具”工具返回后再展示拿到结果的摘要。这个交互设计不是炫技。用户信任 AI 应用的前提是“可预期”看到执行过程他就能判断 Agent 是死是活、下一步会干什么。如果你做的 Agent 产品没有这块可视化我可以很负责任的讲用户吐槽率至少翻倍。4.2 Token 流式处理的三种实现方式第 2 个月会接触不同的流式传输协议我帮你把三种方式对比理清方式传输层前端 API适用场景Fetch 流式读取HTTPresponse.body.getReader()单次请求适合聊天场景SSE (Server-Sent Events)HTTPEventSource或fetch解析text/event-stream服务端主动推送适合实时状态更新WebSocket长连接ws.onmessage全双工通信适合复杂 Agent 交互聊天场景我最推荐用 SSE因为它是单向的服务器只管推前端处理逻辑最简单。WebSocket 虽然功能更强但要处理和重连心跳调试成本高一大截。SSE 的前端接入方式很简单。直接使用EventSource只能接收 GET 请求如果你要传消息内容通常会用 POST 请求加上流式读取的方式。我在实际项目里封装了一个通用的sseFetch函数async function sseFetch(url: string, body: any, onEvent: (event: any) void) { const response await fetch(url, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify(body), }); const reader response.body!.getReader(); const decoder new TextDecoder(); let buffer ; while (true) { const { done, value } await reader.read(); if (done) break; buffer decoder.decode(value, { stream: true }); // 按双换行分割 SSE 事件 const lines buffer.split(\n\n); buffer lines.pop()!; for (const line of lines) { if (line.startsWith(data:)) { const data line.slice(5).trim(); onEvent(JSON.parse(data)); } } } }这里的小坑是SSE 的数据块是按事件边界分割的但网络包可能把半个事件发过来所以定义一个buffer变量把未完成的数据留到下一轮再处理不然后面解析会经常出错。4.3 上下文管理与 Token 成本的可视化多轮对话的上下文管理是 AI 应用前端最容易忽略但影响最深的设计点。大模型每次请求都会携带全部历史消息token 数量越大响应越慢、费用越高还有“超出上下文长度”的报错风险。前端不管理上下文用户体验会直线下降。我在实际项目里维护了一套简单的上下文机制渲染层永远展示完整对话历史用户视角不受限。请求层默认携带最近 20 轮消息超过限额时自动移出最早的一批。在界面上展示当前对话的 token 估算值用一个进度条指示“已用 / 模型上限”。当 token 达到 80% 时前端提示“对话将超出模型上限建议开启新会话”。前端也可以做本地 token 估算一个 Unicode 字符约等于 1 到 2 个 token英文单词约等于 1 到 1.5 个 token。不用算得很精准只要给用户一个大致感知就行。很多成熟产品都在做这个交互比如自动截断上下文前会弹一个提示让用户确认是否保留关键信息这些细节能明显提升产品体验。4.4 实操案例做一个带文件上传和知识库引用的对话框第 2 个月的重头项目我建议做一个支持文件上传的对话框用户上传 PDF 或文本文件后对话框能结合文件内容回答问题答案里标注引用来源。整体交互链路是这样的用户上传文件 → 前端把文件交给后端 → 后端切片、embedding、存入向量库 → 用户提问 → 后端检索相关片段 → 把片段作为上下文传给大模型 → 大模型输出答案并在相关句子后标注来源索引 → 前端渲染答案时把索引渲染成“引用块”点击可查看原文片段。前端的主要工作有三块上传文件的进度管理与并发控制多文件上传一定要有队列不能一次性把所有文件打到后端对话消息里展示引用来源用可展开的卡片而不是一串看不见的索引号如果消息内容变长了直接用虚拟滚动列表否则页面会越聊越卡。虚拟滚动我推荐直接使用tanstack/react-virtual它比手写实现可靠得多长列表背景下渲染性能直上一个台阶。我在一个上千条消息的测试项目中实测过不开虚拟滚动的时候每次输入都会掉帧开了之后流畅度稳定在 60fps。5. 第 3 个月产品化与面试冲刺进入第三个月你的目标已经不只是“会跑 demo”了而是“能交付一个像样的小产品”和“能应对面试官的深挖”。这段时间是我见过成长最快但也是最容易焦虑的阶段因为突然发现要学的东西很多永远填不完。挑重点下手别贪多。5.1 架构设计与性能优化如果你只做了聊天页面那还撑不起“AI 应用前端工程师”这个头衔。要往完整项目里加三个维度才能体现你的工程能力可扩展性不同模型提供方走同一个适配层切换模型时只改配置不改业务代码。用策略模式写一个LLMProvider接口OpenAI 实现、DeepSeek 实现、通义实现各自封装。可维护性把网络层、渲染层、状态层拆开不要在一个组件里既写 fetch、又写 DOM、又写样式。至少拆成ChatPage、MessageList、MessageItem、StreamingHook四个模块。可观测性接入前端日志上报记录每次请求的耗时、Token 用量、流式中断原因、错误码。AI 应用的失败模式比传统应用复杂得多没有日志你根本不知道用户为什么卡住。性能优化上几个已经验证过的做法虚拟滚动处理超长消息列表对流的增量追加做防抖避免每毫秒触发 React 重渲染代码高亮不要同步做重计算通通用 worker 或者懒加载处理对于多模态内容图片、图表单独用懒加载组件渲染不要阻塞主消息流。5.2 面试准备高频题盘点面试官现在问 AI 应用前端的题目已经逐渐形成了一套相对固定的模式。我梳理了我在近期 AIGC 方向面试中高频出现的问题怎么实现流式输出核心回答点fetch ReadableStream TextDecoder边读边解析增量渲染。怎么处理流式传输中断核心回答点AbortController.abort()并在 catch 里识别 AbortError然后做状态清理。怎么保证渲染层安全核心回答点不用 dangerouslySetInnerHTML用 react-markdown rehype-sanitize 等白名单清洗方案。怎么管理多轮对话上下文核心回答点维护 messages 数组按需裁减历史前端做 token 用量可视化。怎么让 Agent 的执行过程可见核心回答点用执行流时间线组件展示 thinking / tool call / observation / result 状态。SSE、WebSocket、普通轮询怎么选核心回答点单向推送选 SSE双向交互选 WebSocket请求响应一次完事用普通 fetch。做过的某个 AI 项目里最大的坑是什么准备好一个真实案例讲清楚背景、踩坑过程、怎么排查、怎么解决。这块非常见实力比背八股文管用得多。遇到大模型输出的长文本前端怎么不卡顿核心回答点虚拟滚动 / 增量追加渲染 / 非阻塞代码高亮 / 后端按结构化分片返回。另外前端基础也不能扔像 useEffect 依赖数组的顺序、闭包陷阱、事件循环和微任务、JS 垃圾回收都是各厂面试必问。但前端的面试题每年都在变我强烈建议你准备完项目案例后把时间放在“把流式处理讲清楚”而不是“背诵更多 API 名称”上面。5.3 作品集项目如何打造作品集项目的包装直接决定面试官的第一印象。不要放五六个小 demo只放一个重点项目把它往深里做。我建议做“AI 工作流助手”因为它同时融合了对话、工具调用、执行可视化、上下文管理几个核心能力面试官怎么追问都问不出死角。思路是这样的用户输入一句需求比如“帮我查一下最新的前端就业趋势并总结成报告”Agent 会拆解成多个子任务依次调用搜索工具、文档工具最后汇总答案。前端要做三块任务拆解的可视化展示步骤卡片 状态流转、每步的工具调用的执行日志、最终长报告的分步渲染和 Markdown 格式化。这个项目做好里面天然包含了三到四个可深挖的亮点任务流状态渲染、接口并发与错误恢复、长文本分段渲染的性能方案、多工具调用时的 UI 反馈设计。面试时你可以把这几个点都提前准备好每种追问都能讲出细节。项目部署方面前端直接扔到 Vercel 或 Netlify 上免费托管后端可以用国内大厂提供的免费 API 额度这样运行成本几乎为零。如果是因为模型接口政策原因无法直接发布到公网也可以录一个演示视频本地跑给面试官看视频里把核心交互流程都录清楚面试官同样能感知到你的能力。6. 常见问题与避坑经验实录这部分是我这几天整理近期做项目时的复盘也是我认为这篇文章最不能错过的一部分。很多坑不是代码层面的而是在方案设计阶段就已经埋下来了。6.1 高频踩坑点只做前端不做 mock 服务。后端还在联调前端就干等着这是最常见的进度瓶颈。我建议前端先写好一套 mock 流式接口用 Node.js 起一个简单的 Server-Sent Events 服务前端开发不被后端阻塞一个 mock 服务半天就能搭好后面切换到真实接口最多半小时。不区分用户端和模型端时区。多轮对话的消息时间戳如果前端直接用new Date()用户换了时区就会乱。建议统一用Date.now()存时间戳展示时再转成用户时区字符串不要在 state 里存格式化后的字符串。请求并发无限制。用户快速连续点击发送前端会同时发出多个流式请求界面全部乱掉。上线前一概需要做并发锁当loading true时禁用发送按钮或者做一个任务队列阻止同时发送多个请求。流式渲染时整条消息重新渲染。每隔几十毫秒更新一个数组所有组件重新 render页面卡顿。优化方向是只让当前正在生成的 MessageItem 订阅“增量内容”其他消息不参与 diff。把 system prompt 直接暴露到前端。前端把系统提示词拼好、发给后端用户打开控制台都能看到。这不安全所有系统提示词必须放后端拼接前端只传用户消息。忽略错误状态的设计。流式中断了、请求超时了、后端返回非 200 了正常要有对应的 UI 反馈。每类异常我都预留了“重试”“回到上一轮”“清空上下文”三个操作按钮简单有效。6.2 常用问题速查表我把日常开发中可能遇到的情况整理成一张速查表方便你做项目时随手查阅现象可能原因快速排查思路流式输出中文乱码TextDecoder 没有加stream: true检查解码器参数用户点了停止但请求还在没有调用 AbortController.abort()检查停止按钮绑定的 handler生成的 Markdown 没有样式没有加载 markdown 样式表引入 github-markdown-css 或自己写样式消息列表越来越卡渲染了整条消息内容改用虚拟滚动 只更新增量节点Agent 状态一直转圈执行流事件没有与消息同步检查后端是否发送了status事件请求返回 401API Key 无效或过期检查环境变量和请求头确认 key 权限上传文件后对话无法引用知识库检索失败检查文件是否切片成功、向量库连接是否正常模型回答太短或直接空转上下文被裁减掉了关键信息检查发送给后端的历史消息是否被错误清理同一个问题回答结果时好时坏温度参数设得偏高调整 temperature 稳定范围比如 0.2~0.5打包体积超过预期额外引入了整个 markdown 渲染库按需加载插件用轻量级替代方案个人经验里我做项目最顺手的方法是“先让链路跑通再回头抠细节”。很多新手第一版就想着把所有功能都接上结果东修西补一周下来什么也没跑通。我一般会把全链路的第一步先打通一条消息从用户发出 → 到后端 → 到模型 → 再返回前端渲染出来。整个链路哪怕是最简陋的样子只要通了后面每加一个功能都是“锦上添花”而不是“从头再来”。三个月时间按照这个节奏走你会逐渐发现自己看 AI 应用产品的角度变了从前端工程师思维迭代成“产品与技术兼备”的复合型思维这对职业发展的加成是巨大的。