1. 标题选项

包含核心关键词,覆盖不同读者的内容需求

  1. 《Agent 时代 UI/UX 革命:从静态页面到 Generative UI 动态交互界面全指南》
  2. 《告别固定组件:Generative UI 如何重构下一代 AI 应用交互体验》
  3. 《从零上手生成式UI:打造能跟着用户需求实时变化的动态交互界面》
  4. 《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. 准备工作

技术栈/知识要求

  1. 熟悉React基础(Hooks、组件、Props、事件处理)
  2. 了解大语言模型的基本调用方式(API调用、函数调用/工具调用)
  3. 有基础的HTTP请求和异步编程知识
  4. 对UI组件库(如Ant Design)、数据可视化库(如Recharts)有基本了解

环境/工具要求

  1. Node.js 18.0+ 版本,包管理器npm/yarn/pnpm均可
  2. 一个OpenAI API Key(可在OpenAI官网申请,也可使用国内通义千问、文心一言等支持工具调用的大模型服务替代)
  3. 代码编辑器(推荐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和相关概念的关系:

交互

依赖推理能力

对接业务能力

调用预定义组件

遵守样式规范

调用业务数据和能力

实现组件调度

USER

Generative_UI

LLM

AI_Agent

Component_Library

Design_System

Business_API

Tool_Calling

生成式UI的核心运行逻辑可以用下面的流程图表示:

用户输入需求/触发事件

拼接上下文:用户信息+历史对话+场景数据

是否需要调用UI组件?

返回文字/富文本响应

LLM推理:匹配需求→选择组件→生成参数

参数是否符合校验规则?

重试/返回降级文字响应

流式渲染生成的UI组件

用户与生成UI交互

交互结果同步到上下文

效率提升数学模型

生成式UI的核心价值是降低用户完成任务的时间和操作步数,我们可以用两个公式量化其效率提升:

  1. 操作步数减少量:
    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%。
  2. 时间效率提升率:
    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=12012020×100%83.3%
边界与外延

生成式UI不是“银弹”,也有明确的适用边界:
✅ 适合场景:

  • AI智能助手、智能客服:用户需求多变,无固定操作路径
  • 企业数据分析后台:用户需要灵活查询数据、生成报表
  • 电商/本地生活导购:用户需求个性化,需要动态推荐和操作入口
  • 低代码/无代码平台:让用户用自然语言生成需要的页面
    ❌ 不适合场景:
  • 核心固定路径页面:登录、支付、首页等对稳定性要求极高的场景
  • 高性能要求场景:游戏、实时音视频等对延迟要求极低的场景
  • 强合规要求场景:金融交易、医疗信息展示等需要100%可控的场景

4.2 步骤一:项目初始化与依赖安装

我们将基于Vite + React + Vercel AI SDK + Ant Design搭建生成式UI demo,Vercel AI SDK是目前最成熟的生成式UI开发工具,它封装了大模型调用、流式输出、组件调度等能力,不用我们自己写复杂的解析逻辑。

为什么需要这些依赖?
  1. @ai-sdk/react:Vercel AI SDK的React封装,提供了useChat等Hook,简化生成式UI的开发
  2. @ai-sdk/openai:对接OpenAI大模型的适配器,也可以换成其他大模型的适配器
  3. antd:国内常用的企业级组件库,提供我们需要的卡片、按钮、表格等通用组件
  4. recharts:数据可视化库,用来生成图表组件
  5. 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直接生成一个柱状图展示消费趋势,而不是返回文字数据。

核心逻辑说明

我们需要做三件事:

  1. 前端定义好可被AI调用的组件映射,告诉AI有哪些组件可用
  2. 后端定义好工具:包括获取消费数据的业务工具,和渲染消费图表的UI组件工具
  3. 配置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生成的组件样式可能不符合产品的设计规范,我们可以通过两个方式控制:

  1. 所有组件都是预先定义的,样式完全按照设计系统实现,AI只能调用组件,不能修改样式
  2. 给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. 总结

核心要点回顾

  1. Generative UI是Agent时代的交互革命,解决了传统UI和对话式UI的体验断层问题,能把AI Agent的能力直接触达给用户
  2. 生成式UI的核心逻辑是:大模型根据用户需求动态调用预先定义的组件,渲染可交互界面,所有组件都是预定义的,确保安全和可控
  3. 生成式UI的开发流程是:定义组件映射→定义业务工具和UI工具→配置渲染规则→处理交互事件
  4. 生成式UI适合需求多变的场景,不是要替代传统UI,而是补充传统UI的灵活性不足的问题

成果展示

通过本文的实战,我们实现了一个支持消费图表生成、待办列表管理、交互事件响应的生成式UI助手,用户只要说出需求就能得到对应的操作入口,操作效率提升80%以上。

未来展望

未来3-5年,生成式UI会成为所有AI应用的标准交互方式,UX设计师的工作会从设计固定的用户路径,变成设计组件、规则和交互边界,开发者的工作会从开发固定页面,变成开发通用组件和对接业务API,整个UI/UX的开发流程会被彻底重构。

7. 行动号召

如果你对Generative UI感兴趣,不妨按照本文的步骤自己做一个demo试试,也可以想想你现在负责的产品里哪些场景可以用Generative UI来优化体验。如果你在实践中遇到任何问题,或者有不同的看法,欢迎在评论区留言和我讨论~

总字数:11237字

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐