본문으로 건너뛰기

MapLibre 지도에 Kaleidr Chat 연결하기

이 가이드를 마치면 MapLibre GL JS 지도 안에 채팅 패널을 배치한 페이지가 완성됩니다. 방문자가 질문하면 답변이 패널에 순차적으로 표시되고, 답변 속 장소가 MapLibre 지도에 핀으로 나타나며 카메라가 이동해 해당 장소를 보여줍니다. Free를 포함한 모든 요금제에서 게시 가능 키로 사용할 수 있습니다. 질문할 때 조직의 AI 크레딧이 소비됩니다.

패널은 지도에서 이미 사용 중인 스타일 그대로 작동하며 스타일이나 타일 소스를 변경하지 않습니다.

시작하기 전에​

  • kaleidr.com/api-keys에서 발급하고 Chat에 필요한 ai 범위가 포함된 Kaleidr 게시 가능 키(kld_pk_live_…). API 키 발급 참고.
  • 제한이 있다면 페이지 출처가 키에 허용되어야 합니다. 로컬 테스트에서는 http://localhost:8080 등을 추가합니다.
  • MapLibre 스타일 URL. 예제는 공개 데모 스타일을 사용하므로 운영 환경에서는 자체 스타일을 사용하세요.
  • script 태그로 MapLibre GL JS를 로드하여 window.maplibregl이 있어야 합니다. npm으로 가져올 경우 라이브러리를 페이지 전역에 노출하기를 참고하세요.
  • npx serve 또는 python -m http.server 8080 같은 HTTP 서버. 디스크에서 직접 열면 동작하지 않습니다.
  • 콘텐츠 보안 정책이 있다면 콘텐츠 보안 정책의 호스트를 허용하세요.

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>

예상 결과: 아직 지도는 보이지 않고 높이 520px의 빈 영역만 생깁니다. 테마 및 레이아웃에서 각 설정을 설명합니다.

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 객체로, 직접 추가한 마커와 별도로 관리됩니다.
  • 경로는 패널이 스타일에 추가하는 소스 및 레이어로 그려지고 이후 제거됩니다. 사용자의 기존 소스와 레이어는 변경되지 않습니다.
  • 패널이 마운트된 동안 세션은 자동으로 갱신됩니다. 토큰을 직접 관리하지 않아도 됩니다.

작동 확인하기​

페이지에서

  • Ask Kaleidr 입력 막대가 지도 왼쪽 위에 표시됩니다.
  • Show me three museums in London을 입력하고 Enter를 누르세요. 답변이 순차적으로 표시되고 핀 3개가 생기며 지도가 모든 핀을 보여줍니다.

콘솔에서

  • [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 definedkaleidr.js보다 코드가 먼저 실행됐습니다. async나 defer가 원인일 수 있습니다.kaleidr.js를 일반 script 태그로 먼저 로드하거나 스크립트의 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 참조를 확인하세요. 그 외 레이블은 영어입니다.
  • Chat 마운트에서 handle.setCamera()는 경고만 남기고 작동하지 않습니다. MapLibre API로 카메라를 움직이세요.
  • 단일 페이지 앱에서 지도의 뷰가 사라질 때 handle.destroy()를 호출하고 다시 표시될 때 재마운트하세요.
  • 채팅 패널은 기본 지도를 제공하지 않습니다. Kaleidr 기본 지도는 별도 요소에서 렌더링되는 Tile을 사용하세요. 채팅은 map-target으로 이 요소를 제어할 수 있습니다.

전체 목록은 기능과 제한에 있습니다.

다음 단계​