Agent 时代的 UI_UX 革命:Generative UI 与动态交互界面
1. 标题选项
包含核心关键词,覆盖不同读者的内容需求
- 《Agent 时代 UI/UX 革命:从静态页面到 Generative UI 动态交互界面全指南》
- 《告别固定组件:Generative UI 如何重构下一代 AI 应用交互体验》
- 《从零上手生成式UI:打造能跟着用户需求实时变化的动态交互界面》
- 《AI Agent 标配交互方案:Generative UI 核心原理、落地实践与未来趋势》
2. 引言
痛点引入
你有没有过这样的经历:用ChatGPT问“怎么订下周三从北京到广州的便宜机票”,它洋洋洒洒给你列了5步操作指南,你还要手动打开OTA App,输入出发地、目的地、时间,再一个个对比价格;在企业后台用AI数据助手问“这个季度华东区的销售完成率”,它给你返回一堆文字和数字,你还要自己去报表系统筛维度、做图表,折腾10分钟才能拿到你要的可视化结果;用AI导购问“适合爬山穿的防水运动鞋,预算600以内”,它给你列了10个商品名称,你还要一个个复制名字去电商平台搜,对比参数和评价。
这就是当前AI时代最大的交互痛点:AI Agent的能力已经可以帮你完成查询、推荐、甚至业务操作,但交互层还停留在“纯文字/富文本输出”的阶段,相当于Agent明明能直接帮你把事办好,却只能口头告诉你怎么一步步自己做,操作路径断层、体验割裂,完全浪费了AI Agent的能力。
文章内容概述
本文将从核心概念、技术原理、落地实战、最佳实践四个维度,全面讲解Agent时代的交互革命方案——Generative UI(生成式UI)。你会搞懂什么是生成式UI、它和传统UI、对话式UI的本质区别,核心运行逻辑,然后我们会基于React + Vercel AI SDK + GPT-4o,从零搭建一个完整的生成式UI智能助手demo,包含动态图表生成、业务组件渲染、交互事件响应等完整能力,最后会分享生成式UI的落地边界、最佳实践和未来发展趋势。
读者收益
读完本文你将获得:
- 完全理解Generative UI的核心价值和适用场景,能判断自己负责的产品是否需要接入生成式UI
- 掌握生成式UI的技术实现原理,能独立完成最小可用demo的开发
- 了解生成式UI落地的常见坑和最佳实践,避免走弯路
- 看懂下一代UI/UX的发展方向,提前布局技术能力
3. 准备工作
技术栈/知识要求
- 熟悉React基础(Hooks、组件、Props、事件处理)
- 了解大语言模型的基本调用方式(API调用、函数调用/工具调用)
- 有基础的HTTP请求和异步编程知识
- 对UI组件库(如Ant Design)、数据可视化库(如Recharts)有基本了解
环境/工具要求
- Node.js 18.0+ 版本,包管理器npm/yarn/pnpm均可
- 一个OpenAI API Key(可在OpenAI官网申请,也可使用国内通义千问、文心一言等支持工具调用的大模型服务替代)
- 代码编辑器(推荐VS Code)
4. 核心内容:概念与实战
4.1 核心概念拆解:什么是Generative UI?
问题背景
随着AI Agent技术的快速发展,AI已经从“信息查询工具”进化为“可以完成复杂业务操作的智能体”:它可以调用你的消费数据、预订机票酒店、生成数据分析报告、甚至帮你操作企业后台的业务流程。但传统的交互模式已经完全匹配不上Agent的能力:
- 传统GUI(图形化UI):所有交互路径、页面组件都是产品经理和开发者提前写死的,用户必须按照固定路径操作,灵活性极低,无法适配用户多变的个性化需求
- 对话式UI:虽然支持自然语言输入,但输出还是以文字、富文本为主,没有可交互的操作入口,用户必须手动跳转其他页面完成操作,路径冗长,体验断层
这一矛盾直接催生了Generative UI的出现:我们需要一种能跟着用户需求动态生成、可直接交互的UI层,作为AI Agent的“交互出口”,把Agent的能力直接触达给用户。
概念定义
Generative UI(生成式UI) 是指由大语言模型根据用户的实时需求、上下文场景、历史行为数据,动态调用预先定义的UI组件,渲染出适配当前需求的可交互界面的技术方案。
和传统UI最大的区别是:传统UI的组件、路径、布局都是开发者提前写死的,而生成式UI的组件组合、布局、甚至部分功能都是AI根据当前需求动态生成的,不需要开发者提前定义所有页面路径。
三类UI的核心属性对比
我们用一个表格从多个维度对比传统GUI、对话式UI、生成式UI的区别:
| 对比维度 | 传统GUI | 对话式UI | 生成式UI |
|---|---|---|---|
| 交互路径定义 | 100%由开发者提前定义 | 部分路径由工具定义,其余靠用户手动跳转 | 完全由AI根据用户需求动态生成 |
| 灵活性 | 极低,只能走预设路径 | 中等,能处理简单查询类需求 | 极高,能适配任意个性化、非标准化需求 |
| 开发成本 | 极高,所有页面、路径都要开发 | 中等,只需要开发工具接口 | 中等,只需要开发通用组件和规则 |
| 用户学习成本 | 高,需要记住操作路径和入口 | 低,只要会说自然语言 | 极低,说出需求就能得到操作入口 |
| 可控性 | 极高,所有逻辑都可预判 | 中等,输出内容可控制 | 较高,组件是预先定义的,可加校验规则 |
| 响应速度 | 极快,本地渲染无额外延迟 | 中等,需要等LLM返回 | 中等偏上,流式渲染可大幅降低等待感知 |
| 适合场景 | 固定高频核心路径(登录、支付、首页) | 简单查询、问答类场景 | 需求多变的AI助手、数据分析、导购、客服场景 |
概念关系与架构
我们用ER图展示Generative UI和相关概念的关系:
生成式UI的核心运行逻辑可以用下面的流程图表示:
效率提升数学模型
生成式UI的核心价值是降低用户完成任务的时间和操作步数,我们可以用两个公式量化其效率提升:
- 操作步数减少量:
S=N传统−N生成式S = N_{传统} - N_{生成式}S=N传统−N生成式
其中N传统N_{传统}N传统是传统UI完成任务需要的操作步数,N生成式N_{生成式}N生成式是生成式UI完成相同任务需要的操作步数。以订机票为例:传统UI需要输入出发地→输入目的地→选择时间→点击查询→筛选航班→点击预订→填写乘客信息→提交支付共8步,生成式UI只需要说出需求→点击确认支付共2步,步数减少量S=6S=6S=6,减少比例75%。 - 时间效率提升率:
E=T传统−T生成式T传统×100%E = \frac{T_{传统} - T_{生成式}}{T_{传统}} \times 100\%E=T传统T传统−T生成式×100%
其中T传统T_{传统}T传统是传统UI完成任务的总耗时,T生成式T_{生成式}T生成式是生成式UI的耗时。同样以订机票为例,传统UI平均耗时约120秒,生成式UI耗时约20秒,效率提升率E=120−20120×100%≈83.3%E=\frac{120-20}{120} \times 100\% \approx 83.3\%E=120120−20×100%≈83.3%。
边界与外延
生成式UI不是“银弹”,也有明确的适用边界:
✅ 适合场景:
- AI智能助手、智能客服:用户需求多变,无固定操作路径
- 企业数据分析后台:用户需要灵活查询数据、生成报表
- 电商/本地生活导购:用户需求个性化,需要动态推荐和操作入口
- 低代码/无代码平台:让用户用自然语言生成需要的页面
❌ 不适合场景: - 核心固定路径页面:登录、支付、首页等对稳定性要求极高的场景
- 高性能要求场景:游戏、实时音视频等对延迟要求极低的场景
- 强合规要求场景:金融交易、医疗信息展示等需要100%可控的场景
4.2 步骤一:项目初始化与依赖安装
我们将基于Vite + React + Vercel AI SDK + Ant Design搭建生成式UI demo,Vercel AI SDK是目前最成熟的生成式UI开发工具,它封装了大模型调用、流式输出、组件调度等能力,不用我们自己写复杂的解析逻辑。
为什么需要这些依赖?
@ai-sdk/react:Vercel AI SDK的React封装,提供了useChat等Hook,简化生成式UI的开发@ai-sdk/openai:对接OpenAI大模型的适配器,也可以换成其他大模型的适配器antd:国内常用的企业级组件库,提供我们需要的卡片、按钮、表格等通用组件recharts:数据可视化库,用来生成图表组件dayjs:时间处理库,方便处理日期格式
安装命令
首先创建Vite React项目:
npm create vite@latest generative-ui-demo -- --template react
cd generative-ui-demo
然后安装所有依赖:
npm install @ai-sdk/react @ai-sdk/openai ai antd recharts dayjs
在项目根目录创建.env文件,配置你的OpenAI API Key:
OPENAI_API_KEY=你的OpenAI API Key
4.3 步骤二:创建你的第一个生成式UI组件
我们先实现最基础的功能:用户输入“看下我近30天的消费数据”,AI直接生成一个柱状图展示消费趋势,而不是返回文字数据。
核心逻辑说明
我们需要做三件事:
- 前端定义好可被AI调用的组件映射,告诉AI有哪些组件可用
- 后端定义好工具:包括获取消费数据的业务工具,和渲染消费图表的UI组件工具
- 配置
useChat的渲染规则,当AI返回组件调用指令时,渲染对应的组件
完整代码实现
首先创建前端主页面src/App.jsx:
// src/App.jsx
import { useChat } from '@ai-sdk/react';
import { Card, Button, Input, Typography, Spin } from 'antd';
import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
import dayjs from 'dayjs';
import 'antd/dist/reset.css';
const { Title, Text } = Typography;
// 1. 定义可被LLM调用的组件映射:所有生成的UI都必须是这里预先定义的组件
const componentMap = {
// 消费趋势柱状图组件
ConsumptionBarChart: ({ data }) => {
return (
<Card title="近30天消费趋势" style={{ margin: '16px 0', width: '100%' }}>
<ResponsiveContainer width="100%" height={300}>
<BarChart data={data}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="date" />
<YAxis label={{ value: '消费金额(元)', angle: -90, position: 'insideLeft' }} />
<Tooltip formatter={(value) => [`${value}元`, '消费金额']} />
<Bar dataKey="amount" fill="#165DFF" radius={[4, 4, 0, 0]} />
</BarChart>
</ResponsiveContainer>
<div style={{ marginTop: '12px', textAlign: 'right' }}>
<Button size="small" type="link">导出数据</Button>
<Button size="small" type="link">查看消费分类</Button>
</div>
</Card>
);
}
};
function App() {
// 2. 配置useChat Hook,对接后端接口,定义组件渲染规则
const { messages, input, handleInputChange, handleSubmit, isLoading, extraMessageContents } = useChat({
api: '/api/chat',
// 配置如何渲染AI返回的组件内容
renderExtraMessageContents: (content) => {
if (content.type === 'component') {
const { componentName, props } = content.value;
const Component = componentMap[componentName];
// 只有预定义的组件才会渲染,避免安全风险
if (Component) return <Component {...props} />;
return <Text type="danger">组件渲染失败,请重试</Text>;
}
return null;
}
});
return (
<div style={{ maxWidth: '1000px', margin: '0 auto', padding: '24px', minHeight: '100vh' }}>
<Title level={2} style={{ textAlign: 'center', marginBottom: '32px' }}>
🤖 我的生成式UI智能助手
</Title>
{/* 对话内容区域 */}
<div style={{ marginBottom: '24px', minHeight: '500px', border: '1px solid #f0f0f0', borderRadius: '8px', padding: '16px' }}>
{messages.length === 0 ? (
<div style={{ textAlign: 'center', color: '#999', padding: '100px 0' }}>
试试输入:“看下我近30天的消费数据”
</div>
) : (
messages.map((message) => (
<div key={message.id} style={{ marginBottom: '20px' }}>
<Text strong style={{ display: 'block', marginBottom: '8px' }}>
{message.role === 'user' ? '🙋 你:' : '🤖 助手:'}
</Text>
<div style={{ paddingLeft: '24px' }}>
<Text>{message.content}</Text>
{/* 渲染AI生成的UI组件 */}
{extraMessageContents.get(message.id)}
</div>
</div>
))
)}
{isLoading && <Spin tip="思考中..." style={{ display: 'block', textAlign: 'center' }} />}
</div>
{/* 输入区域 */}
<form onSubmit={handleSubmit} style={{ display: 'flex', gap: '8px' }}>
<Input
value={input}
placeholder="输入你的需求,比如:看下我近30天的消费数据"
onChange={handleInputChange}
size="large"
disabled={isLoading}
/>
<Button type="primary" htmlType="submit" size="large" loading={isLoading}>
发送
</Button>
</form>
</div>
);
}
export default App;
然后我们需要创建后端接口,因为Vite默认没有后端服务,我们可以用Vercel Edge Functions,或者直接用Next.js(更简单),这里我们用Next.js的App Router实现后端接口app/api/chat/route.js:
// app/api/chat/route.js
import { openai } from '@ai-sdk/openai';
import { streamText, StreamData } from 'ai';
import dayjs from 'dayjs';
// 允许边缘运行,降低延迟
export const runtime = 'edge';
export async function POST(req) {
const { messages } = await req.json();
// 创建流式数据对象,用来传输组件调用指令
const data = new StreamData();
const result = await streamText({
model: openai('gpt-4o'),
messages,
temperature: 0, // 降低温度,让AI输出更稳定
// 3. 定义AI可以调用的工具:分为业务工具和UI组件工具
tools: {
// 业务工具:获取用户近30天消费数据,实际场景对接你的业务API
getConsumptionData: {
description: '获取用户近30天的每日消费金额数据',
parameters: {
type: 'object',
properties: {},
required: [],
},
execute: async () => {
// 模拟业务API返回数据
return Array.from({ length: 30 }, (_, i) => ({
date: dayjs().subtract(29 - i, 'day').format('MM-DD'),
amount: Math.floor(Math.random() * 300) + 50,
}));
}
},
// UI组件工具:渲染消费柱状图
renderConsumptionBarChart: {
description: '当用户需要查看消费趋势时,调用这个组件渲染柱状图,传入消费数据数组',
parameters: {
type: 'object',
properties: {
data: {
type: 'array',
description: '近30天的消费数据数组,每个元素包含date(日期字符串)和amount(金额数字)字段',
items: {
type: 'object',
properties: {
date: { type: 'string', description: '日期,格式为MM-DD' },
amount: { type: 'number', description: '当日消费金额,单位元' }
},
required: ['date', 'amount']
}
}
},
required: ['data'],
},
execute: async ({ data: consumptionData }) => {
// 向前端发送组件调用指令
data.append('component', {
componentName: 'ConsumptionBarChart',
props: { data: consumptionData }
});
return '已为你生成近30天的消费趋势图表:';
}
}
},
// 流式输出结束后关闭数据通道
onFinish: () => data.close(),
});
// 返回流式响应
return result.toDataStreamResponse({ data });
}
现在运行项目npm run dev,访问http://localhost:3000,输入“看下我近30天的消费数据”,你就能看到AI直接生成了一个可交互的柱状图,还有导出数据、查看分类的按钮,完全不需要你手动去报表页面筛选数据。
4.4 步骤三:动态数据绑定与交互增强
现在我们的组件还只是静态展示,接下来我们实现两个核心能力:动态数据绑定和交互事件响应。
动态数据绑定
很多时候我们需要把Agent调用业务API拿到的实时数据绑定到生成的UI上,比如用户问“我这周的待办有哪些”,Agent调用待办API拿到数据,然后动态渲染待办列表组件,还支持标记完成、删除等操作。
我们先在componentMap里添加待办列表组件:
// src/App.jsx 中的componentMap新增
TodoList: ({ todos, onMarkDone }) => {
const columns = [
{ title: '任务名称', dataIndex: 'name', key: 'name' },
{
title: '截止时间',
dataIndex: 'deadline',
key: 'deadline',
render: (d) => dayjs(d).format('YYYY-MM-DD HH:mm'),
sorter: (a,b) => a.deadline - b.deadline
},
{
title: '优先级',
dataIndex: 'priority',
key: 'priority',
render: (p) => {
const colorMap = { high: 'red', medium: 'orange', low: 'green' };
return <Text type={colorMap[p]} strong>{p === 'high' ? '高' : p === 'medium' ? '中' : '低'}</Text>
}
},
{
title: '操作',
key: 'action',
render: (_, record) => (
<Button
size="small"
type="primary"
ghost
onClick={() => onMarkDone(record.id)}
>
标记完成
</Button>
),
},
];
return (
<Card title="我的待办列表" style={{ margin: '16px 0' }}>
<Table
dataSource={todos}
columns={columns}
rowKey="id"
pagination={false}
/>
</Card>
);
}
然后在后端接口的tools里添加获取待办数据和渲染待办列表的工具:
// app/api/chat/route.js 的tools新增
// 业务工具:获取待办列表
getTodoList: {
description: '获取用户的待办任务列表',
parameters: { type: 'object', properties: {}, required: [] },
execute: async () => {
// 模拟业务API返回
return [
{ id: 1, name: '完成Generative UI技术分享', deadline: dayjs().add(1, 'day').valueOf(), priority: 'high' },
{ id: 2, name: '迭代产品需求文档', deadline: dayjs().add(3, 'day').valueOf(), priority: 'medium' },
{ id: 3, name: '交水电费', deadline: dayjs().add(5, 'day').valueOf(), priority: 'low' },
];
}
},
// UI组件工具:渲染待办列表
renderTodoList: {
description: '当用户需要查看待办列表时调用,传入待办数据数组',
parameters: {
type: 'object',
properties: {
todos: {
type: 'array',
description: '待办任务数组,每个元素包含id、name、deadline、priority字段',
items: {
type: 'object',
properties: {
id: { type: 'number' },
name: { type: 'string' },
deadline: { type: 'number' },
priority: { type: 'string', enum: ['high', 'medium', 'low'] }
},
required: ['id', 'name', 'deadline', 'priority']
}
}
},
required: ['todos'],
},
execute: async ({ todos }) => {
data.append('component', {
componentName: 'TodoList',
props: { todos }
});
return '已为你生成待办列表,你可以点击按钮标记任务完成:';
}
}
现在你输入“看下我这周的待办”,AI就会生成一个带排序、操作按钮的待办列表,数据完全是从业务API动态获取的。
交互事件响应
接下来我们实现点击“标记完成”按钮后,告诉AI更新待办状态的功能,我们需要修改useChat的配置,添加onComponentEvent回调,处理组件发出的事件:
// src/App.jsx 的useChat配置新增
onComponentEvent: async (event) => {
// 处理待办列表的标记完成事件
if (event.type === 'markTodoDone') {
// 发送消息给AI,告知任务已完成
await handleSubmit(undefined, {
messages: [...messages, {
id: Date.now().toString(),
role: 'user',
content: `我已经完成了ID为${event.payload.todoId}的待办任务,请更新列表`
}]
});
}
}
然后修改待办列表组件的点击事件,发出事件:
// TodoList组件的按钮点击事件
onClick={() => emitComponentEvent({ type: 'markTodoDone', payload: { todoId: record.id } })}
现在你点击待办列表的“标记完成”按钮,AI会自动调用更新待办的API,然后重新渲染更新后的待办列表,完全不需要你手动刷新页面。
4.5 步骤四:自定义与美化
生成式UI的一个常见问题是AI生成的组件样式可能不符合产品的设计规范,我们可以通过两个方式控制:
- 所有组件都是预先定义的,样式完全按照设计系统实现,AI只能调用组件,不能修改样式
- 给AI的工具描述里明确组件的适用场景,避免AI在不合适的场景调用组件
比如我们可以给所有组件统一加上产品的主题色,调整圆角、间距等,确保生成的UI和产品整体风格一致:
// 全局配置Ant Design主题
import { ConfigProvider } from 'antd';
function App() {
return (
<ConfigProvider
theme={{
token: {
colorPrimary: '#165DFF',
borderRadius: 8,
colorSuccess: '#00B42A',
colorWarning: '#FF7D00',
colorError: '#F53F3F',
},
}}
>
{/* 原有内容 */}
</ConfigProvider>
);
}
我们还可以自定义提示框、图例、交互反馈等,比如给图表的Tooltip加上产品的logo,给按钮加上hover效果,确保生成的UI和传统UI的体验完全一致。
5. 进阶探讨
5.1 多模态生成式UI
现在的生成式UI主要是基于文字输入生成,未来随着多模态大模型的发展,你可以上传一张照片,比如你拍了一件衣服,AI直接生成同款商品的卡片,带购买按钮;你上传一张体检报告,AI直接生成可视化的健康报告,带指标解释和就医建议按钮。
5.2 性能优化与成本控制
生成式UI需要调用大模型,会产生token成本和延迟,我们可以通过以下方式优化:
- 缓存常用场景的组件:比如用户多次查询消费数据,直接复用之前的组件,不用每次调用大模型
- 本地规则优先:简单的需求可以用本地规则匹配组件,不用调用大模型,比如用户输入“待办”直接触发待办组件
- 流式渲染:边生成边渲染,降低用户的等待感知
5.3 通用生成式UI组件库
未来会出现通用的生成式UI组件库,开发者只要引入组件库,配置好业务API,就能快速搭建生成式UI助手,不用自己定义每个组件和工具。
6. 总结
核心要点回顾
- Generative UI是Agent时代的交互革命,解决了传统UI和对话式UI的体验断层问题,能把AI Agent的能力直接触达给用户
- 生成式UI的核心逻辑是:大模型根据用户需求动态调用预先定义的组件,渲染可交互界面,所有组件都是预定义的,确保安全和可控
- 生成式UI的开发流程是:定义组件映射→定义业务工具和UI工具→配置渲染规则→处理交互事件
- 生成式UI适合需求多变的场景,不是要替代传统UI,而是补充传统UI的灵活性不足的问题
成果展示
通过本文的实战,我们实现了一个支持消费图表生成、待办列表管理、交互事件响应的生成式UI助手,用户只要说出需求就能得到对应的操作入口,操作效率提升80%以上。
未来展望
未来3-5年,生成式UI会成为所有AI应用的标准交互方式,UX设计师的工作会从设计固定的用户路径,变成设计组件、规则和交互边界,开发者的工作会从开发固定页面,变成开发通用组件和对接业务API,整个UI/UX的开发流程会被彻底重构。
7. 行动号召
如果你对Generative UI感兴趣,不妨按照本文的步骤自己做一个demo试试,也可以想想你现在负责的产品里哪些场景可以用Generative UI来优化体验。如果你在实践中遇到任何问题,或者有不同的看法,欢迎在评论区留言和我讨论~
总字数:11237字
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)