Agent Interaction UI
Agent Interaction UI 是 AI Agent 应用中所有用户交互界面的总称,包括 Chat UI、Tool Call UI、Approval UI、Artifact UI 和状态指示器。它不只是聊天框,而是 Agent 能力的完整可视化层。
#concept
#evergreen
#frontend
#ai
[!info] related notes
- 所属 MOC: AI Agent Application MOC
- 子组件: Chat UI, Tool Call UI, Human Approval UI, Artifact UI
- 框架: assistant-ui, Vercel AI SDK UI
Agent Interaction UI
一句话定义
Agent Interaction UI 是 AI Agent 应用中所有用户交互界面的总称。它不只是一个聊天框,而是包含消息流、工具调用状态、审批弹窗、产物查看器、进度指示器和错误提示的完整交互系统。
它解决什么问题
除了基础消息收发,Agent 交互还需要表达执行与授权状态:
- Agent 在执行过程中需要实时反馈(正在搜索、正在分析)
- 按权限与产品策略需要确认的操作,通过审批界面呈现具体动作、参数和影响
- Agent 生成的不只是文字,还有结构化产物(图表、代码、文件)
- 执行可能出错,需要错误恢复(重试、取消)
- 长时间执行需要进度指示;只能展示实际步骤或有依据的时间估计,不能用虚构百分比代替运行状态
核心原理
UI 组件全景
Agent Interaction UI
├── Chat UI (聊天界面)
│ ├── MessageList (消息列表)
│ ├── Composer (输入区)
│ └── ScrollAnchor (自动滚动)
├── Tool Call UI (工具调用状态)
│ ├── ToolCallCard (调用卡片)
│ └── ToolTimeline (执行时间线)
├── Approval UI (审批界面)
│ ├── ApprovalCard (审批卡片)
│ └── ParameterEditor (参数编辑)
├── Artifact UI (产物查看器)
│ ├── ChartViewer (图表)
│ ├── CodeViewer (代码)
│ ├── DataTable (表格)
│ └── FileViewer (文件)
├── Status UI (状态指示)
│ ├── StreamingIndicator (流式指示)
│ ├── ProgressIndicator (进度)
│ └── ErrorBoundary (错误边界)
└── Controls (控制)
├── StopButton (停止按钮)
├── RetryButton (重试按钮)
└── RegenerateButton (重新生成)
交互状态机
界面可以投影为 idle、running、waiting_approval、completed、failed、cancel_requested、cancelled 等状态。Streaming 与 tool calling 是执行中的活动,不一定是互斥的 run 状态。
- 连接断开表示暂时失去更新,不证明后台 run 已失败或取消。
- 点击停止先进入取消请求状态,收到服务端确认后再显示已取消。
- 审批必须绑定具体 run、动作和参数版本;编辑参数后要重新验证,不能沿用旧批准。
- 重试和重新生成可能创建新的执行,界面需要区分其身份,并避免重复副作用。
这些状态应来自服务端事件或可查询的持久状态;隐藏按钮不能代替服务端授权。
典型工程实现
组件组合示例
下面使用应用自定义的 useAgentViewModel 与展示组件说明组合方式;字段和状态不是 Vercel AI SDK 或 assistant-ui 的直接 API,集成时需做事件到 UI 状态的适配。
function AgentChat() {
const { messages, status, sendMessage, requestCancel, retry } = useAgentViewModel();
return (
<div className="agent-chat">
<MessageList>
{messages.map(msg => (
<Message key={msg.id}>
{msg.role === 'assistant' && msg.toolCalls?.map(tc => (
<ToolCallCard key={tc.id} toolCall={tc} />
))}
<TextContent content={msg.content} />
{msg.artifacts?.map(a => (
<ArtifactViewer key={a.id} artifact={a} />
))}
</Message>
))}
</MessageList>
{status === 'running' && <ActivityIndicator />}
{status === 'cancel_requested' && <StatusText>正在请求取消</StatusText>}
{status === 'waiting_approval' && <ApprovalCard />}
{status === 'failed' && <ErrorBanner onRetry={retry} />}
<Composer onSend={sendMessage}>
{status === 'running' && <StopButton onClick={requestCancel} />}
</Composer>
</div>
);
}
常见设计模式
1. 渐进式披露
默认只显示摘要,用户点击展开详情。
2. 上下文感知
根据 Agent 当前状态动态显示/隐藏组件。
3. 响应式布局
桌面端左右分栏,移动端上下排列。
常见坑
- 只做聊天框: 忽略了工具调用、审批、产物等交互需求
- 状态不同步: UI 状态和 Agent 实际状态不一致
- 不做错误边界: 一个组件崩溃导致整个界面不可用
- 移动端适配差: 审批卡片、产物查看器在手机上显示不全