跳到主要内容

将 Kaleidr Chat 连接到 MapLibre 地图

完成本指南后,网页将展示 MapLibre GL JS 地图以及嵌入地图的聊天面板。访客提问时,回答会逐步显示在面板中,其中的地点作为标记出现在 MapLibre 地图上,相机也会移动以展示这些位置。所有套餐(包括 Free)都支持,只需要可公开使用的密钥。提问会消耗组织的 AI 点数。

面板沿用地图当前的样式,不会更改样式或瓦片数据源。

开始之前​

  • 从 kaleidr.com/api-keys 获取包含 ai 权限的 Kaleidr 可公开使用的密钥(kld_pk_live_…)。参阅获取 API 密钥。
  • 如果密钥限制来源,网页来源必须在允许列表中;本地开发可添加 http://localhost:8080。
  • MapLibre 样式 URL。示例使用 MapLibre 公开演示样式;生产环境应使用自己的样式。
  • 通过 script 加载 MapLibre GL JS,保证存在 window.maplibregl。从 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 步:加载 MapLibre GL JS 并创建地图​

在网页 head 中加载样式表,并在自己的代码前加载脚本。两个 URL 必须指向相同版本。

<link rel="stylesheet" href="https://unpkg.com/maplibre-gl@5.17.0/dist/maplibre-gl.css" />
<script src="https://unpkg.com/maplibre-gl@5.17.0/dist/maplibre-gl.js"></script>
<script>
const map = new maplibregl.Map({
container: 'map',
style: 'https://demotiles.maplibre.org/style.json', // your own style here
center: [-0.12, 51.5],
zoom: 11,
});
</script>

**预期结果:**地图可以拖动和缩放。演示样式只是城市细节较少的简化国家地图,但地点标记和相机移动仍会正常工作。

第 3 步:加载 kaleidr.js​

在 MapLibre 脚本之后、挂载聊天面板的代码之前加入 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 MapLibre</title>
<link rel="stylesheet" href="https://unpkg.com/maplibre-gl@5.17.0/dist/maplibre-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://unpkg.com/maplibre-gl@5.17.0/dist/maplibre-gl.js"></script>
<script src="https://cdn.kaleidr.com/embed/v1/kaleidr.js"></script>
<script>
const map = new maplibregl.Map({
container: 'map',
style: 'https://demotiles.maplibre.org/style.json',
center: [-0.12, 51.5],
zoom: 11,
});

const handle = Kaleidr.mount('#chat', {
product: 'chat',
publishableKey: 'kld_pk_live_…',
map,
contained: true,
});
</script>
</body>
</html>

工作原理​

访客操作聊天面板MapLibre 地图
提交问题展开聊天窗口,逐步显示回答文本。暂无变化。
等待回答为回答中的每个地点显示一张结果卡片。每找到一个地点就显示标记。只有一个地点时,相机飞向该位置;多个地点时,调整视野并留出空间避开聊天面板。
点击标记或结果打开包含概况、照片和路线工具的地点卡片。点击结果将相机移动到该地点。
请求路线显示路线距离和耗时。绘制并框选路线。
继续提问在同一对话中追加消息。新标记被添加,旧标记保留。
关闭聊天恢复到输入栏并结束对话。删除标记和路线。

MapLibre GL JS 的具体行为:

  • 标记使用包含 HTML 元素的 MapLibre Marker 对象,与您自行添加的标记相互独立。
  • 路线使用面板向样式添加的 source 和 layer 绘制,之后会被移除。您自己的数据源和图层不会被更改。
  • 面板挂载期间会在后台续期会话,您无需管理令牌。

检查是否正常工作​

在网页中

  • Ask Kaleidr 输入栏显示在地图左上角。
  • 输入 Show me three museums in London 并按 Enter,回答文字逐步出现,地图上显示三个标记并调整视野以容纳它们。

在控制台中

  • 没有包含 [kaleidr 的错误或警告。

在 Network 面板中

请求预期结果
GET https://cdn.kaleidr.com/embed/v1/kaleidr.js200
GET https://cdn.kaleidr.com/embed/v1/chat.js200
POST https://api.kaleidr.com/inference-api/b2b/v1/sdk/sessions200,返回类似下方示例的 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 参数传入的对象未被识别。传入真正的 maplibregl.Map 实例。参阅支持的地图。
相机能飞向单个地点,但无标记且无法框选多个地点不存在 window.maplibregl。单地点移动只需地图对象,标记和多地点适配需要全局对象。如果从 npm 导入 MapLibre,请在挂载前设置 window.maplibregl。参阅npm 导入。
面板始终显示“Sorry — that didn't go through. Please try again.”密钥被撤销或允许来源发生变化,导致会话失效。检查密钥并刷新网页。
面板显示“You've reached your usage limit for now.”429 错误:组织的 AI 点数耗尽或密钥触发速率限制。同一密钥的所有访客共享速率上限。参阅配额和速率限制。
无法拖动地图聊天层拦截了地图交互。为 #chat 添加 pointer-events:none。

更多问题请参阅故障排查。

限制​

  • 网页不会从聊天面板收到回调或事件,因此不能通过代码响应提问、回答或标记点击。
  • 助手无法看到您的图层、标记或当前地图可视区域。提问时仅发送缩放级别。
  • 不能通过聊天面板向助手提供自定义指令或自己的数据。
  • 回答语言、面板标题和输入框占位文字是挂载选项(lang、title、placeholder),详见 Chat 参考文档。其他界面标签为英文。
  • 对聊天挂载调用 handle.setCamera() 不起作用,且会输出警告。请使用 MapLibre 自身的 API 移动相机。
  • 在单页应用中,地图视图移除时调用 handle.destroy(),视图返回时再重新挂载。
  • 聊天面板不会提供底图。如需显示 Kaleidr 底图,请使用在独立元素中渲染的 Tile,聊天面板可通过 map-target 控制该元素。

完整清单见功能和限制。

后续步骤​