Skip to content

AI UI 怎么选:先看三类状态归谁管 ​

接到“给产品加个 AI 助手”的需求后,我最先搜的是聊天组件。

搜索结果里的 Demo 长得都差不多:左边消息、右边消息、底部输入框,回答还能流式吐字。直到真正列开发任务,我才发现自己问错了问题:我不是在选一套聊天气泡,而是在决定三类状态分别交给谁管理。

🎯 本文目标

读完你应该能:分清 UI 状态、对话状态和业务状态;看懂 Ant Design X、AI Elements、assistant-ui、CopilotKit 为什么不能只按“组件库”横向排名;最后用一份最小验证清单,判断候选方案是否值得继续投入。


一个 AI 操作,为什么会产生三类状态 ​

先不看组件库。假设我们在 CRM 中加入一个 AI 助手,用户对它说:

删除客户 A。

这句话进入系统后,会依次发生三件事:

  1. 聊天窗口显示用户消息,随后弹出“确认删除”按钮。
  2. AI 发起删除工具调用;用户确认后,对话等待工具返回结果。
  3. 服务端校验权限、删除客户记录,并写入审计日志。

它们看起来都发生在聊天窗口里,描述的却不是同一种状态:

状态它回答的问题在这个例子中
UI 状态界面当前长什么样?确认弹窗是否打开、结果卡片是否展开
对话状态这次 AI 交互进行到哪里?消息、工具调用、等待结果、停止与重试
业务状态现实业务中真正发生了什么?权限是否通过、客户是否删除、审计是否写入

同一件事还可能同时影响三类状态。工具返回“删除成功”,这条返回值属于对话状态;客户记录在数据库中消失,属于业务状态;页面把结果渲染成一张绿色卡片,则属于 UI 状态。

所以,区分它们的关键不是看数据最后出现在哪个页面,而是看它描述的是界面表现、交互过程,还是真实业务事实。

💡 三类状态不是三选一

它们会同时存在于一个 AI 应用中,也不要求放进三个独立的 Store。你完全可以用现成 UI 组件搭配自研对话状态,再连接自己的业务后端。选型真正要确认的是:UI 状态谁管?对话状态谁管?业务状态又由谁管?


第一类:UI 状态——页面“长什么样、怎么操作” ​

UI 状态包括输入框内容、附件预览、自动滚动、消息布局、思考过程折叠、代码块与引用来源的展示。它们大多只活在浏览器里,不决定 Agent 下一步做什么。

这一层常见的起点有:

  • Ant Design X:React 组件完整,包含 Bubble、Sender、Conversations、ThoughtChain、Sources 等;如果项目原本就在 Ant Design 体系里,视觉和交互接入成本低。
  • MateChat:面向 Vue 3 的组件方案,适合不想为了 AI 界面切换 React 技术栈的团队。
  • Deep Chat:基于 Web Component,官方定位就是 framework agnostic;React、Vue、Svelte、Angular 或原生页面都可以接。
  • AI Elements:基于 shadcn/ui 的源码组件集合,消息、输入框、推理过程、工具状态等组件会直接进入你的代码仓库。

这里有一个容易误判的点:“源码归我”不是更高一层的能力,而是一种交付方式。

AI Elements 用 CLI 把代码复制进项目,普通组件库则通过 npm 依赖提供实现。前者方便深度修改,但升级时需要自己处理差异;后者升级集中,但要接受公开 API 的边界。这个差异很重要,却不能说明谁更会管理对话状态。

⚠️ 第一个选型陷阱

不要把“组件源码复制进项目”理解成“消息状态也有人替你管理”。AI Elements 主要提供可修改的 UI 源码;官方示例仍使用 AI SDK 的 useChat 管理消息、流式状态、停止和重试。线程持久化、复杂分支以及业务操作,仍需要额外设计。


第二类:对话状态——一句回答从请求到落库怎么活 ​

对话状态是 AI 界面和普通表单真正分叉的地方。

一条模型消息不是一次性返回的字符串,而会经历:

text
submitted → streaming → ready
                    ↘ error

流里还可能交错出现文本、推理过程、工具调用和工具结果。用户点击停止、重新生成、编辑历史消息时,状态又会继续分叉。只用一个 messages 数组当然也能写,但你很快会在项目里长出一套没有名字的运行时。

这一层要重点看三个方案。

1. Ant Design X v2:已经不只是“纯 UI” ​

旧印象里,Ant Design X 只是 Bubble 和 Sender。这个判断在 v2 已经过时:官方把 useXChat、useXConversations、Chat Provider、XRequest 等能力放进了 @ant-design/x-sdk。

useXChat 会管理单会话消息及 loading / updating / success / error / abort 等状态,Provider 负责把不同后端的数据格式转换成它能消费的形状。也就是说,它已经覆盖了“UI + 基础对话数据流”。

但“有运行时能力”不等于“替你承包了所有运行时”。分支模型、持久化策略、复杂工具 UI 如何落库,仍然要按你的后端和版本逐项核对。

2. AI SDK useChat:无头的对话状态层 ​

AI SDK 的 useChat不规定页面长什么样,主要管理 messages、status、error、发送与停止等状态,并通过 transport 决定消息如何发给后端。

它适合两类团队:

  • 已经在用 Next.js / AI SDK,希望 UI 完全自己控制;
  • 使用 AI Elements,把“源码组件”和“对话状态”组合起来。

它的优势是链路直接;边界也很清楚:线程列表、长期持久化、复杂分支和应用侧权限,不会因为调用了一个 Hook 就自动完成。

3. assistant-ui:把对话本身当成产品 ​

assistant-ui 的核心不是一套漂亮气泡,而是 runtime 和围绕 runtime 组织的 primitives。官方状态模型直接包含 thread、message part、tool UI、branch 等概念;线程既可以只放内存,也可以接自己的数据库或托管服务。

如果用户会长期使用对话、切换多个线程、重新生成分支、依赖工具结果渲染,assistant-ui 的价值才真正出现。代价是你需要理解它的 runtime、adapter 和组件上下文,而不是把它当成“复制一个聊天页”来用。

💡 一句话区分

Ant Design X v2 更像“设计体系 + 基础会话 SDK”;AI Elements + useChat 是“源码 UI + 无头状态”;assistant-ui 则把线程、消息和工具 UI 组织成一套更完整的对话运行时。


第三类:业务状态——AI 不只回答,还要动手 ​

如果 AI 只负责回答问题,对话状态通常就是边界;一旦 AI 要操作页面,问题会立刻升级:

  • 它能读取哪些页面状态?
  • 它能调用哪些前端函数?
  • 删除、提交、付款这类动作由谁确认?
  • 工具执行了一半,页面卸载了怎么办?
  • UI 上看到的成功,是否真的与服务端事务一致?

这已经不是消息气泡能解决的问题,而是 Agent 与真实业务之间的权限和状态同步。

CopilotKit v2 的 useFrontendTool 就属于这一类能力:前端可以注册带参数约束的工具,Agent 调用时在浏览器执行 handler,还能为执行过程和结果提供自定义渲染。

它适合“AI 是产品操作入口”的场景,例如:

用户说“把延期订单筛出来,给金额超过 5 万的负责人发提醒”。AI 先读取当前筛选条件,再调用前端动作切换视图,最后提交一个需要确认的批量操作。

如果你的需求只是“文档问答”,引入这类应用框架会增加协议、权限和部署复杂度;如果核心需求就是“AI 操作应用”,继续用组件库手写动作桥接,也会逐渐造出一个不完整的应用框架。

⚠️ 第二个选型陷阱

“能渲染工具调用”不等于“能安全执行工具”。前者只是把参数和结果画出来;后者还包括权限、确认、幂等、失败恢复和审计。选型演示里至少要亲手跑一次失败和一次人工确认。


把方案放回同一张责任表 ​

这不是排名,而是一张“默认由谁负责”的起点表。项目版本和扩展能力会变化,真正落地时仍要用自己的需求验证。

方案UI 侧提供什么对话状态由谁管应用动作由谁管适合作为起点的场景
Ant Design X v2Ant Design 风格组件与 X SDKuseXChat 等基础会话能力,复杂状态按需补齐业务侧接入已使用 Ant Design 的 React 项目
MateChatVue 3 AI 交互组件结合项目的数据层设计业务侧接入Vue 3 AI 界面
Deep Chat可跨框架嵌入的 Web Component组件支持连接与流式,业务会话仍需设计业务侧接入跨框架嵌入、快速原型
AI Elements + AI SDK可直接修改的源码组件AI SDK useChat 管消息、状态和 transport业务侧接入Next.js / AI SDK 技术栈
assistant-ui可组合的聊天 primitivesruntime 管线程、分支和工具 UI,可接持久化 adapter通过 tool / adapter 接入对话本身就是核心产品
CopilotKit聊天与生成式 UI与 Agent 运行过程协作Frontend Tool 连接应用动作AI 要直接操作业务应用

你会发现,一个方案可以横跨多列,并不存在整齐的“第一层、第二层、第三层”。库是能力组合,状态归属才是稳定的比较坐标。


我会怎么选:先砍需求,再看技术栈 ​

场景一:现有后台加一个知识问答侧栏 ​

优先保留现有设计体系。React + Ant Design 可以先看 Ant Design X;Vue 可以先看 MateChat;跨框架嵌入可以验证 Deep Chat。此时别急着上 Agent 应用框架,因为核心状态仍是“问答”。

场景二:要做一个长期使用的 ChatGPT 类产品 ​

先验证线程持久化、消息分支、工具 UI 和流中断,而不是先挑主题色。assistant-ui 值得优先做 spike;如果团队已深度使用 AI SDK,也可以用 AI Elements + useChat,但要明确哪些高级对话状态由自己补。

场景三:AI 要读页面、改表单、执行操作 ​

先设计权限与确认流程,再看 CopilotKit 这类应用框架。这里最贵的不是 UI,而是“模型建议”和“真实副作用”之间那道闸门。

场景四:公司只是需要一个内部 AI 入口 ​

先确认你是不是根本不该选库。LibreChat、Open WebUI、LobeChat 这类完整应用与组件库不是同一类东西;如果品牌定制和业务嵌入都不重要,直接部署成品可能比开发更合理。


最小选型验证:不要只跑 happy path ​

我会给每个候选方案接同一个假后端,然后依次做下面六个动作:

验证动作真正在测什么
流式回答到一半点击停止状态是否能从 streaming 正确收口
让下一段流返回错误错误属于消息、请求还是整个线程
对历史问题重新生成数据是简单数组还是可表达分支
切换线程后再切回来运行状态和草稿是否串线
工具调用返回结构化结果能否稳定映射到业务组件
工具执行前要求确认是否有真正的动作治理边界

六个动作跑完,答案通常比 stars、官网截图和功能清单诚实得多。某个方案缺能力不一定要淘汰,关键是你是否愿意长期拥有那部分状态。

🔍 评审时可以直接问的四句话
  1. 页面刷新后,线程和未完成消息从哪里恢复?
  2. 后端事件格式变化时,改 adapter、改 runtime,还是改所有组件?
  3. 同一条消息出现多个回答分支,数据模型是否表达得出来?
  4. AI 调用有副作用的工具时,谁负责确认、幂等和审计?

结语:选库,本质是在分配长期责任 ​

AI UI 的 Demo 很会制造错觉:只要气泡能流式吐字,产品就完成了大半。

真正进入迭代后,工作量会沿着三条线长出来:UI 状态决定界面是否好用,对话状态决定产品是否稳定,业务状态决定 Agent 是否真的能安全做事。

所以我现在不会先问“哪个 AI 组件库最好”,而会先把需求写成一句更具体的话:

这三类状态,哪些由库长期负责,哪些由团队自己长期负责?

选型没有免费的能力。你少写的每一段代码,都会变成一个需要理解的框架约定;你拒绝的每一个框架约定,也会变成团队需要维护的状态机。边界想清楚,比榜单上的第一名更重要。


📚 核对范围与官方资料
  • 本文为选型方法论与公开文档调研,不是完整性能横评;未声称对所有方案做过生产实测。
  • Ant Design X:组件总览、X SDK、useXChat 与 v2 迁移文档。
  • assistant-ui:官方 Runtime、Threads、Branching Response 与 Tool UI 文档。
  • Vercel:AI SDK useChat、Transport 与 AI Elements 官方文档。
  • CopilotKit:v2 useFrontendTool 官方文档。

原创声明

本文首发于我的个人博客。如需转载请注明作者及 原文链接。

👀 本文阅读 ··· 次

基于 VitePress 构建

本站总访问量 ··· 次·访客数 ··· 人