mcpField
G
generative-ui

generative-ui

github.com/assistant-ui开发291.1k 次安装2 天前更新
代码仓库

关于 generative-ui

generative-ui 是用于构建可组合界面的 assistant-ui 技能与软件包,提供可复用组件词汇。它支持由模型或后端生成界面,并可转换组件树以供浏览器、Slack 和 Microsoft Teams 渲染。

主要功能

  1. 01提供 29 个默认界面组件
  2. 02通过 present 组合布局
  3. 03渲染后端生成的界面消息
  4. 04自定义组件词汇
  5. 05转换为 Slack 和 Teams 格式
  6. 06转换 A2UI 界面

适用场景

  1. 01让模型用界面组件组合仪表盘
  2. 02渲染后端生成的界面消息部分
  3. 03将组件树发送至 Slack 或 Microsoft Teams

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/assistant-ui/skills --skill generative-ui

安装后在 Claude Code 中输入/generative-ui确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
a2ui-openui.md
actions.md
renderers.md
tokens.md
vocabulary.md

详细介绍

assistant-ui 生成式 UI

请务必查阅 assistant-ui.com/llms.txt,以获取最新 API。

生成式 UI 颠覆了常见的工具渲染关系。你无需为每次工具调用手写一个组件,而是提供一套组件词汇,并让模型通过 present 工具,或让后端通过消息部分或 LangGraph 事件,从中组装出一棵组件树。@assistant-ui/generative-ui 提供了包含 29 个组件(卡片、事实、表格、图表、表单、控件)的默认词汇,以及可将同一棵组件树转换为 Slack Block Kit 或 Microsoft Teams Adaptive Card 的转换器,还有一个可将 A2UI surface 转换为该格式的转换器。因此,只需构建一次组合,就能在浏览器内外渲染。

参考资料

  • ./references/vocabulary.md —— 29 个默认组件,以及如何使用 defineGenerativeComponents 添加自定义组件
  • ./references/actions.md —— _action 分发、createActionRegistry,以及交互式组件会发送回来的 $input 形状
  • ./references/renderers.md —— MessagePrimitive.GenerativeUI 及其允许列表、Slack 和 Teams 转换器,以及两种规范形状为何不能互换
  • ./references/a2ui-openui.md —— 通过 AG-UI 提供的 A2UI surfaces,以及第三方 OpenUI 集成
  • ./references/tokens.md —— 共享的 token 数组,以及如何重新设置样式或覆盖组件词汇

选择哪种生成式 UI 模式?

有两个问题可以区分这些模式:由模型组合布局,还是提前绑定布局;UI 是源自工具调用,还是由后端发出的消息部分。

模式API最适合
present 工具JSONGenerativeUI + present让模型根据你提供的组件词汇组合仪表板、卡片和布局
工具 UI工具包 render(参见工具)与一个你已知的工具调用绑定的小组件
生成式 UI 原语MessagePrimitive.GenerativeUI + 允许列表已经发出 generative-ui 消息部分的后端
LangGraph 数据 UImakeAssistantDataUI + ui_message在 LangGraph 流中发出 UI 的 LangGraph Agent;参见 assistant-ui.com/docs/runtimes/langgraph/generative-ui
OpenUI@openuidev/assistant-ui,第三方已投入 OpenUI 生态系统及其组件套件

前两种由工具驱动,因此由模型决定何时显示 UI;LangGraph 一行则由后端驱动,因此由你的 Agent 决定。present 和生成式 UI 原语都接受 JSON 组件树,但其形状不可互换;参见规范形状差异。为 present 构建的组件树,也是 Slack 和 Teams 转换器接受的形状,并且是 A2UI 转换器生成的形状。

快速开始

安装软件包,添加样式化元素,并为你的框架启用 "use generative" 编译器:

zod 是由 /react 入口导入的可选 peer dependency,因此请与软件包一并安装。

npm install @assistant-ui/generative-ui zod
npx assistant-ui@latest add generative-ui
import { withAui } from "@assistant-ui/next";

export default withAui({
  /* your Next config */
});

Vite 和 TanStack Start 使用来自 @assistant-ui/vite 的 aui()(plugins: [aui({ ... })]);Expo 和纯 React Native 则在 metro.config.js 中使用 const { withAui } = require("@assistant-ui/metro");。该指令允许同一个文件声明工具,供浏览器和你的服务端路由共同导入:编译器会从服务端构建中剥离仅浏览器端的部分,并从客户端构建中剥离 schemas。

JSONGenerativeUI 会将组件库转换为面向模型的 present schema。像注册其他工具一样,将结果注册到工具包中:

"use generative";

import { defineToolkit } from "@assistant-ui/react";
import {
  JSONGenerativeUI,
  defaultGenerativeUILibrary,
} from "@assistant-ui/generative-ui/react";

const generative = new JSONGenerativeUI({
  library: defaultGenerativeUILibrary,
});

export default defineToolkit({
  present: generative.present({ display: "standalone" }),
});

display: "standalone" 会将结果渲染在独立界面中,位于思维链轨迹之外;省略它则会内联渲染。默认词汇表无需你自备组件即可正常使用;完整列表及扩展方法请参阅 vocabulary.md。

通过 AuiConfig 在客户端注册工具包,并设置 sendAutomaticallyWhen,以便前端工具解析后继续运行:

"use client";

import { AssistantRuntimeProvider, AuiConfig, Tools } from "@assistant-ui/react";
import { useChatRuntime } from "@assistant-ui/ai-sdk";
import { lastAssistantMessageIsCompleteWithToolCalls } from "ai";
import toolkit from "./toolkit";

export function MyRuntimeProvider({
  children,
}: {
  children: React.ReactNode;
}) {
  const runtime = useChatRuntime({
    sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithToolCalls,
  });
  const config = AuiConfig({ tools: Tools({ toolkit }) });

  return (
    <AssistantRuntimeProvider runtime={runtime} config={config}>
      {children}
    </AssistantRuntimeProvider>
  );
}

present 是一个前端工具:它会在浏览器中解析;如果未设置 sendAutomaticallyWhen,UI 会渲染出来,但对话会在模型说出其他内容之前停止。

路由会导入同一个工具包模块。编译器会将该导入解析为服务端构建,因此只有 schemas 会传过去,浏览器代码不会进入你的服务端包:

import { openai } from "@ai-sdk/openai";
import { AISDKToolkit } from "@assistant-ui/ai-sdk";
import { convertToModelMessages, stepCountIs, streamText } from "ai";
import toolkit from "@/app/toolkit";

const aiToolkit = new AISDKToolkit({ toolkit });

export async function POST(req: Request) {
  const { messages, tools } = await req.json();

  const result = streamText({
    model: openai("gpt-5.6-luna"),
    messages: await convertToModelMessages(messages),
    stopWhen: stepCountIs(10),
    tools: await aiToolkit.tools({ frontend: tools }),
  });

  return result.toUIMessageStreamResponse();
}

如果你的后端没有导入工具包模块(例如运行在云端托管环境中),请使用 backendless: true 进行编译,这样客户端就会保留所有可上传的 schema,包括 present 的 schema:

export default withAui({ ...yourConfig, aui: { backendless: true } });

添加样式

上面运行的 npx assistant-ui@latest add generative-ui 会安装随附的样式表以及 components/assistant-ui/elements/generative-ui.tsx。该文件导出 styledGenerativeUILibrary:包含相同的 29 个组件,但将默认的纯文本渲染器替换为真实的 Markdown 渲染器。它是 "use client" 模块,因此将其接入 "use generative" 工具包文件时,需遵循下文注意事项中的客户端模块规则;准确的覆盖模式、data-aui 样式钩子和 token 数组请参阅 tokens.md。

不止于 present

  • 使用自己的组件扩展词汇表,或读取模型生成的树并显示:vocabulary.md。
  • 通过 _action 让已渲染的节点回调你的应用:actions.md。
  • 使用 MessagePrimitive.GenerativeUI 和由使用方提供的允许列表,渲染后端已发出的 generative-ui 消息部分:renderers.md。
  • 将树发送到 Slack 或 Microsoft Teams,或通过 AG-UI 渲染 A2UI 界面,或接入第三方 OpenUI 集成:renderers.md 和 a2ui-openui.md。

常见陷阱

present 渲染 UI 后,对话就停止了

  • present 是前端工具;如果未在 useChatRuntime 上设置 sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithToolCalls,运行在 present 完成后就不会继续。

模型在云托管后端上始终无法获知 present

  • 客户端构建会跳过上传前端和 human 模式,因为它假设你的后端导入了同一个工具包模块。如果没有任何服务器由你提供,请使用 aui: { backendless: true } 编译。

styledGenerativeUILibrary 会导致 "use generative" 构建失败

  • 它是一个 "use client" 模块。"use generative" 文件只能在 defineGenerativeComponents 调用中将它作为内联 render 值引用,不能将它用作展开对象、顶层常量或直接用作 library 选项。只有在不含 "use generative" 指令的普通文件中,才能直接将它传给 library;请参阅 tokens.md。

generative-ui 消息部分什么也没有渲染

  • 默认的 shadcn Thread 不会连接 MessagePrimitive.GenerativeUI。请在消息渲染器中明确启用;请参阅 renderers.md。

未知组件名称:静默丢弃还是抛出错误

  • present 工具路径会丢弃无法识别的 _type,并在开发模式下发出警告。除非传入 Fallback,否则 generative UI 原语会抛出类型化的 GenerativeUIRenderError。这两个边界都不会限制这些组件接收的属性;请自行验证 href/src 值,绝不要将 Agent 提供的属性传入 dangerouslySetInnerHTML。

Slack 或 Teams 的输出与浏览器中不一致

  • 转换覆盖全面但有损:请查看返回的 warnings 数组。只有为 present 构建的 $type 树才能转换;原语的 { component, props } 结构没有 Slack、Teams 或 A2UI 转换器。

useChatRuntime 从不发出原生 generative-ui 部分

  • AI SDK 会将工具结果映射为 tool-call 部分,而不是 generative-ui 部分。可以通过 render_gui 工具桥接,并自行将其结果解析为规范;文档将该辅助函数称为 parseRenderGuiResult,但它并非包导出;请参阅 renderers.md。

相关技能

  • tools -- 工具包编写、"use generative" 编译器,以及绑定到某个特定工具调用的小组件工具 UI
  • elements -- 安装 generative-ui 样式化元素及目录中的其他元素
  • primitives -- MessagePrimitive 和其他无样式构建块
  • runtime -- AuiConfig、Tools 和其他配置连接机制

评论

支持 Markdown