前言
想象一下这样的场景:用户在聊天界面输入"帮我创建一个用户管理表格",几秒钟后,界面上自动出现了一个功能完整的表格组件,包含搜索、分页、排序、编辑等所有功能。用户不需要编写任何代码,也不需要设计任何界面,AI 已经完成了一切。
这不是科幻小说,而是 2026 年生成式 UI(Generative UI)正在实现的现实。
生成式 UI 是指由 AI 在运行时动态生成的用户界面,而不是由开发者提前编写和构建的静态界面。它代表了前端开发的下一个重大范式转变:从"命令式 UI"(开发者告诉计算机每个组件做什么)转向"声明式 UI"(开发者告诉计算机用户需要什么,AI 决定如何呈现)。
本文将深入探讨生成式 UI 的核心概念、技术实现、最佳实践和实际案例,帮助你理解如何构建下一代 AI 驱动的用户界面。

第一章:生成式 UI 的核心概念
1.1 什么是生成式 UI
生成式 UI 是一种全新的界面构建方式,它的核心思想是:
- 用户意图驱动:界面由用户的自然语言查询或操作意图驱动
- 动态生成:界面组件在运行时由 AI 动态生成,而不是提前预定义
- 智能适配:界面会根据用户上下文、设备特性和业务规则自动调整
与传统的命令式 UI 相比,生成式 UI 有以下显著差异:
| 特性 | 命令式 UI | 生成式 UI |
|---|---|---|
| 驱动方式 | 开发者编写代码 | 用户意图 + AI |
| 界面生成时机 | 编译时/构建时 | 运行时 |
| 组件来源 | 预定义组件库 | AI 动态生成 |
| 交互逻辑 | 开发者硬编码 | AI 智能推导 |
| 个性化程度 | 有限 | 高度个性化 |
1.2 生成式 UI 的技术栈
生成式 UI 的实现依赖于以下关键技术:
核心技术一:大型语言模型(LLM)
LLM 是生成式 UI 的"大脑",它理解用户意图并生成相应的 UI 描述。
typescript
interface LLMResponse {
type: 'component' | 'text' | 'action';
content: string;
props?: Record<string, any>;
children?: LLMResponse[];
}
async function generateUI(prompt: string): Promise<LLMResponse> {
const response = await fetch('/api/generate-ui', {
method: 'POST',
body: JSON.stringify({ prompt }),
});
return response.json();
}
核心技术二:UI 渲染引擎
渲染引擎负责将 LLM 生成的 UI 描述转换为实际的 DOM 元素。
typescript
function renderUI(node: LLMResponse): React.ReactNode {
switch (node.type) {
case 'component':
const Component = getComponent(node.content);
return <Component {...node.props}>{node.children?.map(renderUI)}</Component>;
case 'text':
return <span>{node.content}</span>;
case 'action':
return <button onClick={() => executeAction(node.content)}>执行</button>;
default:
return null;
}
}
核心技术三:结构化输出格式
LLM 需要输出结构化的 UI 描述,常用的格式包括:
- JSON Schema:最通用的结构化格式
- OpenUI:专门为生成式 UI 设计的格式
- A2UI:另一种生成式 UI 格式标准
1.3 生成式 UI 的四种状态
与传统 CRUD 应用不同,AI 交互是异步和多步骤的。生成式 UI 必须处理四种不同的状态:
typescript
type UIState = 'idle' | 'thinking' | 'streaming' | 'finalized';
interface GenerativeUIProps {
prompt: string;
onStateChange?: (state: UIState) => void;
}
function GenerativeUI({ prompt, onStateChange }: GenerativeUIProps) {
const [state, setState] = useState<UIState>('idle');
const [content, setContent] = useState<string>('');
useEffect(() => {
if (!prompt) return;
setState('thinking');
onStateChange?.('thinking');
const stream = generateUIStream(prompt);
stream.on('data', (chunk) => {
setState('streaming');
onStateChange?.('streaming');
setContent(prev => prev + chunk);
});
stream.on('end', () => {
setState('finalized');
onStateChange?.('finalized');
});
}, [prompt]);
switch (state) {
case 'idle':
return <div>等待输入...</div>;
case 'thinking':
return <div className="thinking">正在思考...</div>;
case 'streaming':
return <div className="streaming">{content}</div>;
case 'finalized':
return <div className="finalized">{content}</div>;
}
}

第二章:使用 Vercel AI SDK 构建生成式 UI
2.1 Vercel AI SDK 简介
Vercel AI SDK 是构建 AI 驱动应用的首选工具库,它提供了一套完整的工具链来实现生成式 UI。
bash
npm install ai @ai-sdk/openai
2.2 基础用法:流式文本生成
让我们从最简单的流式文本生成开始:
tsx
'use client';
import { useChat } from 'ai/react';
function ChatInterface() {
const { messages, input, handleInputChange, handleSubmit } = useChat({
api: '/api/chat',
initialMessages: [
{ role: 'system', content: '你是一个专业的前端助手' },
],
});
return (
<div className="chat-interface">
<div className="messages">
{messages.map((message) => (
<div key={message.id} className={`message ${message.role}`}>
{message.content}
</div>
))}
</div>
<input
value={input}
onChange={handleInputChange}
onSubmit={handleSubmit}
placeholder="输入你的问题..."
/>
</div>
);
}
typescript
// app/api/chat/route.ts
import { openai } from '@ai-sdk/openai';
import { streamText } from 'ai';
export async function POST(req: Request) {
const { messages } = await req.json();
const result = await streamText({
model: openai('gpt-4o'),
messages,
});
return result.toAIStreamResponse();
}
2.3 进阶用法:生成 React 组件
Vercel AI SDK 3.0 引入了 streamUI 函数,可以直接生成 React 组件:
tsx
import { streamUI } from 'ai/react';
import { openai } from '@ai-sdk/openai';
import { z } from 'zod';
async function FlightAssistant({ query }: { query: string }) {
const result = await streamUI({
model: openai('gpt-4o'),
prompt: query,
text: ({ content }) => <div className="text-content">{content}</div>,
tools: {
getFlights: {
description: '获取航班信息',
parameters: z.object({
destination: z.string(),
date: z.string(),
}),
generate: async ({ destination, date }) => {
const flights = await fetchFlights(destination, date);
return <FlightCard flights={flights} />;
},
},
},
});
return result.value;
}
tsx
function FlightCard({ flights }: { flights: Flight[] }) {
return (
<div className="flight-card">
<h3>航班信息</h3>
<div className="flight-list">
{flights.map((flight) => (
<div key={flight.id} className="flight-item">
<div className="flight-info">
<span>{flight.airline}</span>
<span>{flight.number}</span>
</div>
<div className="flight-time">
<span>{flight.departure}</span>
<span>→</span>
<span>{flight.arrival}</span>
</div>
<div className="flight-price">¥{flight.price}</div>
</div>
))}
</div>
</div>
);
}
2.4 实战案例:AI 代码助手
让我们构建一个完整的 AI 代码助手应用:
tsx
'use client';
import { useState } from 'react';
import { useChat } from 'ai/react';
function CodeAssistant() {
const [language, setLanguage] = useState('javascript');
const { messages, input, handleInputChange, handleSubmit, isLoading } = useChat({
api: '/api/code-assistant',
initialMessages: [
{
role: 'system',
content: `你是一个专业的${language}代码助手,请提供高质量的代码示例和解释`
},
],
});
return (
<div className="code-assistant">
<div className="header">
<h2>AI 代码助手</h2>
<select value={language} onChange={(e) => setLanguage(e.target.value)}>
<option value="javascript">JavaScript</option>
<option value="typescript">TypeScript</option>
<option value="python">Python</option>
<option value="rust">Rust</option>
</select>
</div>
<div className="chat-area">
{messages.map((message) => (
<div key={message.id} className={`message ${message.role}`}>
{message.role === 'assistant' && message.content.includes('```') ? (
<pre className="code-block">
<code>{message.content.replace(/```[\s\S]*?```/g, (match) => match.slice(3, -3))}</code>
</pre>
) : (
<p>{message.content}</p>
)}
</div>
))}
{isLoading && <div className="loading">思考中...</div>}
</div>
<div className="input-area">
<input
value={input}
onChange={handleInputChange}
onKeyDown={(e) => e.key === 'Enter' && handleSubmit()}
placeholder="输入你的代码需求..."
disabled={isLoading}
/>
<button onClick={handleSubmit} disabled={isLoading}>
发送
</button>
</div>
</div>
);
}
typescript
// app/api/code-assistant/route.ts
import { openai } from '@ai-sdk/openai';
import { streamText } from 'ai';
export async function POST(req: Request) {
const { messages } = await req.json();
const result = await streamText({
model: openai('gpt-4o'),
messages,
temperature: 0.1,
maxTokens: 4000,
});
return result.toAIStreamResponse();
}

第三章:生成式 UI 的架构模式
3.1 模式一:代理渲染模式
代理渲染模式是最常见的生成式 UI 架构,它的核心思想是:AI 在后端生成 UI 描述,前端负责渲染。
typescript
// 后端 - AI 生成 UI 描述
async function generateUIDescription(prompt: string): Promise<UIDescription> {
const response = await llm.generate({
prompt: `根据用户需求生成 UI 描述:\n${prompt}`,
format: 'json',
});
return JSON.parse(response.content);
}
// 前端 - 渲染 UI
function RenderUI({ description }: { description: UIDescription }) {
const components = {
Button,
Input,
Card,
Table,
};
return React.createElement(
components[description.type],
description.props,
description.children?.map(RenderUI)
);
}
3.2 模式二:客户端生成模式
在客户端生成模式中,AI 直接在浏览器中运行,生成 UI 描述并渲染。
typescript
import { createAI } from '@ai-sdk/react';
const AI = createAI({
model: 'gpt-4o',
apiKey: process.env.NEXT_PUBLIC_OPENAI_API_KEY,
});
function ClientSideGenerativeUI() {
const [prompt, setPrompt] = useState('');
const [ui, setUi] = useState<UIDescription | null>(null);
const handleGenerate = async () => {
const result = await AI.generate({
prompt: `生成 UI 描述:\n${prompt}`,
format: 'json',
});
setUi(JSON.parse(result.content));
};
return (
<div>
<input value={prompt} onChange={(e) => setPrompt(e.target.value)} />
<button onClick={handleGenerate}>生成</button>
{ui && <RenderUI description={ui} />}
</div>
);
}
3.3 模式三:混合模式
混合模式结合了代理渲染和客户端生成的优点:
- 复杂逻辑:在后端处理,保证安全性和性能
- 简单渲染:在客户端完成,提升响应速度
typescript
// 后端 - 处理复杂逻辑
async function processRequest(prompt: string): Promise<ProcessingResult> {
const uiDescription = await generateUIDescription(prompt);
const data = await fetchData(uiDescription.dataRequirements);
return { uiDescription, data };
}
// 前端 - 渲染和交互
function HybridGenerativeUI({ prompt }: { prompt: string }) {
const { data, uiDescription } = useSWR(`/api/generate-ui?prompt=${prompt}`, fetcher);
if (!uiDescription) return <Loading />;
return (
<RenderUI
description={uiDescription}
data={data}
onAction={(action) => handleAction(action)}
/>
);
}
3.4 模式四:工具调用模式
工具调用模式允许 AI 根据需要调用外部工具来获取数据或执行操作。
typescript
interface Tool {
name: string;
description: string;
parameters: Record<string, any>;
execute: (params: Record<string, any>) => Promise<any>;
}
const tools: Tool[] = [
{
name: 'getWeather',
description: '获取天气信息',
parameters: { city: 'string' },
execute: async ({ city }) => {
const response = await fetch(`/api/weather?city=${city}`);
return response.json();
},
},
{
name: 'searchProducts',
description: '搜索商品',
parameters: { keyword: 'string', limit: 'number' },
execute: async ({ keyword, limit }) => {
const response = await fetch(`/api/products?keyword=${keyword}&limit=${limit}`);
return response.json();
},
},
];
async function generateUIWithTools(prompt: string): Promise<UIDescription> {
let currentPrompt = prompt;
while (true) {
const response = await llm.generate({
prompt: currentPrompt,
format: 'json',
tools,
});
if (response.toolCalls) {
const toolResults = await Promise.all(
response.toolCalls.map((call) =>
tools.find(t => t.name === call.name)?.execute(call.parameters)
)
);
currentPrompt = `${prompt}\n\n工具调用结果:\n${JSON.stringify(toolResults)}`;
} else {
return JSON.parse(response.content);
}
}
}

第四章:生成式 UI 的最佳实践
4.1 提示词工程
好的提示词是生成式 UI 成功的关键。以下是一些提示词工程的最佳实践:
实践一:明确输出格式
typescript
const prompt = `
请根据以下需求生成 UI 描述:
用户需求: 创建一个用户管理表格
输出格式要求:
{
"type": "component",
"name": "Table",
"props": {
"columns": [...],
"data": [...]
},
"children": [...]
}
`;
实践二:提供上下文信息
typescript
const prompt = `
请根据以下需求生成 UI 描述:
用户需求: 创建一个用户管理表格
上下文信息:
- 当前用户角色: 管理员
- 主题: 深色模式
- 设备类型: 桌面端
- 可用组件: Button, Input, Table, Card, Modal
输出格式要求: JSON
`;
实践三:限制输出范围
typescript
const prompt = `
请根据以下需求生成 UI 描述:
用户需求: 创建一个简单的登录表单
限制条件:
- 只使用以下组件: Input, Button
- 不超过 3 个字段
- 使用浅色主题
输出格式要求: JSON
`;
4.2 组件原子化设计
为了让 AI 能够灵活组合组件,需要将 UI 组件设计为原子化的、可复用的单元。
typescript
// 原子组件
interface ButtonProps {
children: React.ReactNode;
variant?: 'primary' | 'secondary' | 'danger';
size?: 'sm' | 'md' | 'lg';
onClick?: () => void;
}
function Button({ children, variant = 'primary', size = 'md', onClick }: ButtonProps) {
return (
<button
className={`btn btn-${variant} btn-${size}`}
onClick={onClick}
>
{children}
</button>
);
}
// 分子组件
interface SearchBarProps {
placeholder?: string;
onSearch: (keyword: string) => void;
}
function SearchBar({ placeholder = '搜索...', onSearch }: SearchBarProps) {
const [value, setValue] = useState('');
return (
<div className="search-bar">
<Input
value={value}
onChange={(e) => setValue(e.target.value)}
placeholder={placeholder}
/>
<Button onClick={() => onSearch(value)}>搜索</Button>
</div>
);
}
// 组织组件
interface UserTableProps {
users: User[];
onEdit: (user: User) => void;
onDelete: (userId: string) => void;
}
function UserTable({ users, onEdit, onDelete }: UserTableProps) {
return (
<Table data={users}>
<Table.Column field="name" title="姓名" />
<Table.Column field="email" title="邮箱" />
<Table.Column field="role" title="角色" />
<Table.Column
title="操作"
render={(user) => (
<div className="actions">
<Button onClick={() => onEdit(user)}>编辑</Button>
<Button variant="danger" onClick={() => onDelete(user.id)}>删除</Button>
</div>
)}
/>
</Table>
);
}
4.3 错误处理与回退机制
生成式 UI 可能会失败,需要有完善的错误处理和回退机制。
typescript
function GenerativeUI({ prompt }: { prompt: string }) {
const [error, setError] = useState<Error | null>(null);
const [isFallback, setIsFallback] = useState(false);
const { data: uiDescription } = useSWR(`/api/generate-ui?prompt=${prompt}`, fetcher, {
onError: (err) => {
setError(err);
setIsFallback(true);
},
});
if (isFallback) {
return (
<div className="fallback">
<p>生成失败,显示默认界面</p>
<DefaultUI />
</div>
);
}
if (error) {
return (
<div className="error">
<p>发生错误: {error.message}</p>
<button onClick={() => window.location.reload()}>重试</button>
</div>
);
}
if (!uiDescription) {
return <Loading />;
}
return <RenderUI description={uiDescription} />;
}
4.4 性能优化策略
生成式 UI 面临独特的性能挑战,以下是一些优化策略:
策略一:缓存生成结果
typescript
const cache = new Map<string, UIDescription>();
async function generateUIWithCache(prompt: string): Promise<UIDescription> {
const cacheKey = hash(prompt);
if (cache.has(cacheKey)) {
return cache.get(cacheKey)!;
}
const result = await generateUI(prompt);
cache.set(cacheKey, result);
return result;
}
策略二:懒加载组件
typescript
const componentMap: Record<string, React.LazyExoticComponent<any>> = {
Button: React.lazy(() => import('./Button')),
Input: React.lazy(() => import('./Input')),
Table: React.lazy(() => import('./Table')),
Card: React.lazy(() => import('./Card')),
};
function RenderUI({ description }: { description: UIDescription }) {
const Component = componentMap[description.type];
return (
<Suspense fallback={<Loading />}>
{Component && <Component {...description.props} />}
</Suspense>
);
}
策略三:流式渲染
typescript
async function* streamUI(prompt: string): AsyncGenerator<string> {
const response = await fetch('/api/generate-ui-stream', {
method: 'POST',
body: JSON.stringify({ prompt }),
});
const reader = response.body?.getReader();
const decoder = new TextDecoder();
while (reader) {
const { done, value } = await reader.read();
if (done) break;
yield decoder.decode(value);
}
}
function StreamingGenerativeUI({ prompt }: { prompt: string }) {
const [content, setContent] = useState('');
useEffect(() => {
const generator = streamUI(prompt);
async function consume() {
for await (const chunk of generator) {
setContent(prev => prev + chunk);
}
}
consume();
}, [prompt]);
return <div dangerouslySetInnerHTML={{ __html: content }} />;
}
第五章:生成式 UI 的安全考虑
5.1 注入攻击防护
生成式 UI 面临的最大安全风险是注入攻击。以下是一些防护措施:
措施一:输出验证
typescript
import { z } from 'zod';
const UIDescriptionSchema = z.object({
type: z.enum(['component', 'text', 'action']),
name: z.string().optional(),
props: z.record(z.any()).optional(),
children: z.array(z.lazy(() => UIDescriptionSchema)).optional(),
});
async function generateUI(prompt: string): Promise<UIDescription> {
const response = await llm.generate({
prompt,
format: 'json',
});
const result = JSON.parse(response.content);
const validated = UIDescriptionSchema.safeParse(result);
if (!validated.success) {
throw new Error('无效的 UI 描述');
}
return validated.data;
}
措施二:组件白名单
typescript
const allowedComponents = ['Button', 'Input', 'Table', 'Card', 'Modal'];
function RenderUI({ description }: { description: UIDescription }) {
if (!allowedComponents.includes(description.name)) {
throw new Error(`不允许的组件: ${description.name}`);
}
const Component = getComponent(description.name);
return <Component {...description.props} />;
}
措施三:属性过滤
typescript
const allowedProps: Record<string, Set<string>> = {
Button: new Set(['children', 'variant', 'size', 'onClick']),
Input: new Set(['value', 'placeholder', 'onChange', 'type']),
Table: new Set(['data', 'columns']),
};
function filterProps(componentName: string, props: Record<string, any>): Record<string, any> {
const allowed = allowedProps[componentName] || new Set();
return Object.fromEntries(
Object.entries(props).filter(([key]) => allowed.has(key))
);
}
5.2 数据安全
生成式 UI 可能会泄露敏感数据,需要注意以下几点:
- 不在提示词中包含敏感信息
- 对 AI 返回的内容进行脱敏处理
- 限制 AI 访问敏感 API
typescript
async function fetchData(dataRequirements: DataRequirements) {
const sensitiveEndpoints = ['/api/users', '/api/orders'];
if (sensitiveEndpoints.includes(dataRequirements.endpoint)) {
const user = getCurrentUser();
if (!user.isAdmin) {
throw new Error('权限不足');
}
}
const response = await fetch(dataRequirements.endpoint);
const data = await response.json();
return sanitizeData(data);
}
function sanitizeData(data: any): any {
if (Array.isArray(data)) {
return data.map(sanitizeData);
}
if (typeof data === 'object' && data !== null) {
const sanitized: Record<string, any> = {};
for (const [key, value] of Object.entries(data)) {
if (['password', 'token', 'secret'].includes(key)) {
sanitized[key] = '***';
} else {
sanitized[key] = sanitizeData(value);
}
}
return sanitized;
}
return data;
}
第六章:生成式 UI 的未来展望
6.1 技术演进方向
生成式 UI 正在快速演进,未来几年可能会出现以下趋势:
- 多模态生成:AI 不仅生成文本和组件,还能生成图像、视频和音频
- 实时协作:多人同时使用 AI 生成和编辑界面
- 个性化自适应:根据用户行为和偏好自动调整界面
6.2 开发工具革新
生成式 UI 将彻底改变前端开发工具:
- AI 原生 IDE:IDE 直接集成生成式 UI 能力
- 智能设计工具:Figma + AI 自动生成代码
- 零代码平台:普通人也能创建复杂应用
6.3 架构范式转变
生成式 UI 将推动前端架构的根本性转变:
- 从组件库到组件市场:AI 可以从互联网获取任何组件
- 从静态布局到动态布局:界面根据上下文自动调整
- 从硬编码逻辑到智能逻辑:AI 自主决策交互逻辑
结语
生成式 UI 是前端开发的下一个重大范式转变。它将彻底改变我们构建用户界面的方式,从"开发者编写代码"转向"AI 根据用户意图生成界面"。
虽然生成式 UI 还处于早期阶段,但它已经展现出巨大的潜力。随着 AI 技术的不断进步,生成式 UI 将成为构建复杂应用的主流方式。
如果你想在这个领域保持领先,建议你:
- 学习 Vercel AI SDK 等主流工具
- 掌握提示词工程技巧
- 深入理解 AI 与 UI 的交互模式
- 关注生成式 UI 的最新进展
生成式 UI 的时代已经到来,准备好迎接它了吗?
📱 实用工具推荐
在日常工作和生活中,我们经常需要处理各种视频资源。如果你需要下载短视频平台上的视频,但又被烦人的水印困扰,那么这款小程序绝对值得一试!
三峋视频去水印
功能特点:
- 🎬 一键去水印:支持微信视频号、抖音、快手、小红书、B站等主流短视频平台,复制分享链接即可自动提取无水印视频
- 🚀 极速下载:智能解析视频链接,秒级获取高清无水印视频
- 💾 本地保存:下载的视频直接保存到手机相册,方便随时查看和当做素材使用或分享
- 🆓 完全免费:所有功能永久免费使用,无解锁广告干扰,无隐藏收费
使用方法:
- 在短视频平台找到喜欢的视频,点击分享按钮
- 复制视频的分享链接
- 打开「三峋视频去水印」小程序
- 粘贴链接,点击解析,即可获取无水印视频并下载
搜索方式:
在微信小程序中搜索 「三峋视频去水印」,即可找到并使用这款实用工具!
无论是工作中需要提取视频素材,还是生活中想要保存喜欢的短视频,「三峋视频去水印」都能帮你轻松搞定,让去水印下载变得简单高效!