
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 聊天體驗?!久赓M下載鏈接】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),僅供參考