生成式用户界面(Generative UI)让智能体不再局限于文本,还能够生成丰富的用户界面。这使得我们可以创建更加交互式且能够感知上下文的应用程序,让 UI 根据对话流程和 AI 响应动态调整。 Agent Chat 展示了一个关于预订住宿的提示,并以内嵌 UI 组件的形式渲染了一组生成的酒店列表卡片(包括图片、标题、价格和位置)。 LangSmith 支持将 React 组件与图代码放在一起。这样,你可以专注于为图构建特定的 UI 组件,同时轻松接入现有的聊天界面,例如 Agent Chat,并且只在实际需要时加载代码。

教程

1. 定义并配置 UI 组件

首先,创建你的第一个 UI 组件。对于每个组件,你都需要提供一个唯一标识符,图代码将使用它来引用该组件。
src/agent/ui.tsx
接下来,在 langgraph.json 配置中定义 UI 组件:
ui 部分指向图将使用的 UI 组件。默认情况下,我们建议使用与图名称相同的键,但你也可以按照自己的需求拆分组件。详情请参阅自定义 UI 组件的命名空间。 LangSmith 会自动打包 UI 组件代码和样式,并将它们作为外部资源提供,供 LoadExternalComponent 组件加载。某些依赖(例如 react 和 react-dom)会自动从打包结果中排除。 CSS 和 Tailwind 4.x 也可以直接使用,因此你可以在 UI 组件中自由使用 Tailwind 类以及 shadcn/ui。

2. 在图中发送 UI 组件

src/agent.py

3. 在 React 应用中处理 UI 元素

在客户端,你可以使用 useStream() 和 LoadExternalComponent 来显示 UI 元素。
src/app/page.tsx
在幕后,LoadExternalComponent 会从 LangSmith 获取 UI 组件的 JS 和 CSS,并在 shadow DOM 中渲染它们,从而确保样式与应用的其他部分相互隔离。

操作指南

在客户端提供自定义组件

如果你的客户端应用中已经加载了这些组件,可以提供一个组件映射,直接渲染它们,而无需从 LangSmith 获取 UI 代码。

组件加载时显示加载 UI

你可以提供一个备用 UI,在组件加载期间进行渲染。

自定义 UI 组件的命名空间

默认情况下,LoadExternalComponent 会使用 useStream() hook 中的 assistantId 来获取 UI 组件代码。你可以向 LoadExternalComponent 组件提供 namespace 属性来进行自定义。

从 UI 组件访问并操作线程状态

你可以使用 useStreamContext hook 在 UI 组件内部访问线程状态。

向客户端组件传递额外上下文

你可以向 LoadExternalComponent 组件提供 meta 属性,以便向客户端组件传递额外的上下文。
然后,你可以使用 useStreamContext hook 在 UI 组件中访问 meta 属性。

从服务器流式传输 UI 消息

你可以使用 useStream() hook 的 onCustomEvent 回调,在节点执行完成之前就流式传输 UI 消息。当 LLM 正在生成响应时需要更新 UI 组件,这种方式尤其有用。
然后,你可以通过调用 ui.push() / push_ui_message(),并使用与要更新的 UI 消息相同的 ID,向 UI 组件推送更新。

从状态中移除 UI 消息

与通过追加 RemoveMessage 来从状态中移除消息类似,你可以调用 remove_ui_message / ui.delete,并传入 UI 消息的 ID,从状态中移除 UI 消息。

了解更多