Chat UI

Chat UI 是 AI Agent 应用的用户交互界面,负责消息输入、流式渲染、工具调用状态展示、审批交互和结果呈现。它不只是一个聊天框,而是 Agent 能力的可视化层。

#type / concept #status / evergreen #tech / frontend #tech / ai

[!info] related notes

Chat UI

一句话定义

Chat UI 是 AI Agent 应用的用户交互界面,负责消息输入、流式渲染、工具调用状态展示、审批交互和结果呈现。它不只是一个聊天框,而是 Agent 能力的可视化层。

它解决什么问题

AI Agent 的输出比传统聊天复杂得多:

  • 文本是流式到达的(逐字打字效果)
  • 可能包含工具调用状态(“正在搜索…”、“正在执行查询…”)
  • 可能需要人类审批(“即将删除 50 条记录,确认吗?”)
  • 可能包含结构化产物(图表、代码、文件)
  • 可能出错需要重试

一个简单的 <textarea> + <div> 无法满足这些需求。

核心原理

Chat UI 的组件结构

ChatContainer
├── ThreadList (会话列表,可选)
├── Thread (当前会话)
│   ├── MessageList (消息列表)
│   │   ├── UserMessage (用户消息)
│   │   ├── AssistantMessage (AI 回复)
│   │   │   ├── TextContent (文本内容,流式渲染)
│   │   │   ├── ToolCallCard (工具调用卡片)
│   │   │   └── ArtifactViewer (产物查看器)
│   │   └── SystemMessage (系统消息)
│   ├── Composer (输入区域)
│   │   ├── TextInput (文本输入)
│   │   ├── FileUpload (文件上传,可选)
│   │   └── SendButton (发送按钮)
│   └── ScrollAnchor (自动滚动锚点)
└── StatusBar (状态栏:token 用量、延迟等)

状态机

idle → streaming → done
                 → error
                 → cancelled
       waiting_approval → approved → streaming
                       → rejected → idle

典型工程实现

基于 Vercel AI SDK 的最简实现

import { useChat } from '@ai-sdk/react';

function Chat() {
  const { messages, input, handleInputChange, handleSubmit, isLoading, stop } = useChat();

  return (
    <div className="chat-container">
      <div className="message-list">
        {messages.map(m => (
          <div key={m.id} className={m.role}>
            {m.content}
          </div>
        ))}
      </div>
      <form onSubmit={handleSubmit}>
        <input value={input} onChange={handleInputChange} />
        <button type="submit">发送</button>
        {isLoading && <button onClick={stop}>停止</button>}
      </form>
    </div>
  );
}

基于 assistant-ui 的组合式实现

import { Thread, Message, Composer, ThreadList } from '@assistant-ui/react';

function AgentChat() {
  return (
    <AssistantRuntimeProvider runtime={runtime}>
      <ThreadList />
      <Thread>
        <Message>
          {/* 自定义消息渲染 */}
          <TextContent />
          <ToolCallCard />
          <ArtifactViewer />
        </Message>
        <Composer />
      </Thread>
    </AssistantRuntimeProvider>
  );
}

常见设计模式

1. 流式打字效果

文本逐字到达,前端逐字渲染。不是等全部文本到齐再显示。

2. 工具调用状态卡片

Agent 调用工具时,显示”正在搜索…”、“正在查询数据库…”等状态。工具完成后显示结果摘要。

3. 审批弹窗

高风险操作需要人类审批时,暂停流式输出,显示审批卡片。

4. 产物查看器

Agent 生成图表、代码、文件时,在消息内嵌入查看器。

5. 重试与重新生成

用户可以重试上一条消息或让 Agent 重新生成回答。

常见坑

  1. 不做流式渲染: 等全部文本到齐再显示,用户体验差
  2. 工具调用状态不更新: Agent 在执行工具,但 UI 看不到任何反馈
  3. 自动滚动失效: 新消息到达后没有自动滚动到底部
  4. 不做消息去重: SSE 重连后消息重复
  5. 不做加载状态: 用户不知道 Agent 是否在工作

和其他概念的关系

参考资料

创建于 2026/6/30 更新于 2026/7/15