將 Kaleidr Chat 連接到 Mapbox 地圖
完成本指南後,網頁將展示 Mapbox GL JS 地圖以及嵌入地圖的聊天面板。訪客提問時,回答會逐步顯示在面板中,其中的地點作為標記出現在 Mapbox 地圖上,相機也會移動以展示這些位置。所有套餐(包括 Free)都支持,只需要可公開使用的金鑰。提問會消耗組織的 AI 點數。
開始之前
- 從 kaleidr.com/api-keys 取得 Kaleidr 可公開使用的金鑰(
kld_pk_live_…)。新金鑰預設帶有聊天所需的ai權限。參閱取得 API 金鑰。 - 如果金鑰設定了允許來源,網頁來源必須包含在該列表中。本地開發可添加
http://localhost:8080。 - 從 Mapbox 賬戶取得 Mapbox 訪問令牌(
pk.…)。Mapbox 對地圖收費,Kaleidr 對提問收費,二者互不影響。 - 通過 script 標籤載入 Mapbox GL JS,保證存在
window.mapboxgl。如果從 npm 匯入 Mapbox,請先閱讀將 npm 庫公開為頁面全局對象。 - 通過 HTTP 提供網頁,例如
npx serve或python -m http.server 8080。不能直接從磁盤打開文件。 - 如果網站設定了內容安全策略,請允許內容安全策略中列出的主機。
第 1 步:佈置地圖和聊天層
將地圖和聊天掛載目標放在同一個定位容器中。聊天層覆蓋在地圖上方,但允許指針事件穿透。
<div id="mapHost" style="position:relative; height:520px">
<div id="map" style="position:absolute; inset:0; z-index:0"></div>
<div id="chat" style="position:absolute; inset:0; z-index:1; pointer-events:none"></div>
</div>
**預期結果:**此時還沒有地圖,只顯示一個高度為 520 px 的空白塊。主題與佈局解釋了各項聲明的作用。
第 2 步:載入 Mapbox GL JS 並創建地圖
在網頁 head 中載入樣式表,並在自己的程式碼之前載入腳本。樣式表必不可少,否則地圖無法正確顯示。
<link rel="stylesheet" href="https://api.mapbox.com/mapbox-gl-js/v3.9.4/mapbox-gl.css" />
<script src="https://api.mapbox.com/mapbox-gl-js/v3.9.4/mapbox-gl.js"></script>
<script>
mapboxgl.accessToken = 'pk.…';
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v12',
center: [-0.12, 51.5],
zoom: 11,
});
</script>
**預期結果:**顯示倫敦市中心的 Mapbox 地圖,可以拖動和縮放。
第 3 步:載入 kaleidr.js
在 Mapbox 腳本之後、掛載聊天面板的程式碼之前加入 Kaleidr 載入器。
<script src="https://cdn.kaleidr.com/embed/v1/kaleidr.js"></script>
**預期結果:**網頁不會發生明顯變化。在控制台中,Kaleidr.version 會傳回版本字符串。
第 4 步:掛載聊天面板
傳入金鑰和實際運行的地圖對象。
const handle = Kaleidr.mount('#chat', {
product: 'chat',
publishableKey: 'kld_pk_live_…',
map,
contained: true,
});
無需等待地圖的 load 事件。Kaleidr.mount 會立即傳回;聊天程序包載入完成且金鑰交換為會話後,面板就會出現。
**預期結果:**地圖左上角出現寫有“Ask Kaleidr”的輸入欄。
完整頁面
將文件保存為 index.html,替換兩個金鑰並通過 HTTP 提供文件夾。
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Kaleidr Chat on Mapbox</title>
<link rel="stylesheet" href="https://api.mapbox.com/mapbox-gl-js/v3.9.4/mapbox-gl.css" />
<style>
body { margin: 0; font-family: system-ui, sans-serif; }
#mapHost { position: relative; height: 100vh; }
#map { position: absolute; inset: 0; z-index: 0; }
#chat { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
</style>
</head>
<body>
<div id="mapHost">
<div id="map"></div>
<div id="chat"></div>
</div>
<script src="https://api.mapbox.com/mapbox-gl-js/v3.9.4/mapbox-gl.js"></script>
<script src="https://cdn.kaleidr.com/embed/v1/kaleidr.js"></script>
<script>
mapboxgl.accessToken = 'pk.…';
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v12',
center: [-0.12, 51.5],
zoom: 11,
});
const handle = Kaleidr.mount('#chat', {
product: 'chat',
publishableKey: 'kld_pk_live_…',
map,
contained: true,
});
</script>
</body>
</html>
工作原理
| 訪客操作 | 聊天面板 | Mapbox 地圖 |
|---|---|---|
| 提交問題 | 展開聊天窗口,逐步顯示回答文本。 | 暫無變化。 |
| 等待回答 | 為回答中的每個地點顯示一張結果卡片。 | 每找到一個地點就顯示標記。只有一個地點時,相機飛向該位置;多個地點時,調整視野並留出空間避開聊天面板。 |
| 點擊標記或結果 | 打開包含概況、照片和路線工具的地點卡片。 | 點擊結果將相機移動到該地點。 |
| 要求路線 | 顯示路線距離和耗時。 | 繪制並框選路線。 |
| 繼續提問 | 在同一對話中追加消息。 | 新標記被添加,舊標記保留。 |
| 關閉聊天 | 恢復到輸入欄並結束對話。 | 刪除標記和路線。 |
Mapbox GL JS 的具體行為:
- 標記使用包含 HTML 元素的 Mapbox
Marker對象,與您自行添加的標記相互獨立。 - 路線使用面板向樣式添加的 source 和 layer 繪制,之後會被移除。您自己的資料源和圖層不會被更改。
- 面板掛載期間會在背景續期會話,您無需管理令牌。
檢查是否正常工作
在網頁中
- Ask Kaleidr 輸入欄顯示在地圖左上角。
- 輸入
Show me three museums in London並按 Enter,回答文字逐步出現,地圖上顯示三個標記並調整視野以容納它們。
在控制台中
- 沒有包含
[kaleidr的錯誤或警告。
在 Network 面板中
| 要求 | 預期結果 |
|---|---|
GET https://cdn.kaleidr.com/embed/v1/kaleidr.js | 200 |
GET https://cdn.kaleidr.com/embed/v1/chat.js | 200 |
POST https://api.kaleidr.com/inference-api/b2b/v1/sdk/sessions | 200,傳回類似下方示例的 JSON |
POST https://api.kaleidr.com/inference-api/b2b/v1/chat/control/stream(提問後) | 200,content-type: text/event-stream |
{ "session_token": "kld_sess_live_…", "expires_in": 900, "product": "chat" }
無法正常工作時
SDK 會記錄簡短信息,不會重復伺服器給出的詳細原因。要求失敗時,請在 Network 面板中打開它並查看 JSON 響應。403 和 404 的錯誤程式碼位於 detail;429 的程式碼位於 error,說明文字位於 detail。
| 現象 | 原因 | 解決方法 |
|---|---|---|
無面板,控制台提示 …/sdk/sessions 的 CORS 錯誤和 [kaleidr:chat] 錯誤 | 金鑰無效、已撤銷或網頁來源未被允許。API 僅為允許的來源傳回 CORS 頭。 | 檢查金鑰,並在 kaleidr.com/api-keys 添加完整來源,包括協議和端口。 |
[kaleidr:chat] kaleidr session exchange failed (403) | 金鑰有效,但無權打開 Chat。detail 可能為 insufficient_scope(缺少 ai)、product_not_allowed(僅限其他產品)或 tier_capability_not_allowed。 | 使用包含 ai 且允許 chat 產品的金鑰。 |
[kaleidr:chat] Kaleidr: a server key (kld_sk_…) must never be used in the browser … | 傳入了伺服器金鑰,因此未傳送要求。 | 使用可公開使用的金鑰(kld_pk_live_…)。如伺服器金鑰曾出現在公開網頁中,請撤銷它。 |
[kaleidr:chat] mount target not found: #chat | 選 擇器找不到目標。 | 在目標元素存在後再調用 mount,或直接傳入元素。 mount |
[kaleidr:chat] [kaleidr] failed to load https://cdn.kaleidr.com/embed/v1/chat.js | 程序包被內容安全策略或廣告攔截器阻止。 | 在 script-src 中允許 https://cdn.kaleidr.com。 |
Kaleidr is not defined | 程式碼早於 kaleidr.js 執行,例如腳本使用 async 或 defer。 | 先用普通 script 標籤載入 kaleidr.js,或在腳本 load 事件中運行程式碼。 |
[kaleidr] embed is disabled — … | 啓用控制阻止了掛載。 | 消息會說明由哪個設定引起。參閱 kaleidr.js。 |
| 面板位於瀏覽器窗口左上角,而不是地圖上方 | 缺少 contained,或 #chat 未定位。 | 添加 contained: true 和第 1 步的樣式。 |
| 面板能回答,但不顯示標記,地圖也不移動 | map 參數傳入的對象未被識別。 | 傳入真正的 mapboxgl.Map 實例。參閱支持的地圖。 |
| 相機能飛向單個地點,但無標記且無法框選多個地點 | 不存在 window.mapboxgl。單地點移動只需地圖對象,標記和多地點適配需要全局對象。 | 如果從 npm 匯入 Mapbox,請在掛載前設定 window.mapboxgl。參閱npm 匯入。 |
| 面板始終顯示“Sorry — that didn't go through. Please try again.” | 金鑰被撤銷或允許來源發生變化,導致會話失效。 | 檢查金鑰並刷新網頁。 |