
我最近在给团队搭一个内部 AI 问答助手第一步就卡在聊天界面的技术选型上。网上搜了一圈被提到最多的两个方案就是 ChatUI 和 Ant Design X。一个算是阿里系的老牌对话界面组件库一个是 Ant Design 面向 AI 场景推出的新组件库。不少文章把它们当成“旧版 vs 新版”来对比实际上手跑了一遍才发现这俩从设计目标开始就不是同一个物种选型结论自然也完全不同。这篇不打算复述官方文档。我想从真实接入的角度把两个库的核心定位、消息模型、定制边界、流式处理、移动端适配和工程化体验拆开来讲最后结合我的实际项目给出选型建议。如果你也在为“聊天窗口到底用哪个 UI 库”纠结这篇文章应该能帮你省下不少试错时间。1. 两个库看起来都做聊天出发点差了十万八千里1.1 ChatUI把“聊天气泡”这一件事做到极致ChatUI 当初的设计目标非常聚焦给对话式交互提供一个开箱即用的 React 组件库。它的核心概念就是 Chat、Bubble、Composer 这一套东西对应到界面就是消息列表、气泡和输入区。组件本身就内置了 text、image、file、audio、video、system、typing 这些常见的消息类型开发者只要按约定把消息数据传进去一个看起来还不错的聊天窗口就出来了。我印象最深的是它的 useMessages 这个 hook它把消息列表的增删改、打字中状态都封装好了。最初跑通一个最简单的问答界面拢共写了不到 50 行代码。对于“只要一个聊天窗口不想关心别的”的场景ChatUI 确实是效率最高的选择之一。但 ChatUI 的边界也在这它关注的是“对话框内部”你的产品如果有欢迎页、推荐问题、思维链这类 AI 应用特有模块它帮不上什么忙需要自己用别的组件拼。1.2 Ant Design X从欢迎页到思维链覆盖整个 AI 交互链路Ant Design X 的定位不是“聊天 UI 组件库”而是“AI 原生应用的前端解决方案”。这一点从它的组件矩阵就能看出来除了 Bubbles气泡列表还有 Welcome欢迎页、Suggestion推荐建议、Prompt提示词编辑器、ThoughtChain思维链、Attachment附件、Voice语音以及做全局配置的 XProvider。我用 X 做第一个 Demo 时的直观感受是它不是在帮你拼一个“聊天窗口”而是在帮你搭一个“完整的 AI 产品页面”。比如用户进来先看到一个 Welcome 页面下面有几个 Suggestion 推荐问题点了一个进入对话回答过程中有一个 ThoughtChain 展示当前 AI 思考到哪一步了聊到需要多模态时还能接 Attachment 和 Voice。这套链路如果完全用普通组件硬拼工作量要比 ChatUI 场景大得多。另外 X 提供了 useXAgent 和 useXChat 这两个 hooks专门处理 AI 流式对话的状态管理。这是 ChatUI 完全没有的层次后面的章节我会专门拆开讲。1.3 定位差异直接影响选型结论很多人把 Ant Design X 当成 ChatUI 的“升级替代版”这是一个很常见的误判。ChatUI 是一个部件Ant Design X 是一个框架层级的东西。如果你的场景只需要一个对话窗口引进 X 会显得有点重而且它的优势模块你根本用不上反过来如果你在做一个完整的 AI 产品只用 ChatUI 会发现自己要在系统层面补非常多东西。我后来用一个类比跟团队解释ChatUI 类似一套成品厨房柜主要管“做菜区域”Ant Design X 则是一套整屋装修方案从玄关到阳台都给你出了图。选型的第一步不是比谁的柜门好看而是想清楚你是在装修一个厨房还是在盖整栋房子。2. 消息模型和渲染机制是选型的核心分水岭2.1 ChatUI 用 type content 的协议驱动渲染ChatUI 的每个消息对象长这样{ type: text, content: { text: 你好我是智能助手 } }消息列表就是一个这样的数组。组件内部根据type去匹配不同消息类型的默认渲染逻辑。如果默认渲染满足不了业务ChatUI 留了一个自定义渲染器入口renderMessageContentChat messages{messages} onSend{handleSend} renderMessageContent{(message) { if (message.type product) { return ProductCard data{message.content} /; } return null; }} /这种设计思路是数据层保持简单所有复杂展示放在渲染器里做。业务上要做商品卡片、图文混排、订单状态这类定制消息时自定义一个 type在渲染器里写对应组件就行。它本质上是一个“消息协议 渲染分发器”的架构。不过它的自定义渲染器并不带样式隔离所有自定义内容需要你自己布局。用久了你会发现它给你的是“消息级”的自由但不是“组件级”的集成方案。2.2 Ant Design X 用 items 和 hooks 组织整个对话流Ant Design X 的核心呈现组件是 Bubble批量渲染用Bubble.Listimport { Bubble, Suggestion, XProvider } from ant-design/x; XProvider Bubble.List items{[ { key: 1, role: user, content: 帮我总结一下今天的会议 }, { key: 2, role: assistant, content: 好的我来处理。 }, ]} / /XProvidercontent可以传字符串也可以是任意 ReactNode。气泡的角色、头像、样式都通过roles或styles定制。这个模型对“复杂内容”更开放——你不用先在数据层定义 type直接在content里塞一个ProductCard /就行。更关键的是官方推荐配useXAgent和useXChat实现整个对话状态流const [agent] useXAgent({ request: async ({ message }) { // 在这里调用后端支持流式 }, }); const { onRequest, messages } useXChat({ agent }); // 发送消息 onRequest({ message: 你好 });useXChat负责维护消息列表agent负责和模型方通信。消息的发送、回复、更新、结束都在这一套状态机制里流转。相比 ChatUI 手动appendMsgsetTyping的方式X 把“对话生成”当成一个生命周期来管理更适合复杂的 AI 交互。为了看得更清楚我把流式接收在不采用高层封装时的样子写出来const [agent] useXAgent({ request: async ({ message }, { onUpdate, onSuccess }) { const response await fetch(/api/chat, { method: POST, body: JSON.stringify({ message }), }); const reader response.body.getReader(); const decoder new TextDecoder(); let content ; while (true) { const { done, value } await reader.read(); if (done) break; content decoder.decode(value, { stream: true }); onUpdate(content); } onSuccess(content); }, });这一段是我实际项目里直接用过的骨架后面讲踩坑时还会回到它。2.3 两种消息模式对应两种开发心智ChatUI 的心智是“消息是我定义的我控制怎么渲染”Ant Design X 的心智是“整个对话交互是一个系统我在系统里挂载业务组件”。这个差异带来几个实际影响。首先ChatUI 适合消息形态多、但页面结构固定的业务场景因为它支持任意自定义消息类型其次Ant Design X 适合消息形态相对统一、但整体应用需要快速搭起来的场景因为它把链路都铺好了。最后如果你需要深度改样式ChatUI 要覆盖它的 CSS 变量或 Less 变量X 则直接走 CSS-in-JS 的 token 体系改起来更符合现代 React 团队的工程习惯。3. 实测下来的关键差异集成、定制、流式、移动端、体积3.1 集成速度ChatUI 五分钟跑通X 需要先接受它的世界观ChatUI 的接入成本确实低。装包、引入组件和 CSS创建 messages 数组再绑定 onSend一个能发消息、能展示回复的最小闭环就有了。它不要求你额外引入 antd也不强制你用某个状态管理方案对老项目非常友好。Ant Design X 这边官方要求 React 18 以上并且底层依赖 antd v5。如果你的项目当前还在 React 16 或者 antd v4升级就是一笔明面上的成本。而且 X 更希望你按照它的 XProvider、Bubble、useXChat 这套结构组织代码第一次用会有一个从“我调组件”到“我接入框架”的思维转换期。但一旦接顺了后面做欢迎页、推荐问题、思维链这些模块会非常快。说实话如果只看“从安装到跑通”的时间ChatUI 赢。但再看“从跑通到完成一个完整 AI 应用”的总时间X 通常是反超的。3.2 自定义消息卡片ChatUI 用渲染器X 直接交给 ReactNode我在两个库里都实现了一个“商品推荐卡片”的业务消息。ChatUI 的做法是先给数据加一个自定义 type{ type: product, content: { id, title, price } }然后在renderMessageContent里加一个 switch 分支返回商品卡片组件。消息一多分支也变多需要维护一个“消息类型 → 渲染函数”的映射关系。Ant Design X 的做法更简单在获取到模型结果后直接把ProductCard data{...} /作为 content 塞给对应气泡。它有赖于“服务端返回结构化数据后由前端映射成 ReactNode”这一套思维。在 X 里单个气泡的渲染就是 ReactNode天然可以做富交互不需要碰消息协议。论极端灵活性ChatUI 的消息级协议在跨端、日志回放、消息持久化方面更有优势论写业务代码的速度X 直接塞组件明显更爽。3.3 流式输出体验setTyping 与 onUpdate 的差别ChatUI 对“AI 正在输入”的原生模拟是 setTyping 和 typing 类型的消息。你需要自己控制时序先 setTyping(true)等异步结果回来后 appendMsg 追加完整消息再 setTyping(false)。好处是直观、好理解坏处是所有增量逻辑都要自己维护尤其是处理“打字中”状态和最后消息替换的边界时很容易在时序上出小 bug。Ant Design X 的流式更彻底。agent 的onUpdate可以不断更新当前生成中的消息内容界面上的气泡会跟着平滑变化。配合onSuccess/onError收尾整个生成生命周期是框架托管的。做惯了大模型应用的团队会觉得这套流程非常“对味”。但要提醒一点X 的这种流式能力是有前提的后端必须支持真正的流式输出或者你至少要在前端正确处理 ReadableStream。如果后端只是普通 JSON 一次性返回那 X 的流式优势是发挥不出来的这时候用 ChatUI 也完全够。3.4 移动端与响应式ChatUI 天生友好X 需要自己做ChatUI 从一开始就考虑了移动端场景触控、滑动、安全区适配这些细节都有内置处理。做一个手机端客服聊天页它基本能直接顶上去。Ant Design X 目前的设计体系更偏桌面 Web组件本身是响应式的但移动端不是一个零成本的加分项你需要结合自己的媒体查询、viewport 处理去适配输入区、气泡宽度和顶部导航。如果你的核心场景在手机端这点在选择时要非常冷静地评估。我测过 X 在小屏幕下跑通业务流程没有问题但那种“顺手”感确实比 ChatUI 差一些。X 的组件更关注信息结构和交互链路而不是某一个通道的设备细节。3.5 包体积和与 antd 的耦合程度这一点很难绕开。项目里如果已经在用 antd v5那么 Ant Design X 的增量成本主要是它自己的组件代码体积增加在可接受范围内但如果项目是干净的 React 技术栈为了一个聊天窗口把 antd 全家桶引进来首屏体积会有肉眼可见的增长尤其是中后台表格、表单这类组件被打包工具一起带进来的时候。ChatUI 自身相对更独立体积控制也更好。它内置的消息类型和样式是裁剪过的不像 antd 那样需要维护一个庞大的组件体系。但换来的是如果业务里还需要 antd 的表格、弹窗、表单你得同时维护两套 UI 体系的风格统一。所以体积问题不能单独看两个库本身要看“它们进到你的项目里之后带来的总增量”。4. 一张表看清全部维度差异对比维度ChatUIAnt Design X定位对话式 UI 组件库AI 原生应用前端解决方案核心范围聊天窗口内部欢迎页、对话、建议、思维链、语音等全链路发布方阿里Ant Design 团队消息模型type content 协议items / ReactNode hooks自定义消息消息级渲染器自由扩展 type组件级 ReactNode直接嵌入流式输出手动 setTyping appendMsguseXAgent / useXChat 托管移动端适配内置支持较好偏桌面需自行适配antd 依赖独立依赖 antd v5、React 18学习成本低中等需要理解 AI 状态流长期维护更新节奏明显放缓社区活跃迭代快适用产品形态客服、IM、消息密集型聊天完整 AI 助手、知识问答、Agent 应用4.1 “谁更轻”不等于“谁更好”如果只是看接入速度和包体积ChatUI 确实占优。但很多项目最终放弃 ChatUI不是因为不好用而是因为产品演化到后面必然长出欢迎页、推荐问题、思考过程展示这些模块这些在 X 里是现成的在 ChatUI 的体系里需要重新拼装。我见过一个团队用 ChatUI 做了半年客服系统后来要升级成带“建议问题”和“对话摘要”的智能助手最后前端那一大坨自定义渲染代码重构了很久。不是说 ChatUI 扩展不了而是“对话外部”的东西它本就不管。4.2 维护活跃度是隐藏的选型成本ChatUI 的核心功能已经很稳定但 GitHub 上的 issue 和 PR 处理速度明显偏慢。社区里很多问题要靠自己翻源码解决。Ant Design X 更新很快新组件和新 API 一直在加但也意味着 API 还在演进生产环境接入时要做好版本锁定和升级计划。选型时一定要把“这个库未来一年会不会还有人维护”算进成本。如果是做生命周期很长的企业内部系统一个停滞的组件库带来的风险远比想象中大。5. 接入过程中的踩坑实录5.1 ChatUI 的自定义消息映射别写成一个巨型 switch我最初在 ChatUI 里加自定义消息时渲染器里写满了一个又一个 case。等到第八种消息类型的时候整个函数已经没法看了。后来我把消息类型拆成了一个映射表const messageRenderers { product: ProductMessage, order: OrderMessage, system: SystemMessage, }; const renderMessageContent (message) { const Renderer messageRenderers[message.type]; return Renderer ? Renderer data{message.content} / : null; };这样每种消息类型只维护自己的渲染组件代码清晰很多。如果你决定用 ChatUI强烈建议一开始就按映射表组织不要图省事堆 switch。5.2 Ant Design X 不会帮你渲染 Markdown这是我在 X 上遇到的第一个“坑”。Bubble 的 content 直接传一串 markdown 字符串渲染出来就是纯文本没有任何标题、加粗、代码块样式。原因很简单X 只负责气泡结构不负责内容解析。解决办法也不复杂自己接一个 markdown 渲染库即可import ReactMarkdown from react-markdown; Bubble content{ ReactMarkdown {# 标题\n\n正文内容} /ReactMarkdown } /如果你在 X 里要展示代码块、表格、链接预览最好尽早统一封装一个 “AI 回答内容组件”把 markdown、代码高亮、内部链接跳转全部收敛在一个地方。不然后面每个气泡都得改。5.3 流式请求的中断AbortController 必须自己接接 X 的流式输出时我最初只处理了 onUpdate 和 onSuccess忽略了取消逻辑。结果用户点击“停止生成”后前端消息是停了但后端请求还在继续跑浪费 token 不说下一轮消息还会串状态。后面我改成在 agent.request 里接收并传递 abort 信号const [agent] useXAgent({ request: async ({ message }, { onUpdate, onSuccess, signal }) { const response await fetch(/api/chat, { method: POST, body: JSON.stringify({ message }), signal, }); // 读取 reader 时同样监听 signal }, });这种做法虽然看起来只是加了一个参数但实际交互体验差别很大。用户中断生成后UI 层和请求层都能同步停下来不会出现“前端停了后端还在跑”的尴尬。5.4 版本兼容与升级风险ChatUI 的优势是很稳定但稳定也意味着陈旧。它的样式方案和一些内部实现带着早期 React 生态的影子如果你的项目用了最新的构建工具链CSS 加载顺序、主题覆盖之类的细节需要多点耐心解决。Ant Design X 则是另一个方向的坑升级太快。我踩过一次小版本升级后某个组件 props 调整导致类型报错的情况。锁版本、跟进 changelog、在预发环境跑一轮回归这些流程在 X 项目里不能省。6. 怎么选按产品形态、技术栈和维护预期来决策6.1 快速原型和内部工具如果只是做一个内部用的知识问答工具或者验证 AI 功能的 demoChatUI 是最快出效果的选择。它不需要你建立复杂的组件体系一个页面几十行代码就能跑起来改起来也快。6.2 完整的 AI 产品页面如果你的产品是一个对外发布的 AI 助手涉及欢迎页、推荐问题、思考过程可视化、多模态消息那 Ant Design X 的整体链路设计能帮你少走大量弯路。这些模块散着做光是样式统一和交互状态的衔接就够喝一壶。6.3 移动端优先或客服系统移动端优先、会话密集型、需要大量自定义气泡的场景ChatUI 可能更合适。它在消息类型扩展、移动端适配方面是经过生产验证的逻辑很成熟。6.4 深度定制型业务系统如果业务消息非常复杂每一条消息都对应不同的业务组件而且这些组件要和内部基建深度结合我的建议是分开看消息结构用 ChatUI 的类型协议思路做内容展示直接用 ReactNode 思维。这种场景下X 的高层封装反而可能碍事你最终会绕过它自己拼。6.5 我最后的选择和理由我在内部 AI 问答助手里选了 Ant Design X核心原因只有两条团队技术栈已经在 antd 体系内以及产品需要欢迎页、推荐问题、思维链这些完整链路。ChatUI 很好但它对“完整 AI 应用”的覆盖范围不够我不想在聊天区外面再维护一套风格独立的组件。但我也要强调如果换一个侧重移动端客服或者说重度自定义消息卡片的产品我大概率会回头用 ChatUI甚至直接基于它的消息协议自己封装一层。啰嗦了这么多最后说点我自己的体会。选 UI 库这件事最怕的就是抛开使用场景去看谁更先进。ChatUI 和 Ant Design X 都有非常明确的适用边界你的产品如果只是需要一个会话窗口ChatUI 的轻量和消息渲染器设计会让你很舒服如果你的产品是一个完整的 AI 应用欢迎区、建议提示、思维链这些是绕不开的那 Ant Design X 提供的完整链路价值就体现出来了。选型没有标准答案只有合不合适。判断小技巧也很简单先画出你的页面结构如果页面里除了聊天列表还有很多 AI 特有的模块那这题答案基本已经出来了。