콘텐츠로 이동

Dialogue Manager API Schema

이 문서는 현재 dm/api/schemas/의 Pydantic model과 route의 실제 소비 방식을 함께 설명합니다.

표의 열

의미
Type Pydantic field type
Default field 생략 시 model 기본값
Schema required OpenAPI/Pydantic가 field 누락을 거부하는지
Operational required 정상 service 처리에 실질적으로 필요한지
Consumed 현재 route 또는 Dialogue Manager가 실제로 읽는지

현재 model은 대부분 기본값을 선언하므로 OpenAPI상 required field가 거의 없습니다. 이는 빈 문자열이나 빈 object로도 정상 처리된다는 뜻은 아닙니다.

POST request body 자체는 필수입니다. 최상위 request model의 field는 모두 기본값이 있어 생략할 수 있지만, object 형식의 ChatbotSessionLocation을 선택하면 그 안의 latitudelongitude는 모두 필수입니다. Model에 정의되지 않은 추가 field는 현재 Pydantic 기본 설정에 따라 무시됩니다.


1. Active schema와 endpoint

Schema Request/Response 사용 endpoint
ChatbotSessionCreateRequest Request POST /v1/session, POST /v1/session/json
ChatbotSessionUser Nested request ChatbotSessionCreateRequest.user
ChatbotSessionCreateResponse Response POST /v1/session
ChatbotSessionLocation Nested request ChatbotSessionUser.location
CompletionOptions Nested request/response Session 생성 request와 response
ChatbotValidateRequest Request POST /v1/session/validate
ChatbotValidateResponse Response POST /v1/session/validate
ChatbotRequest Request POST /v1/message
UserInput Nested request ChatbotRequest.user_input
MessageInput Nested request ChatbotRequest.message_input
RequeryContext Nested request MessageInput.requery_context
ChatbotMessageResponse Response POST /v1/message, POST /v1/session/json
ChatbotFinalData Nested response ChatbotMessageResponse.final_data
ChatbotSessionInfoResponse Response GET /v1/session/{session_id}

2. Session 생성 request

ChatbotSessionCreateRequest

Field Type Default Schema required Operational required Consumed
user ChatbotSessionUser {} 아니오 아니오 두 endpoint 모두 사용
scenario_name string "" 아니오 /session에서는 예 /session만 사용
llm_choice string "" 아니오 아니오 두 endpoint 모두 사용
nlu_llm_choice string "" 아니오 아니오 두 endpoint 모두 사용
user_system_prompt string "" 아니오 아니오 두 endpoint 모두 사용
bot_first boolean \| null null 아니오 아니오 두 endpoint 모두 사용
max_fallback_retries integer \| null (>= 0) null 아니오 아니오 두 endpoint 모두 사용
stt_confidence_threshold number -0.7 아니오 아니오 두 endpoint 모두 사용
completion_options CompletionOptions 아래 기본값 아니오 아니오 두 endpoint 모두 사용
scenario_graph object {} 아니오 /session/json에서는 예 /session/json만 사용

같은 model을 두 endpoint가 서로 다르게 사용합니다.

Endpoint 사용 field 무시 field
/v1/session user, scenario_name, model choices, user prompt, bot_first, max_fallback_retries, stt_confidence_threshold, completion_options scenario_graph
/v1/session/json user, scenario_graph, model choices, user prompt, bot_first, max_fallback_retries, stt_confidence_threshold, completion_options scenario_name

bot_first를 요청에서 생략하면 graph.bot_first를 사용하며, 시나리오에도 설정이 없으면 false입니다. 요청값이 시나리오 설정보다 우선합니다. 기존 시나리오와의 호환을 위해 scenario JSON의 metadata.bot_first도 fallback으로 지원합니다.

max_fallback_retries를 지정하면 일반 노드의 params.max_fallback_retries보다 우선합니다. 생략하면 노드 설정, 노드에도 없으면 기본값 3을 사용합니다. 단, 종료 노드가 fallback을 즉시 통과시키려고 선언한 max_fallback_retries: 0은 세션값으로 덮어쓰지 않습니다.

stt_confidence_threshold는 세션별 STT 이해 불가 기준입니다. POST /v1/messagemessage_input.confidence가 이 값보다 작거나 같으면 LLM NLU를 실행하지 않고 dialogue_act=null인 이해 불가 fallback으로 처리합니다. 기본값은 -0.7이며 비교에는 경계값이 포함됩니다.

두 confidence는 구분해야 합니다.

생성 주체 용도
MessageInput.confidence API client/STT NLU 실행 전 session threshold gate
NLUResult.confidence 규칙 NLU 또는 LLM NLU intent/entity 결과와 slot confidence의 내부 근거

API request에는 NLU confidence field가 없습니다. Low-STT 경로에서는 내부 NLUResult.confidence에 전달된 STT 값을 복사하지만, 일반 경로의 NLU confidence와 의미가 같아지는 것은 아닙니다.

MessageInput.confidence 자체의 기본값은 0.0이며 route는 field가 생략돼도 이 기본값을 전달합니다. 따라서 session threshold가 0이면 confidence를 생략한 message도 low-confidence fallback 대상입니다. 반면 키보드 CLI의 turn은 input_confidence=None을 전달하므로 STT gate를 적용하지 않습니다.

CompletionOptions

Field Type Default 의미
include_slots boolean true 종료 응답의 final_data.slots 포함
include_history boolean false 종료 응답의 final_data.conversation_history 포함

전체 대화는 개인정보와 payload 크기를 고려해 opt-in입니다. 이 설정은 세션별로 SessionManager에 저장되며 session_complete=true인 응답에만 적용됩니다.

ChatbotSessionUser

ChatbotSessionCreateRequest.user 아래에 들어가는 사용자 정보입니다. 실제로 전달된 값만 session 설정과 DialogueState.context.session_user에 저장하며 NLU/NLG의 개인화 context로 사용합니다. 빈 기본값은 저장하지 않습니다.

Field Type Default 설명
id string "" 사용자 ID
name string "" 사용자 이름
age integer \| null null 사용자 나이
location string \| ChatbotSessionLocation "" 도시명 또는 WGS84 좌표
profile object {} 선호 언어, 관심사, 케어 레벨 등 구조화된 profile
locale string "" 사용자 locale. 예: ko-KR
timezone string "" 사용자 timezone. 예: Asia/Seoul
date_time string "" 날짜 기반 Skill에 전달할 ISO 8601 일시. 빈 값은 session 생성 중 사용자 timezone 또는 서버 timezone의 현재 일시로 채움
metadata object {} backend가 추가로 전달하는 확장 metadata

ChatbotSessionLocation

ChatbotSessionUser.location을 좌표 object로 전달할 때 사용하는 model입니다. 위치 기반 Skill에는 검증된 좌표만 전달되며 accuracy 같은 정의되지 않은 추가 field는 무시됩니다.

Field Type Default Schema required 허용 범위 의미
latitude number 없음 -90 이상 90 이하 WGS84 위도
longitude number 없음 -180 이상 180 이하 WGS84 경도

예:

{
  "location": {
    "latitude": 37.5172,
    "longitude": 127.0473
  }
}

좌표 대신 "서울시 강남구" 같은 문자열 위치도 계속 지원합니다. 좌표 object를 사용할 때는 latitudelongitude를 모두 전달해야 합니다.

scenario_name

허용 값은 Pydantic enum이 아니라 runtime map으로 관리하며 대소문자를 구분하지 않습니다.

등록 파일
senimate senimate.json
card_issuance card_issuance.json
call_for_fire call_for_fire.json
dental_caries_case1 dental_caries_case1.json

다른 문자열도 Pydantic validation은 통과하지만 scenario lookup에서 실패합니다.


3. Session 생성 response

ChatbotSessionCreateResponse

Field Type Default 의미
session_id string "" 생성된 session ID
message string "Session created" 생성 결과 message
llm_choice string "" request에서 받은 NLG model 값
nlu_llm_choice string "" request에서 받은 NLU model 값
user_system_prompt string "" request에서 받은 사용자 prompt
completion_options CompletionOptions {include_slots: true, include_history: false} 적용할 종료 payload 설정
initial_response string "" session 생성 직후 첫 bot response
initial_current_node string "" 첫 턴 transition 적용 후 current node
initial_turn_count integer 0 첫 응답 처리 후 turn count
initial_processing_time_ms number 0.0 첫 bot response 준비 시간(ms)
initial_session_complete boolean false 첫 턴 직후 완료 여부

Model field는 모두 기본값을 갖지만 route가 모든 field를 명시해서 반환합니다.

llm_choicenlu_llm_choice는 실제 resolved session config가 아니라 request field를 그대로 반환합니다. 빈 문자열 요청 시 내부 적용값과 response 표시값이 다를 수 있습니다.


4. Scenario validation

ChatbotValidateRequest

Field Type Default Schema required Operational required Consumed
scenario_graph object {} 아니오

ChatbotValidateResponse

Field Type Default 허용되는 현재 값 의미
status string "" success, error validation 결과
message string "" configured message 사용자용 결과 문구

status는 enum으로 강제되지 않습니다. Graph validation 실패도 현재 HTTP 200이며 body의 status로 구분합니다.


5. Message request

ChatbotRequest

Field Type Default Schema required Operational required Consumed
session_id string "" 아니오
user_input UserInput UserInput 아니오 아니오 현재 route에서 미사용
message_input MessageInput MessageInput 아니오 textconfidence 사용

UserInput

Field Type Default 현재 소비 의미
id string "" 미사용 외부 사용자 ID
name string "" 미사용 사용자 이름
age integer 0 미사용 사용자 나이

Schema는 Voice AI client의 사용자 metadata를 받을 수 있지만 현재 message route는 이 object를 DialogManager에 전달하지 않습니다.

MessageInput

Field Type Default 현재 소비 의미
text string "" 사용 STT가 만든 사용자 발화 text
confidence number 0.0 사용 세션 threshold와 비교하는 STT 인식 신뢰도
duration number 0.0 미사용 발화 길이(초)
emotion string "" 미사용 발화와 함께 전달된 감정
requery_required boolean false 미사용 Client가 재질문이 필요하다고 판단했는지 여부
requery_context RequeryContext 빈 context 미사용 재질문 식별자, 원인과 연속 시도 횟수

confidence에는 0~1 범위 제한이 없고 duration에도 0 이상 제한이 없습니다. emotiontrigger_type도 enum이 아닌 일반 문자열입니다. 따라서 음수 duration이나 임의의 emotion/trigger 값도 현재 schema validation을 통과합니다.

RequeryContext

Field Type Default 의미
requery_id string "" 연속 재질문 요청을 묶는 식별자
trigger_type string "" 예: LOW_CONFIDENCE_STT
consecutive_attempt integer 0 동일 재질문의 연속 시도 횟수. 0 이상

현재 실제 호출:

dialog_manager.process_turn(
    req.session_id,
    req.message_input.text,
    input_confidence=req.message_input.confidence,
)

confidence <= session.stt_confidence_threshold이면 일반 NLU를 생략하고 intent=stt_low_confidence, dialogue_act=null인 규칙 결과를 만든 뒤 FallbackPolicynot_understood 경로로 보냅니다. 이 fallback은 이전 질문을 문맥에 맞게 다시 확인하며 turn_count를 증가시키지 않습니다.

text는 schema/route 오류가 아니라 dialogue_act=silenceno_input fallback으로 처리됩니다. no_inputnot_understood 모두 현재는 LLM으로 문맥에 맞는 문장을 먼저 생성합니다. Node의 responses.no_input/not_understood와 코드 기본 문구는 LLM 실패 시 사용합니다.

Fallback 생성 문장이 기존 assistant history와 공백 정규화 후 정확히 같으면 최대 총 3회 생성합니다. 재생성에도 중복되거나 중복 감지 후 LLM 오류가 나면 언어, fallback 종류와 재시도 단계별 코드 내 안전 문장을 선택합니다. 의미 유사도 검사는 하지 않습니다.

requery_requiredrequery_context는 여전히 request contract로만 수용하며 현재 fallback 판정에는 사용하지 않습니다.

session_id는 UUID type이 아닌 일반 문자열이고 text에도 최소 길이가 없으므로 두 field 모두 빈 문자열이 schema validation을 통과합니다. 정상 turn 처리에는 유효한 session ID와 실제 발화 text가 필요합니다.


6. Message response

ChatbotMessageResponse

Field Type Default 의미 값의 출처
session_id string "" 현재 session ID DST response
response string "" 사용자에게 전달할 bot text executor/policy NLG
current_node string "" transition 적용 후 node DialogueState.current_node
turn_count integer 0 세션의 논리적 turn 수. fallback 재시도 제외 DialogueState.turn_count
processing_time_ms number 0.0 최종 response text 준비까지 걸린 서버 시간(ms) time.perf_counter()
session_complete boolean false 세션 완료 여부 DialogueState.is_complete
final_data ChatbotFinalData \| null null 종료 시 선택적으로 반환하는 business data 아래 참고
error boolean false DST error response 여부 DST result

final_datasession_complete=true일 때만 직렬화됩니다. 일반 턴에서는 field 자체가 생략됩니다. 내부 DialogueState.context와 turn별 slots는 public message response에서 노출하지 않습니다.

완료 상태는 message route의 차단 조건이 아닙니다. 같은 session에 후속 요청을 보내면 terminal node에서 다시 처리하고 재개 transition에 따라 current_node가 이동할 수 있습니다. 하지만 일반 runtime은 is_complete를 자동 해제하지 않으므로 이후 응답도 완료 상태이고 final_data가 다시 생성될 수 있습니다. One-shot 전달 보장은 없습니다.

error=true는 HTTP 오류 status와 같은 의미가 아닙니다. Runtime이 실패를 내부 result로 반환한 경우에도 HTTP 200일 수 있으며, 처리되지 않은 예외만 HTTP 500으로 전파될 수 있습니다. 내부 error code와 detail은 public model에 포함되지 않습니다.

ChatbotFinalData

{
  "end_reason": "terminal_node",
  "slots": {"meal_status": "adequate"},
  "conversation_history": [
    {"role": "user", "message": "다음에 이야기해요"},
    {"role": "assistant", "message": "네, 다음에 또 뵐게요."}
  ]
}
Field Type 의미
end_reason string 저장된 종료 사유. 없으면 transition 사유 또는 completed
slots object \| null include_slots=true일 때 채워진 slot 값 전체
conversation_history array \| null include_history=true일 때 전체 user/assistant 대화

POST /v1/messagePOST /v1/session/jsonresponse_model_exclude_none=true이므로 비활성화된 slots 또는 conversation_historynull로 반환되지 않고 field 자체가 생략됩니다. History는 내부 list 순서를 유지합니다. 각 item이 object이고 rolemessage가 모두 문자열인 항목만 {"role": ..., "message": ...} 형태로 포함하며, 그 외 항목은 버립니다. 현재 role 값 자체를 enum으로 제한하지는 않습니다.

노출되지 않는 내부 field

DST state module의 build_response()가 만든 내부 result에는 details가 포함될 수 있지만 dm/api/response_builder.py가 public model을 다시 조립하므로 응답에서 제외됩니다.

내부 details Public API 노출
details.nlu 아니오
details.slot_updates 아니오
details.state_updates 아니오
details.transition 아니오
details.routing 아니오

7. Session info response

ChatbotSessionInfoResponse

아래 표는 Pydantic/OpenAPI response contract이며 route가 같은 구조로 반환합니다.

Field Type Default 의미
session_id string "" 조회 대상 session ID
current_node string "" 현재 node
turn_count integer 0 논리적 turn count. fallback 재시도 제외
session_complete boolean false 완료 여부
slots object {} 현재 slot
context object {} runtime context
expires_at string \| null null state 만료 예정 시각
ttl_seconds integer \| null null 남은 TTL 초

current_node, turn 정보, 채워진 slot과 context는 DialogueState에서 가져오고 expires_at, ttl_seconds는 해당 session의 ContextStore에서 가져옵니다. 존재하지 않거나 state가 만료된 session은 이 model 대신 FastAPI {"detail":"Session not found"} body와 HTTP 404를 반환합니다.

이 endpoint의 context는 message response에서 제거되는 내부 runtime 및 session_user 정보까지 포함할 수 있습니다. Public chatbot response가 아니라 신뢰된 backend용 조회 경계로 취급해야 합니다.


8. Scenario graph schema

API의 scenario_graphDict로만 선언되어 있어 Pydantic이 내부 구조를 검증하지 않습니다. 내부 검증은 Graph Builder가 수행합니다.

아래 표의 필수 여부는 Pydantic required가 아니라 scenario v2 작성 권장 규칙입니다. API Pydantic model은 scenario_graph를 단순 Dict로만 검사합니다. 실제 허용 여부는 Graph Builder의 parser와 validator가 결정합니다.

권장 v2 최상위 schema:

Field Type 필수 의미
metadata object 식별자, 표시명, 언어, 버전
prompts object 선택 NLG/NLU domain prompt
slots object 선택 전역 slot registry
graph object entry, global transitions, nodes

Metadata

Field Type 필수 의미
slug string 내부 scenario ID
name string 표시 이름
description string 권장 scenario 목적
language string ko, ja
version string scenario version
bot_first boolean legacy fallback graph.bot_first가 없을 때 초기 bot turn 설정

Prompts

Field Type 필수 의미
bot string 권장 NLG persona와 공통 응답 지침
nlu string 선택 domain intent/entity 해석 지침

Graph

Field Type 필수 의미
entry string 최초 node ID
bot_first boolean 선택 요청에서 override하지 않았을 때 초기 bot turn 실행 여부
global_transitions array 선택 모든 node보다 먼저 평가할 전이
nodes array node 정의

Node

Field Type 필수 의미
id string 고유 node ID
name string 선택 표시 이름
description string node 목적과 응답 범위
responses object 선택 기준 문장과 fallback template
params object 선택 turn/fallback/free conversation 설정
collect_slots array[string] 선택 현재 node 수집 대상
next_nodes array[object] 선택 조건부 target 또는 action
default_next string 선택 조건 불일치 시 정상 경로
terminal boolean 선택 명시적 종료 node

상세 작성 규칙은 Scenario 생성 가이드를 기준으로 합니다. bot_first 우선순위는 request field → graph.bot_first → legacy metadata.bot_firstfalse입니다. Slot registry, response template, params, transition condition/operator/action과 legacy graph 형식은 API Pydantic contract가 아니라 scenario runtime contract이므로 Scenario 생성 가이드에서 정의합니다.


9. 정의되어 있지만 active route에서 사용하지 않는 schema

Schema Field 요약 현재 상태
ChatbotMessageRequest session_id, user_input: string 어떤 active route도 request model로 사용하지 않음
BiometricInput emotion, dementia, depression active route 미사용
DialogInput dialog history, biometric history active route 미사용
DialogRequest session, user, dialog input active route 미사용

이 model들은 OpenAPI endpoint contract로 간주하면 안 됩니다. Route에 연결하기 전까지는 예약 또는 legacy schema입니다.

ChatbotMessageRequest (inactive)

Field Type Default
session_id string ""
user_input string ""

현재 active /v1/message는 이 model이 아니라 ChatbotRequest를 사용합니다.

BiometricInput (inactive)

Field Type Default
emotion string ""
dementia boolean false
depression boolean false

DialogInput (inactive)

Field Type Default
dialog string ""
biometric array[BiometricInput] []

DialogRequest (inactive)

Field Type Default
session_id string ""
user_input UserInput UserInput
dialog_input DialogInput DialogInput

이 inactive model들은 module import로 사용할 수는 있지만 어떤 route에도 연결되지 않으므로 HTTP client가 전송해도 선택되지 않습니다.


10. FastAPI validation error

Request가 Pydantic type과 맞지 않으면 FastAPI 표준 error object를 반환합니다.

Field Type 의미
detail array validation error 목록
detail[].type string Pydantic error code
detail[].loc array 오류 field 경로
detail[].msg string 오류 설명
detail[].input Any 거부된 입력

이 response는 project custom Pydantic model이 아니라 FastAPI의 표준 422 schema입니다.


관련 문서