← 返回文章列表
所属专题:架构之道

AI 场景助手的前端架构现实主义演进

更新于 2026-06-30年份:2026字数:3,600阅读时长:11 分钟

AI 产品的前端架构,早已不是把 UI 画得漂亮、把组件分得干净——而是一场关乎体验连续性、业务吞吐效率与系统确定性的系统性战役。

TL;DR · 核心结论

  • 1务实底座:Vue3 + Vite;全局 Store 只留基础状态,聊天/流式/语音逻辑下沉 Composable;Axios 拦截器透明处理 Token、traceId、加解密。
  • 2对话核心:fetch-event-source SSE 三层解耦——通信层、协议解析层、呈现层职责分明,隔离模型侧协议抖动。
  • 3扩展与防御:Intent 统一契约复用会话链路;TTS/埋点 App 原生与 H5 双轨降级,边缘场景稳定性决定用户感知。

架构之道 · AI 旅行助手前端

3
大支柱
3
层解耦
意图驱动
多端降级

在 AI 浪潮席卷产品设计的前沿,前端架构的内涵早已悄然蜕变。它不再是单纯把 UI 画得漂亮、把组件分得干净,而演变成了一场关乎体验连续性、业务吞吐效率与系统确定性的系统性战役。

本文聊的"AI 场景助手",不是实验室里的理想模型,而是一个在资源受限、需求狂飙、多端环境错综复杂的真实业务泥潭里,连滚带爬摸索出来的实战型架构。我们不谈空中楼阁的"完美设计",只聊如何在"稳定交付、丝滑体验、无限扩展"的既定约束下,跳好一场务实的踢踏舞。

场景挑战

现场:多端场景下的"硬核"挑战

作为一款深度嵌入宿主 App 的 AI 场景助手,它一出生就要面对极其刁钻的生存环境:

旅行场景 · 硬核挑战

三大生存压力

网络波动 · 功能密度 · 宿主环境

#挑战维度场景描述 & 架构要求
1网络极其不稳定用户可能在地铁、机场、甚至是信号微弱的户外。系统必须对网络波动、流式数据断联、UI 频繁重绘有极高的容错率。
2功能密度高、跨度大实时语音翻译、双向对话翻译、图像场景识别、日程规划推荐……这些功能不是孤立的页面,产品要求它们在同一个会话上下文中无缝流转。
3宿主环境复杂它既要能作为独立 H5 跑在浏览器里,又要通过 window.HostBridge 原生桥接、稳如泰山地嵌入宿主 App。

面对这碗"硬菜",我们团队达成了三点共识作为架构的底色:

架构底色 · 三点共识

流式协议 · 意图驱动 · 多端兼容

面对复杂业务环境,团队达成的架构共识

架构支柱设计与实现要点
1流式协议
以流式协议为交互心脏,SSE 长连接管理连接的建立、维持、中断与异常销毁
2意图驱动
intent + query + files 统一请求契约,所有能力复用同一条聊天通道
3多端兼容
独立 H5 与宿主 App 原生桥接并存,TTS/埋点双轨降级应对复杂环境
务实底座

务实的底座:不盲从、不包揽

在技术选型上,我们选择了 Vue3 + Vite。这很常规,但足够轻快、生态成熟。

真正让我们纠结过的是状态管理。在很多人眼里,大厂架构就该把所有状态塞进 Pinia 这样的全局 Store 里。但我们偏不。我们选择了一种极具"现实主义"的做法:只把全局通用的基础状态留给 Store,而将聊天主状态、输入态、流式加载态等与交互强相关的逻辑,全部"下沉"到 Composable(组合式函数)和页面局部状态中。

架构师大白话:

在业务一天三变、功能频繁迭代的开荒期,如果把所有交互细节都抽象成全局 Store,很快就会因为模块间盘根错节的依赖,陷入"动一发而动全身"的维护噩梦。通过 Composable 封装诸如"对话流控制"、"语音录制状态机",既实现了逻辑的干净复用,又把变量的生命周期死死掐在组件内部,变更成本极低。

在基础设施层面,我们用 Axios 统一了网络请求管道,并在这个管道上横向切了一刀,把以下硬核能力做成了透明的拦截器:

  • Token 自动注入:业务同学无需手动拼接鉴权头
  • traceId 全链路追踪:一次请求从发起到渲染可串联排查
  • 防重复提交:关键写操作在网关层前被拦截
  • 请求/响应加解密:安全能力对上层完全透明

业务开发同学只需要关心接口数据,剩下的安全和链路追踪,架构在底层全包了。

三层解耦

对话能力的核心:三层解耦的"内容交响乐"

AI 产品的灵魂在于"对话"。如果把大模型的输出单纯当成一串"蹦字"的文本流,那是把架构做窄了。我们将对话交互抽丝剥茧,拆解为职责泾渭分明的三层结构:

对话交互 · 三层解耦架构
┌─────────────────────────────────────────────────────────────┐
│ 1. 通信层 (fetch-event-source) → SSE 长连接与连接生命周期      │
└─────────────────────────────────────────────────────────────┘
                              │ (原始数据流)
                              ▼
┌─────────────────────────────────────────────────────────────┐
│ 2. 协议解析层 (Protocol Parser) → META / Chunk 分片协议拆解   │
└─────────────────────────────────────────────────────────────┘
                              │ (结构化卡片/文本)
                              ▼
┌─────────────────────────────────────────────────────────────┐
│ 3. 呈现层 (UI Render) → Markdown + 动态业务卡片 (行程/景点)    │
└─────────────────────────────────────────────────────────────┘

3.1 通信层:告别原生的脆弱

我们放弃了原生的 EventSource 和 WebSocket,选用了 fetch-event-source 库通过 SSE(Server-Sent Events)方式接入。它既有流式的实时性,又完全兼容 HTTP 协议的各种配置(比如支持自定义 Header)。通信层只干一件事:管理连接的生死,管它建立、维持、中断(Abort)还是异常销毁,给上层提供一条清爽的数据管道。

3.2 协议解析层:最具有战略眼光的一着

我们把大模型的输出,定义为"可编排的内容流"。前端会显式解析 STREAM_META(元数据)、text_chunk(文本碎片)和 card_chunk(推荐卡片分片)等多种自定义协议。大模型吐出的不仅仅是字,还可能是结构化的指令。这一层完美隔离了模型侧协议的抖动,无论后端大模型怎么换、字段怎么变,在这里都被洗成前端认识的标准化数据。

3.3 呈现层:让表达形式各得其所

在这里,Markdown 语法与我们自定义的业务卡片(如动态行程单、景点推荐小卡片)混合编排、即时渲染。

意图驱动

意图驱动:如何把乱成麻的功能拧成一股绳

同传、翻译、查行程、看场景……如果每个功能开一个页面,用户会迷失在无尽的菜单跳转里,研发也得针对每个功能写一套会话管理。

我们的破局点在于引入了 Intent(意图驱动)机制。在业务视角下,无论用户是在敲字、在说英文、还是在拍一张路牌,在底层都被抽象成统一的请求契约:

{ intent: string; query: string; files?: File[] }
intent: live_interpretation

用户点「实时语音翻译」

intent: image_scene_recognition

用户拍照片,触发图像场景识别

intent: policy_consultation

政策咨询等新业务,只需加枚举与卡片组件

所有能力全部复用同一条聊天通道和流式基础设施。新业务上线,前端研发只需要在枚举里加个类型,写一下专属的卡片渲染组件,剩下的会话状态管理、重试逻辑、流式解析全套现成"样板房"直接拎包入住。这才是真正的架构复用效率。

防御性设计

现实主义的防御性设计:多端协同与语音管线

真实的工程世界里没有标准答案,只有"看菜吃饭"。

以语音输出(TTS)为例,我们在架构上同时接入了三种路径:

HTTP 静态 TTS

纯 H5 环境下的基础路径,网络一般时的可靠降级

WebSocket 流式 TTS

网络良好时的实时音频,低延迟体验

App 内优选

原生 App TTS

App 内走 Bridge 桥接,获得最完美的音频权限和底噪控制

这看起来有点冗余,但恰恰是应对复杂环境的"现实主义生存智慧"——在 App 内,走原生桥接能获得最完美的音频权限和底噪控制;在纯 H5 环境下,根据网络好坏动态在流式和静态音频之间降级切换。

同样,埋点与日志也采用了类似的"双轨制":App 内走 Bridge 借宿主能力上报,Web 端降级走常规 Beacon/XHR 方案。做 AI 产品,边缘场景下的稳定性,直接决定了用户是觉得它"真聪明"还是"人工智障"。

自我审视

架构的自我审视:当下的痛点与明天的路

坦率地说,在业务野蛮生长的阶段,为了快,我们也留下了不少"成长的代价":

聊天页面超 2000 行

核心聊天页面的组件已经突破了 2000 行,代码编排开始变得臃肿

双 UI 库并存

Element Plus 和 Vant 双 UI 库并存,带来了样式冲突和打包体积的负担

i18n 未启用

国际化基础能力虽然铺好了,但运行时为了赶进度依然固定成了中文,属于"枪已擦亮,发令枪未响"

系统已经成功跨越了"从无到有"的草莽期,正站在"从可用走向可治理"的十字路口。基于构建一个"严谨、可信、优雅"的系统,我们下一阶段的目标很明确:

全链路可观测

围绕消息发送、首字节时间(TTFB)、流式渲染完成、用户主动中断等关键节点建立统一事件打点,让 traceId 贯穿到流式渲染层

复杂度外科手术

把那两千多行的聊天页面,精准拆解为会话编排、消息渲染、输入控制、语音管线四个子域,并为协议解析等核心逻辑补齐单元测试

安全与配置收敛

清理通过 URL Query 传递 Token 的野路子,收敛配置文件加载策略;针对大模型和 Markdown 动态渲染构建严格白名单 Sanitize,把 XSS 风险锁死在摇篮里

结语

结语

这个"AI 场景助手"的前端架构,没有什么惊天动地的自研框架,也没有炫技式的复杂概念。它的价值恰恰在于清醒——精准识别了 AI 能力在前端落地时的痛点,然后在流式协议、意图驱动、多端兼容这三个支柱上扎扎实实地做好了防御性设计。

在理想的桃源与残酷的现实之间,找到那条能让业务跑得最稳、最快的路,这就是我们前端工程里的现实主义。

本文属于 无魔法工程流派 的第 8 篇肉身实战。

阅读时长:11 分钟


文档信息

版权声明:自由转载-非商用-非衍生-保持署名(CC BY-NC-ND 3.0)

原文链接:https://yijinlee.com/articles/article-58

作者:李奕锦

商业用途或修改衍生请联系授权。


李奕锦
李奕锦

全栈工程师,业余马拉松选手。

TL;DR

  • 务实底座:Vue3 + Vite;全局 Store 只留基础状态,聊天/流式/语音逻辑下沉 Composable;Axios 拦截器透明处理 Token、traceId、加解密。
  • 对话核心:fetch-event-source SSE 三层解耦——通信层、协议解析层、呈现层职责分明,隔离模型侧协议抖动。
  • 扩展与防御:Intent 统一契约复用会话链路;TTS/埋点 App 原生与 H5 双轨降级,边缘场景稳定性决定用户感知。
Tags:Vue 3ViteComposableSSEfetch-event-sourceIntent 驱动Axios 拦截器多端桥接

参考文章:相关链接

权威引文 · 官方文档 · 站内深度文

  1. Agent 产品概念,避免前端架构过度理想化。

  2. AI UI 状态与流式消息模型,场景助手前端可对照。

  3. 助手体验的流式前置条件。

  4. 从可跑 Demo 到现实主义架构的对照。

该专题下的阅读路径

系统设计原则 → 工程化实践 → 技术选型与重构

常见问题 FAQ

Q1. 为什么不把所有状态都塞进 Pinia 全局 Store?
在业务频繁迭代的开荒期,全局 Store 容易因模块间依赖陷入"动一发而动全身"。聊天主状态、输入态、流式加载态等与交互强相关的逻辑下沉到 Composable,变量生命周期绑定组件,变更成本极低。
Q2. 对话交互为什么要拆成三层?
通信层只管 SSE 连接生死;协议解析层将 STREAM_META、text_chunk、card_chunk 等洗成前端标准结构;呈现层负责 Markdown 与业务卡片渲染。模型升级动第二层,UI 改版动第三层,网络优化动第一层,互不连锁崩塌。
Q3. 什么是 Intent(意图驱动)机制?
无论用户敲字、说英文还是拍照,底层统一抽象为 intent + query + files 请求契约。实时语音翻译、图像场景识别、政策咨询等能力复用同一条聊天通道与流式基础设施,新业务只需加枚举类型和专属卡片组件。

发表评论

分享你的想法和反馈

支持 Markdown 格式

0/5000