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을 선택하면 그 안의
latitude와 longitude는 모두 필수입니다. 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/message의 message_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 경도 |
예:
좌표 대신 "서울시 강남구" 같은 문자열 위치도 계속 지원합니다. 좌표 object를 사용할
때는 latitude와 longitude를 모두 전달해야 합니다.
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_choice와 nlu_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 |
아니오 | 예 | text와 confidence 사용 |
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 이상 제한이 없습니다.
emotion과 trigger_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인 규칙 결과를 만든 뒤
FallbackPolicy의 not_understood 경로로 보냅니다. 이 fallback은 이전 질문을
문맥에 맞게 다시 확인하며 turn_count를 증가시키지 않습니다.
빈 text는 schema/route 오류가 아니라 dialogue_act=silence인 no_input
fallback으로 처리됩니다. no_input과 not_understood 모두 현재는 LLM으로 문맥에
맞는 문장을 먼저 생성합니다. Node의 responses.no_input/not_understood와 코드
기본 문구는 LLM 실패 시 사용합니다.
Fallback 생성 문장이 기존 assistant history와 공백 정규화 후 정확히 같으면 최대 총 3회 생성합니다. 재생성에도 중복되거나 중복 감지 후 LLM 오류가 나면 언어, fallback 종류와 재시도 단계별 코드 내 안전 문장을 선택합니다. 의미 유사도 검사는 하지 않습니다.
requery_required와 requery_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_data는 session_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/message와 POST /v1/session/json은 response_model_exclude_none=true이므로
비활성화된 slots 또는 conversation_history는 null로 반환되지 않고 field 자체가
생략됩니다. History는 내부 list 순서를 유지합니다. 각 item이 object이고 role과
message가 모두 문자열인 항목만 {"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_graph는 Dict로만 선언되어 있어 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_first → false입니다. 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입니다.