DEVELOPMENT TOOL

NAA Tour API 테스트

실제 LLM을 호출합니다. API Key와 요청 본문은 브라우저에 저장하지 않습니다.

샘플 요청을 불러오는 중입니다.

현재 API 설명·규율·명세 책임 경계, 생성·재생성 규칙, 요청·응답·오류 계약 POST /v1/tour/course

현재 구현 계약

NAA 현재 구현spaceContext의 공간 그래프와 scenes 선택 범위 안에서 Survey와 free_text를 반영한 XR 투어 정차 순서와 Action을 생성합니다. 응답은 XROO가 실행할 themeId와 Scene별 Action만 포함하며, 실제 이동 렌더링이나 좌표 기반 waypoint는 반환하지 않습니다.

책임 경계: 서버는 요청의 spaceContext.scenes[].links[].destSceneID를 방향성 이동 제약으로 사용하며, 이 Link로 연결된 Scene 순서만 허용합니다. XROO 클라이언트는 반환된 Scene 전환과 Action을 실행합니다. 별도 Transit Scene을 자동 삽입하지 않으며, 응답의 모든 Scene은 설명이 있는 실제 정차 지점입니다.

처리 흐름

  1. 요청 크기·인증·JSON 필드와 spaceContext의 Scene·Theme·Link 참조를 검증합니다.
  2. scenes를 닫힌 선택 범위로 삼고, 요청 Scene 전체에서 공통으로 사용할 수 있는 Theme을 결정합니다.
  3. history를 후보에서 제외하고 초기 또는 현재 Scene 기준으로 도달 가능한 후보와 첫 Scene 정책을 계산합니다.
  4. 필요한 Scene 좌표가 모두 유효하면 방향성 Link별 상대 coordinateCost를 계산해 LLM에 제공합니다.
  5. LLM이 계획을 반환하면 Domain Validator가 검증합니다. Domain 검증에 실패한 경우에만 같은 후보 범위에서 한 번 Repair한 뒤 다시 검증합니다.
  6. LLM 연결·Structured Output 생성 실패는 즉시, Repair 후 Domain 검증 실패는 재검증 뒤 503 PLANNER_UNAVAILABLE로 응답합니다.

코스 생성 규율

  • 초기 생성의 첫 Scene은 반드시 spaceContext.startingSceneID입니다.
  • Scene은 scenes 안에서만 고르며 중복할 수 없습니다. 관련성이 낮으면 maxScenes보다 적게 선택할 수 있습니다.
  • 연속 Scene은 이전 Scene의 links[].destSceneID에 있어야 합니다. 벽·보행 경로를 별도 추론하지 않습니다.
  • 좌표 비용은 비슷한 의미 경로 사이의 상대 tie-breaker일 뿐입니다. 미터·시간·최단 경로를 보장하지 않습니다.
  • 모든 정차 Scene에는 공백이 아닌 DISPLAY_TEXT가 하나 이상 필요합니다.
  • 설명 근거는 Survey, free_text, Scene 제목·설명·공간 유형·매칭 관심사입니다. 이미지 분석이나 제공되지 않은 채광·크기·수납·가구 정보는 추측하지 않습니다.

재생성 규율

  • currenthistory는 함께 보내고, 재생성에서는 themeId도 필수입니다. 명시한 필드를 null로 보내지 말고 불필요하면 생략합니다.
  • history의 Scene은 후보에서 제외합니다. 중복 ID는 내부 방문 집합에서 하나로 합쳐집니다.
  • 현재 Scene이 미방문이면 응답의 첫 Scene은 current.sceneId입니다.
  • 현재 Scene이 이미 방문됐다면 첫 Scene은 현재 Scene의 직접 Link 중 남은 후보여야 합니다.
  • current.position을 생략하면 해당 Scene의 좌표를 사용합니다. 직접 보내려면 x/y/z를 모두 보냅니다.
  • 서버는 코스·방문 상태를 저장하지 않습니다. 재생성 호출자는 전체 요청 정보와 최초 scenes, 고정 themeId, 최신 current·history를 매번 다시 보냅니다.
  • 테스트 페이지는 최초 성공 코스의 전체 scenes와 Theme을 잠가 미탐색 재생성 범위를 유지합니다.

요청 필드 명세

필드필수형식·제약동작
identifier필수문자열 1..256자호출자가 제공하는 요청 식별값입니다. 서버 세션 상태에는 사용하지 않으며, 현재 접근 로그에는 원문 대신 해시만 기록합니다.
language필수ko 또는 en생성 안내 문구의 언어입니다.
scenes필수중복 없는 정수 배열, 1..5000개LLM이 정차 지점을 고를 수 있는 닫힌 범위입니다. 모든 ID는 spaceContext.scenes에 있어야 하며, 초기 요청에는 startingSceneID가 포함돼야 합니다.
survey필수family, childAges, people, spaces, lifestyle모든 하위 필드를 보냅니다. 지원하지 않는 문자열 코드를 먼저 제외한 뒤, 남은 지원 코드 기준으로 배열 중복을 금지하고 childAges 최대 8개, spaces 3개, lifestyle 2개를 적용합니다.
spaceContext필수id, 정수 startingSceneID, themes 1..256개, scenes 1..5000개, 선택 markers 최대 10000개현재 Phase의 인라인 공간정보입니다. Scene의 ID·제목·Theme Layer·방향성 Link와 선택 좌표를 검증·매핑합니다. 그 밖의 필드는 무시합니다.
free_text선택앞뒤 공백 제거 후 최대 1000자사용자가 XR 투어에서 보고 싶은 관심사 원문입니다. 공백뿐이면 없는 값으로 처리합니다.
themeId초기 선택
재생성 필수
spaceContext.themes의 정수 ID요청 Scene 전체에 공통인 Theme이어야 합니다. 초기 요청에서 생략하면 기본 Theme 또는 Theme 순서로 선택합니다.
options.maxScenes선택정수 1..6, 기본값 6응답 Scene 수의 상한입니다. 정확히 이 수를 채우라는 뜻은 아닙니다.
current재생성 필수{sceneId, position?}sceneId는 요청 scenes 안에 있어야 합니다. 위치는 선택이며 보낼 때 x/y/z를 모두 보냅니다.
history재생성 필수정수 배열, 최대 5000개실제 방문 완료 Scene 목록입니다. 모든 ID는 요청 scenes와 공간정보에 있어야 하며 다음 후보에서 제외됩니다.

Survey 지원 코드

  • family: single=1인 가구, couple=부부·커플, child=자녀가 있는 가족, parents=부모님과 함께 거주, etc=기타
  • childAges: a=영유아, b=초등학생, c=중·고등학생, d=성인 자녀
  • people: 1=1명, 2=2명, 3=3명, 4=4명, 5=5명 이상
  • spaces: living=거실, kitchen=주방·다이닝, bedroom=침실, kids=자녀방, bath=욕실, dress=드레스룸·파우더룸, pantry=팬트리·수납공간, utility=다용도실, balcony=발코니·테라스
  • lifestyle: famtime=가족이 함께 보내는 공간, kidedu=자녀 학습과 생활, wfh=재택근무·홈오피스, guest=손님 방문과 모임, pet=반려동물과 생활, hobby=취미·운동 공간, chores=편리한 가사 동선, privacy=가족 구성원별 독립 공간, none=특별히 없음

알 수 없는 요청 필드는 현재 호환성을 위해 허용하지만 Planner나 성공 응답으로 전달하지 않습니다. 필드 형태의 기계 판독 기준은 OpenAPI JSON, 실제 초기 예시는 아래 “초기 샘플 불러오기”를 사용하세요.

응답 및 Action 명세

성공 응답은 추가 필드 없이 themeId와 1..6개의 scenes만 포함합니다. 각 Scene은 {sceneId, actions} 형태이며 Action은 실행 순서대로 적용합니다.

Actionvalue의미·제약
DISPLAY_TEXT공백 아닌 문자열Scene 설명입니다. 모든 Scene에 하나 이상 필요합니다.
AROUND_360없음360도 둘러보기입니다. 객체에는 type만 둡니다.
STAY0 이상 정수밀리초 단위 대기 시간입니다.
OPEN_MARKER_CONTENTSMarker 정수 ID계약에는 있으나 현재 Marker→Scene 명시 매핑이 확정되지 않아 생성 단계에서는 허용하지 않습니다.
UPDATE_FOV30..120절대 수직 FOV 값입니다.
UPDATE_YAW-45..45, 0 제외상대 좌우 회전 각도입니다.
UPDATE_PITCH-30..30, 0 제외상대 상하 회전 각도입니다.
{
  "themeId": 12608,
  "scenes": [
    {
      "sceneId": 291441,
      "actions": [
        {"type": "DISPLAY_TEXT", "value": "거실을 살펴봅니다."},
        {"type": "AROUND_360"}
      ]
    }
  ]
}

오류·운영 계약

HTTP대표 코드발생 조건
400INVALID_INPUT필수 필드, 타입, 범위, Scene 참조, 초기·재생성 조합이 잘못된 경우
401UNAUTHORIZEDAPI Key 인증이 활성화됐고 X-API-Key가 없거나 일치하지 않는 경우
413PAYLOAD_TOO_LARGE요청 본문이 기본 10 MiB 또는 MAX_PAYLOAD_BYTES 설정을 초과한 경우
422NO_AVAILABLE_THEME
NO_ELIGIBLE_SCENE
INVALID_SPACE_GRAPH
공통 Theme, 도달 가능한 후보, 공간 그래프 참조를 만족하지 못한 경우
500INTERNAL_ERROR인증 설정 누락 또는 처리되지 않은 서버 오류
503PLANNER_UNAVAILABLELLM 연결·Structured Output 생성이 실패한 경우 즉시, 또는 반환 계획의 Domain 검증이 1회 Repair 후에도 실패한 경우
{
  "code": "INVALID_INPUT",
  "message": "Request validation failed",
  "requestId": "요청 추적 ID",
  "details": [{"field": "scenes", "reason": "오류 원인"}]
}

인증·추적

  • API_KEY_REQUIRED=true일 때만 X-API-Key가 필수입니다.
  • 요청의 X-Request-ID를 재사용하거나 서버가 생성하며, 응답 Header와 오류 본문에 돌려줍니다.
  • 애플리케이션 자체 Rate Limit과 Pagination은 현재 없습니다.

상태 확인·테스트 페이지

  • /health/live는 프로세스 생존, /health/ready는 설정 모델이 LLM 서버에 실제 제공되는지 확인합니다.
  • 이 테스트 페이지와 샘플 Route는 TEST_PAGE_ENABLED=true일 때만 열립니다.
  • API Key와 요청 JSON은 브라우저 저장소에 보관하지 않으며 새로고침하면 초기 샘플로 돌아갑니다.

투어 요청 설정

free_text · current · history
요청 모드

사용자 관심사 원문이며, 공백이면 요청에서 제외됩니다.0/1000

서베이 선택

request.survey
자녀 연령 · 복수 선택
관심 공간 · 최대 3개
생활 방식 · 최대 2개

선택값은 즉시 아래 요청 JSON의 survey에 반영됩니다. 지원되는 선택값은 모순되어 보여도 그대로 전송됩니다.

요청 JSON

POST /v1/tour/course

선택한 JSON 객체는 spaceContext로, 포함된 Scene ID는 최상위 scenes로 입력됩니다.

응답

실행 전
아직 응답이 없습니다.

미탐색 후보는 응답 후 계산됩니다.