---
title: 生成式界面
description: "在你的产品中展示 Agent 的结构化回复。"
---

项目启用 **生成式界面（Generative UI）** 后，回复可在 Markdown 中包含 `openui` 内容块，用于卡片、对比、清单、图表、地图和标签页。普通文本和代码仍使用 Markdown。

## 安装

```bash
npm install @beeuni/sdk zod @openuidev/lang-core@0.3.1
# React:
npm install react
```

导入解析器或 React 渲染器前，先安装可选依赖。SDK 主入口和 React Hooks 不会加载它们。

## 导入入口

| Import | API |
| --- | --- |
| `@beeuni/sdk/genui/fence` | 识别内容块，不加载可选依赖 |
| `@beeuni/sdk/genui` | 解析器、组件目录和 Markdown 转换 |
| `@beeuni/sdk/genui/react` | 无预设样式的 React 渲染器及默认 HTML 组件 |

## 渲染内容块

在 Markdown 渲染器中用 `genuiVersionFromClassName(className)` 识别内容块。返回 `null` 表示普通代码块。仅在出现生成式内容块时，才延迟加载渲染器。

```tsx
import type { ReactNode } from 'react';
import { GenuiBlock, defaultGenuiComponents } from '@beeuni/sdk/genui/react';
import { genuiVersionFromClassName } from '@beeuni/sdk/genui/fence';

type Props = {
  code: string;
  className?: string;
  streaming: boolean;
  renderMarkdown: (markdown: string) => ReactNode;
};

function StructuredReply({ code, className, streaming, renderMarkdown }: Props) {
  const version = genuiVersionFromClassName(className);
  if (version === null) return <pre><code>{code}</code></pre>;
  return (
    <GenuiBlock
      code={code}
      version={version}
      streaming={streaming}
      components={defaultGenuiComponents}
      renderMarkdown={renderMarkdown}
    />
  );
}
```

通过 `components` 传入自己的组件，也可先用 `defaultGenuiComponents`。保持 `renderMarkdown` 的函数引用稳定。`streaming` 表示当前内容块是否仍在生成：围栏一闭合就设为 `false`，不必等整条回复结束。

对尚未生成完的大组件，可用 `renderPending` 预留空间。`enabled={false}` 改用 Markdown 展示。`onSettled` 在每个内容块结束后报告一次结果和耗时，不包含内容。

## 纯文本与兼容

纯文本界面可调用 `genuiToMarkdown(text)`。图表转为表格，地图转为地点列表，标签页和折叠面板会展开。流式回复中传入 `{ streaming: true }`，避免过早显示截断提示。

```ts
import { genuiToMarkdown } from '@beeuni/sdk/genui';

const markdown = genuiToMarkdown(reply, { streaming: true });
```

无效或不支持的内容块会显示回退内容，不会执行其中的内容。更新 SDK 可支持新增组件。清单勾选只保存在组件中，Beeuni 不会保存或提交。

## 安全

内容块只包含数据，不执行代码。链接和图片必须使用绝对 `http` 或 `https` URL。生成式界面不能调用工具，也不能修改应用状态。
