콘텐츠로 이동

자유 대화 시나리오

이 폴더는 dm/scenario/general_conversation.json의 현재 설계를 설명합니다. JSON이 실행 기준이며, 문서는 구조와 runtime 동작을 읽기 쉽게 정리합니다.

문서

  • Node Graph: 정적 graph와 runtime routing
  • Slot: 슬롯을 선언·수집하지 않는 구조
  • Intent: 종료 intent와 공통 runtime intent
  • Dialog act: 발화 행위별 공통 정책과 종료 영향

목적

이 시나리오는 정해진 업무나 정보 수집 없이 사용자와 자유롭게 대화합니다.

항목 현재 값
Scenario slug general_conversation
언어 ko
버전 1.1.0
Bot first true
Entry node greeting
Slot registry 없음
Slot 수집 없음
명시적 종료 신호 nlu.intent == user_wants_to_end
Terminal node conversation_closure

전체 흐름

자유 대화 기본 흐름

SVG 원본 열기

세션은 greeting에서 봇이 먼저 인사한 뒤 conversation으로 들어갑니다. conversation은 사용자가 명시적으로 종료하기 전까지 현재 노드에 머뭅니다. conversation_closureterminal: true이며 outgoing edge가 없습니다.

Node 요약

Node 역할 Executor 수집 슬롯 Turn limit
greeting 짧게 인사한 뒤 오늘 이야기를 연다 GeneralResponseExecutor 없음 max_turns 3
conversation 사용자 입력에 이어가는 자유 대화 GeneralResponseExecutor 없음 비활성화
conversation_closure 종료 의사를 짧게 받아들이고 마무리 GeneralResponseExecutor 없음 max_turns 2

세 노드 모두 collect_slots가 없으므로 GeneralResponseExecutor가 선택됩니다.

자유 대화 설정

Param 타입 효과
turn_limit_enabled boolean false executor turn limit과 NLG turn-budget 안내 비활성화

turn_limit_enabled=falseconversation에만 선언되어 있습니다. 따라서 대화 횟수만으로 closure로 이동하지 않습니다.

Prompt

현재 scenario prompt:

경로 선언 여부 내용과 역할
prompts.bot 선언 지금 말에 답하고 앞 사실도 이어가기. 직전 봇 말이 질문이면 이번은 평서문으로만 끝냄
prompts.nlu 선언 짧은 말은 직전 봇 말로 해석. 질문의 부정 답은 종료가 아님. 주제 접기와 대화 종료를 구분

prompts.bot이 빈 값이 아니므로 공통 NLG 시스템 prompt를 완전히 제거하는 구조는 아닙니다. 공통 prompt에 scenario의 bot 지침을 추가하여 사용합니다.

greetingresponses.default를 둡니다. bot-first 첫 발화에서는 이 문장을 그대로 사용하고, 이후 일반 응답에서는 NLG 기준이자 LLM 실패 fallback이 될 수 있습니다. conversationconversation_closure에는 responses가 없으므로 공통 fallback 메시지가 사용될 수 있습니다.

종료 routing

종료 조건은 global transition과 conversation.next_nodes에 같은 형태로 선언되어 있습니다.

위치 조건 결과
graph.global_transitions[0] nlu.intent == user_wants_to_end conversation_closure로 이동
conversation.next_nodes[0] nlu.intent == user_wants_to_end conversation_closure로 이동
conversation.next_nodes[1] nlu.intent != user_wants_to_end 현재 노드 유지

Runtime에서는 global transition이 node-local transition보다 먼저 평가되므로 정상 종료 턴에는 global transition이 우선합니다. Node-local closure target은 정적 graph에 conversation → conversation_closure edge를 만들고 graph 구조를 명확하게 유지하는 역할도 합니다.

종료 턴의 실행 시점

한 턴은 현재 노드가 응답을 만든 뒤 transition을 적용합니다.

conversation에서 사용자 종료 발화 처리
→ conversation 응답 생성
→ global transition 결정
→ current_node = conversation_closure

따라서 closure로 이동한 턴의 응답은 이동 전 conversation이 생성합니다. conversation_closure의 description은 closure가 현재 노드인 다음 처리 턴에 적용됩니다.

Closure는 outgoing edge가 없고 terminal: true이므로 해당 노드에서 명시적 전이가 없으면 TransitionEngine이 세션을 완료합니다.

SeniMate와 다른 점

항목 자유 대화 SeniMate
목적 대화 없음 일상·식사·건강 확인
Slot registry 없음 6개 optional slot
Node 수 3 (greeting 포함) 6
연속 무응답 종료 선언 없음 silent_close global transition
Closure 재개 edge 없음 미수집 단계 또는 자유 대화로 복귀
Closure params max_turns 2 turn/fallback 제한 선언

현재 conversation_closure에는 재개 transition이 없습니다. Closure에서 사용자가 새 이야기를 시작하더라도 SeniMate처럼 conversation으로 돌아가지 않고 terminal 판정으로 완료됩니다.

현재 주의점

  • 명시적 종료 transition은 nlu.intent만 확인합니다.
  • Scenario가 종료 transition을 직접 선언하므로 runtime의 기본 goodbye·nlu.end_signal 조건은 자동 보충되지 않습니다.
  • 종료 intent 분류는 공통 NLU 지침에 prompts.nlu의 부정·주제 접기 규칙을 더합니다.
  • Slot registry와 collect_slots가 모두 없어 task policy와 slot commit 경로를 사용하지 않습니다.
  • 연속 무응답을 closure로 보내는 silent_close 규칙이 없습니다.
  • Closure에서 대화를 재개하는 outgoing edge가 없습니다.
  • conversation의 turn limit은 비활성화됩니다. closure는 max_turns 2입니다.

검증

python -m cli.chatbot \
  --scenario dm/scenario/general_conversation.json \
  --validate-only

python -m cli.chatbot \
  --scenario dm/scenario/general_conversation.json \
  --output-level detailed

python -m cli.chatbot \
  --scenario dm/scenario/general_conversation.json \
  --node conversation_closure \
  --output-level detailed

필수 회귀:

  • 일반 입력에서 conversation 유지
  • 답변 뒤에 습관적인 추가 질문이나 도움 제안을 붙이지 않음
  • 여러 턴 대화 후에도 turn limit으로 종료하지 않음
  • 명시적 user_wants_to_end에서 closure 이동
  • closure가 terminal_node로 완료
  • Slot update와 task outcome이 생성되지 않음
  • closure에서 새 발화를 해도 현재 설계상 대화가 재개되지 않음