资讯动态

Metabase Embedding SDK 消息类型详解:MetabotAgentTextMessage 结构、判别联合与源码实现

发布时间:2026/9/11 2:04:47 来源:尧图企业网站定制
Metabase Embedding SDK 消息类型详解MetabotAgentTextMessage 结构、判别联合与源码实现【免费下载链接】metabaseThe easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart:项目地址: https://gitcode.com/GitHub_Trending/me/metabase导读MetabotAgentTextMessage是 Metabase Embedding SDK 中由 AI 助手Metabot返回给宿主应用的一种纯文本消息类型它描述了对话中Agent 回复这条消息的完整数据结构消息 ID、正文、角色标识与消息种类。本文以该类型定义为主线结合其所属的MetabotMessage判别联合discriminated union、相邻的MetabotAgentChartMessage图表消息、useMetabot对话 Hook 以及frontend/src/embedding-sdk-bundle/types/metabot.ts与enterprise/frontend/src/embedding-sdk-ee/metabot/hooks/use-metabot.tsx的真实实现帮助你彻底掌握如何在嵌入应用里识别、渲染并区分 Agent 的文本回复构建出类型安全的自定义 AI 问答界面。MetabotAgentTextMessage一段最小的 TypeScript 类型定义关联文档 MetabotAgentTextMessage.md 给出的核心类型定义非常精炼完整内容如下type MetabotAgentTextMessage { id: string; message: string; role: agent; type: text; };这是一条带字面量标记的消息类型。四个字段各司其职属性类型语义说明idstring消息的唯一标识可用于retryMessage(messageId)重试定位等场景messagestringAgent 回复的文本正文即要展示给终端用户的自然语言内容roleagent消息发言方标识固定为字面量agent表示消息来自 AI 助手typetext消息种类判别符固定为字面量text表示这是一条纯文本消息其中role与type之所以使用字面量类型literal type而非宽泛的string是为了让 TypeScript 能够在联合类型上进行判别收窄type narrowing只要检查type text且role agent编译器即可推断出这条消息的完整结构。在消息类型体系中的位置一条完整的判别联合MetabotAgentTextMessage并不是孤立存在的它是 SDK 对话消息类型树中的一个叶子节点。结合关联的 MetabotMessage.md 与 MetabotAgentMessage.md可以还原出完整的类型层级// 对话中出现的所有消息用户消息 Agent 消息 type MetabotMessage MetabotUserTextMessage | MetabotAgentMessage; // Agent 产生的消息文本回复 图表回复 type MetabotAgentMessage MetabotAgentTextMessage | MetabotAgentChartMessage;展开后MetabotMessage实际包含三种具体形态用户文本消息MetabotUserTextMessage见 MetabotUserTextMessage.md{ id: string; message: string; role: user; type: text }由用户发出Agent 文本消息MetabotAgentTextMessage本文主角由 Agent 发出role为agent、type为textAgent 图表消息MetabotAgentChartMessage见 MetabotAgentChartMessage.md{ Chart: ComponentTypeMetabotChartProps; id: string; questionPath: string; role: agent; type: chart }Agent 直接产出一张图表。三种形态通过type字段构成可判别的联合。这条定义在开源仓库的源码中有完全一致的对应实现见 frontend/src/embedding-sdk-bundle/types/metabot.ts// User messages export type MetabotUserTextMessage { id: string; role: user; type: text; message: string; }; // Agent messages export type MetabotAgentTextMessage { id: string; role: agent; type: text; message: string; }; export type MetabotAgentChartMessage { id: string; role: agent; type: chart; /** URL path to the question, e.g. /question#base64 */ questionPath: string; /** A pre-wired React component that renders the chart. */ Chart: React.ComponentTypeMetabotChartProps; }; export type MetabotAgentMessage | MetabotAgentTextMessage | MetabotAgentChartMessage; export type MetabotMessage MetabotUserTextMessage | MetabotAgentMessage;值得注意的是源码注释明确说明 SDK 只对外暴露type text消息与generated_entity图表卡片这两类公开消息内部还存在tool_call、action、data_part如code_edit、transform_suggestion、todo_list、adhoc_viz、static_viz、state等调试或内部形态但这些都不会通过 SDK 输入路径产生仅用于产品内其他界面。这解释了为什么公开类型体系中只保留文本与图表两种 Agent 消息。从内部消息到公开类型mapMessage 的映射逻辑MetabotAgentTextMessage并不是后端直接下发的原始结构而是由 SDK 层从内部消息部件message part映射而来。映射逻辑位于 enterprise/frontend/src/embedding-sdk-ee/metabot/hooks/use-metabot.tsx 的mapMessage函数中const mapMessage ( message: PublicChatMessage, cache: Mapstring, ReturnTypetypeof createChartComponent, authConfig: MetabaseAuthConfig | undefined, ): MetabotMessage match(message) .with( { role: user, type: text }, ({ id, message }) ({ id, role: user, type: text, message }) as const, ) .with( { role: agent, type: text }, ({ id, message }) ({ id, role: agent, type: text, message }) as const, ) .with( { role: agent, type: data_part, part: { type: data-generated_entity, data: { type: card } }, }, ({ id, part }) { const questionPath Urls.generatedCard(part.data); const Chart authConfig ? getCachedChartComponent(questionPath, cache, authConfig) : FallbackChartComponent; return { id, role: agent, type: chart, questionPath, Chart, } as const; }, ) .exhaustive();从这段实现可以看出当内部部件匹配{ role: agent, type: text }时直接原样映射为公开的MetabotAgentTextMessage保留id与message当内部部件是data_part且数据为generated_entity卡片时会被转换成语义完全不同的MetabotAgentChartMessage借助Urls.generatedCard(part.data)生成questionPath形如/question#base64的 URL并缓存创建出一个预先接线的 React 图表组件Chart使用ts-pattern的matchexhaustive()保证所有公开消息形态都被穷尽处理新增类型时编译期即可发现遗漏分支。因此MetabotAgentTextMessage是对话流中Agent 用自然语言回答问题这一场景的标准载体而图表消息则对应Agent 直接给出可视化结果。消费入口useMetabot 与 UseMetabotResultMetabotAgentTextMessage通常不是单独使用的而是通过useMetabotHook 从对话状态中读取。关联文档 useMetabot.md 给出其签名与基本用法function useMetabot(): UseMetabotResult | null;useMetabot返回 Metabot 对话 API在 SDK bundle 加载完成、MetabaseProvider挂载其内部订阅器之前返回null因此使用前必须做空值守卫例如const metabot useMetabot(); if (!metabot) { return Spinner /; } metabot.submitMessage(Show me orders);返回对象UseMetabotResult见 UseMetabotResult.md中包含对话消息数组与一系列操作函数属性类型说明messagesMetabotMessage[]对话中的全部消息图表消息包含Chart属性errorMessagesMetabotErrorMessage[]会话级错误不挂在单条消息上submitMessage(message: string) Promisevoid向对话提交一条新消息retryMessage(messageId: string) Promisevoid回退到messageId之前的用户消息并重新提交丢弃该 Agent 消息及其之后的内容cancelRequest() void取消当前进行中的请求resetConversation() void清空所有消息、重新开始isProcessingboolean从提交消息到响应完成含成功、失败、取消期间为truecontextWindowPercentUsagenumber对话占用的模型上下文窗口比例取值 0–100isContextWindowFullboolean对话是否已耗尽整个上下文窗口CurrentChartComponentTypeMetabotChartProps \| null绑定到 Agent 最新产出图表的预接线组件未产出图表时为nullmessages数组正是MetabotAgentTextMessage出现的场所。结合 use-metabot.tsx 的实现messages由内部agent.messages展开所有 parts、过滤出公开部件并逐条mapMessage得到同时每个 turn 只保留最后一张图表getFinalChartMessageIdsPerTurn因为 Agent 在流式输出过程中可能发出多张中间图表。在 Hook 内部submitMessage调用的是agent.submitInput(message, { preventOpenSidebar: true })——即通过 SDK 提交消息时不会弹出产品内边栏保证行为完全由宿主应用控制resetConversation在清空对话的同时还会清空图表组件缓存errorMessages来自内部消息状态status.type errored的展示信息类型为MetabotErrorMessage{ message: string; type: message | alert | locked }alert会以警告图标与错误色渲染message以纯文本渲染。实战如何在自定义聊天界面中渲染并区分 Agent 文本消息借助判别联合与字面量类型可以在渲染层用极少的代码安全区分消息形态。以下示例展示了如何基于type字段收窄联合类型并分别渲染文本气泡与图表卡片import { useMetabot } from metabase/embedding-sdk-react; import type { MetabotMessage } from metabase/embedding-sdk-react; function ChatThread() { const metabot useMetabot(); if (!metabot) { return Spinner /; // SDK 尚未就绪时的守卫 } return ( div {metabot.messages.map((msg) ( MessageBubble key{msg.id} message{msg} / ))} /div ); } function MessageBubble({ message }: { message: MetabotMessage }) { // 判别收窄按 type 区分三种消息形态 if (message.type text message.role agent) { // MetabotAgentTextMessage渲染 Agent 的文本回复 return div classNameagent-bubble{message.message}/div; } if (message.type text message.role user) { // MetabotUserTextMessage渲染用户提问 return div classNameuser-bubble{message.message}/div; } // MetabotAgentChartMessage渲染 Agent 生成的图表 return message.Chart /; }这段代码体现的关键实践用type字段收窄联合类型下的msg.type只有text与chart两种取值再配合role即可把text分支进一步细分为用户消息与 Agent 消息TypeScript 会为每个分支补全正确的字段类型无需任何类型断言图表消息直接渲染组件message.Chart是预接线组件可直接以 JSX 形式渲染。Chart 组件内部按drills属性决定使用静态问题StaticQuestionInternal还是可交互问题InteractiveQuestionInternaldrills{false}默认渲染静态图表drills{true}渲染带下钻交互的图表对应类型 MetabotChartProps.md 中OmitStaticQuestionProps, ...与OmitInteractiveQuestionProps, ...的联合守卫nulluseMetabot返回null时先渲染加载占位避免在订阅器未挂载时访问未就绪的对话状态。除消息渲染外还可以组合UseMetabotResult的其他能力实现完整对话交互用submitMessage发送用户输入、用isProcessing显示输入中的加载态、用isContextWindowFull提示上下文已满并引导用户resetConversation、用retryMessage(msg.id)实现单条回复的重试该函数会回退到目标 Agent 消息之前的用户消息并重新提交目标消息及其之后的内容会被丢弃。高级话题上下文窗口、错误与会话状态理解MetabotAgentTextMessage所处的运行时环境有助于正确设计 UI上下文窗口管理contextWindowPercentUsage表示当前对话占用的模型上下文比例0–100。当isContextWindowFull为true时对话已耗尽上下文继续提问可能无法获得有效回答应提示用户开启新会话调用resetConversation。注意所有useMetabot实例在同一个应用内共享对话状态都读取同一份 Redux 状态因此在多个组件中挂载 Hook 不会产生独立的会话。会话级错误模型errorMessages是会话级的不附着在单条消息上。它来自内部消息的errored状态类型为 MetabotErrorMessage.md 中定义的message | alert | locked三态alert用于需要醒目警告的错误message用于普通文本提示。重试语义retryMessage(messageId)的messageId应传入 Agent 消息的id即MetabotAgentTextMessage.id。它会把会话回滚到该 Agent 消息之前的用户消息并重新提交属于整轮回退重试而非单条替换。企业版能力useMetabot的完整实现挂载在METABOT_SDK_EE_PLUGIN插件上见 use-metabot.tsx源码位于enterprise/目录说明 Metabot 对话属于 Metabase 企业版/嵌入能力开源OSS版本中该插件未激活时useMetabot不提供完整功能。如果不想完全自绘聊天界面也可以直接使用 SDK 现成的 MetabotQuestion 组件——它接收 MetabotQuestionProps 并渲染一个完整的 metabot 问题界面支持layoutauto/sidebar/stacked其中auto在移动端使用stacked、大屏使用sidebar、isSaveEnabled是否显示保存按钮、targetCollection保存到指定集合隐藏保存弹窗的集合选择器等配置而useMetabot面向的是需要完全自定义界面的场景MetabotAgentTextMessage正是这种场景下处理 Agent 文本回复的类型基石。小结MetabotAgentTextMessage看似只是一个四字段的小类型却是整个 Metabot 对话消息体系的关键一环它以role: agent与type: text两个字面量参与MetabotMessage判别联合让 TypeScript 在渲染层能安全地收窄消息形态它由 use-metabot.tsx 中的mapMessage从内部消息部件映射而来与图表消息MetabotAgentChartMessage共同构成 Agent 的两类回复。掌握它的结构、在联合类型中的位置以及useMetabot/UseMetabotResult的消费方式即可在嵌入应用中构建类型安全的自定义 AI 聊天体验。【免费下载链接】metabaseThe easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart:项目地址: https://gitcode.com/GitHub_Trending/me/metabase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价