콘텐츠로 이동

SeniMate 시나리오

이 폴더는 위치 기반 날씨 인사까지 포함한 dm/scenario/senimate_weather.json의 현재 설계를 설명합니다. JSON이 실행 기준입니다.

문서

  • Node Graph: 기본 흐름, global transition, node-local routing
  • Slot: 전역 슬롯, 노드별 수집 범위, routing 사용
  • Intent: 시나리오와 런타임이 사용하는 intent
  • Dialog act: 발화 행위별 정책·라우팅 동작

전체 흐름

SeniMate 기본 흐름

SVG 원본 열기

기본 경로는 6개 노드의 선형 흐름입니다. 다음 예외가 있습니다.

  • 명시적 종료 intent는 어느 노드에서든 conversation_closure로 이동합니다.
  • 연속 무응답이 3회에 도달하면 conversation_closure로 이동합니다.
  • 마무리 노드에서 사용자가 대화를 계속하면 아직 수집하지 않은 가장 이른 단계로 돌아갑니다.
  • 건강 불편을 말했지만 증상과 이슈를 모두 못 들었으면 health_check에 머뭅니다.
  • 자유 대화는 명시적인 종료 intent가 있을 때만 conversation_closure로 이동합니다.

노드 요약

Node 역할 Executor 수집 슬롯 min/max turns
greeting_introduction 날씨 조회, 서비스 소개와 대화 가능 여부 확인 Skill — / 3
daily_life_check 생활·기분·활동 안부 Task daily_life 2 / 3
meal_check 최근 식사 상태 Task meal_status 2 / 3
health_check 몸 상태와 필요한 증상 정보 Task health_status, pain_level, health_issue, symptom 2 / 4
general_conversation 최근 발화에 자유롭게 응답 General — / 6
conversation_closure 질문 없이 한 번만 마무리 General — / 2

params.skill이 있는 인사 노드는 SkillExecutor가 실행합니다. 나머지는 collect_slots가 있으면 Task, 없으면 General executor가 실행합니다.

general_conversationmax_turns: 6입니다. turn_limit_enabled는 선언하지 않으므로 기본값 true입니다. 턴 상한에 닿아도 next_nodes의 stay 조건이 종료 intent가 아니면 현재 노드에 머뭅니다. 화법은 prompts.bot과 노드 description이 담당하며, 사용자의 명시적인 종료 의도가 있을 때만 closure로 이동합니다.

전역 전이

현재 시나리오는 다음 2개 global transition을 순서대로 평가합니다.

  1. user_wants_to_end
  2. silent_close
flowchart TD
    INPUT["현재 턴"] --> END{"intent = user_wants_to_end?"}
    END -- "예" --> CLOSE["conversation_closure"]
    END -- "아니오" --> SILENT{"silence + no_input_count > 2?"}
    SILENT -- "예" --> CLOSE
    SILENT -- "아니오" --> NORMAL["node-local routing"]

마무리 node로 향하는 전이가 이미 그 node 자체를 가리키면 TransitionEngine은 해당 전이를 무시합니다. 이후 closure의 재개 조건이 일치하지 않으면 terminal_node로 세션을 완료합니다.

마무리 노드 재개

마무리 노드에서도 사용자가 새 이야기를 시작할 수 있습니다.

재개하지 않는 closing acknowledgement:

affirm
goodbye
thank
silence

그 외 dialog act라면 다음 우선순위로 돌아갑니다.

daily_life 미수집 → daily_life_check
meal_status 미수집 → meal_check
health_status 미수집 → health_check
그 외 → general_conversation

재개 여부는 runtime이 system.conversation_resuming으로 한 번 계산합니다. Scenario는 dialog act 목록을 반복하지 않고 conversation_closure.next_nodes의 네 조건에서 이 boolean을 사용합니다.

conversation_closureterminal: true를 명시하므로 복귀 edge가 있어도 terminal node입니다. 종료 여부를 더 이상 출력 차수 0에만 의존하지 않습니다.

Closure에서의 routing 순서:

Action END
→ global transition
→ next_nodes 재개 조건
→ default_next
→ terminal 판정
→ graph successor

max_turns=2에 도달하면 executor가 session_ended=true를 반환하므로 Action END에서 즉시 종료하고 재개 조건은 평가하지 않습니다.

연속 무응답

FallbackPolicyfallback_no_input_count를 관리하고 조건 evaluator는 이를 system.no_input_count로 노출합니다.

dialogue_act = silence
AND system.no_input_count > 2
→ conversation_closure

사용자가 정상적으로 말하면 fallback counter는 0으로 초기화됩니다. 마무리 노드는 max_fallback_retries=0이므로 무응답을 되묻지 않고 평소 terminal routing에 맡깁니다.

말하기 원칙

Scenario prompt와 노드 description의 공통 방향:

  • 따뜻하지만 보통 2~3문장 이내
  • 사용자 소재를 먼저 구체적으로 받아주기
  • 중립 발화에 과장된 공감 금지
  • 질문은 한 턴에 하나
  • 이미 확인한 안부·식사·건강 질문 반복 금지
  • 사용자가 부담을 말하면 이전 화제보다 그 부담을 먼저 다루기
  • 의학적 진단·처방 금지
  • 자유 대화에서 봇이 먼저 종료하지 않기
  • 마무리 노드에서 새 질문 금지

Prompt와 구조화 데이터

prompts.bot은 persona·말투·공감·의료 안전 원칙과, 인사에서 조회한 날씨만 사실로 사용할 수 있다는 범위를 정의합니다.

prompts.nlu는 다음을 상세히 보정합니다.

  • 직전 질문과 slot 주제 일치
  • 짧은 긍정·부정의 문맥 해석
  • 식사 slot guard
  • 건강 상태와 통증 없음 판정
  • 종료 의도와 대화 지속 의도 구분
  • 작별 뒤 짧은 수긍 처리

인사 노드는 weather Skill에 세션 사용자의 위도·경도를 전달하고 response_mode=nlg로 결과를 자연스럽게 표현합니다. 성공 결과 요약은 context.greeting_weather_summary에 저장합니다. Skill 실패 시에는 params.fallback이 응답 키보다 먼저 사용됩니다.

현재 주의점

  • 6개 slot은 모두 optional입니다. 수집 실패 자체가 진행을 막지는 않습니다.
  • min_turns=2가 수집 노드의 너무 빠른 진행을 완화합니다.
  • 마무리 재개 routing은 daily_life, meal_status, health_status의 미수집 여부를 사용합니다.
  • Closure의 재개 조건은 global transition이 아니라 conversation_closure.next_nodes에 있습니다.
  • terminal: true가 closure의 종료 성질을 명시하며, outgoing edge와 공존합니다.
  • 명시된 user_wants_to_end global transition이 intent 하나만 보므로, 런타임이 자동 보충하는 goodbye·nlu.end_signal 조건은 이 시나리오에 추가되지 않습니다.
  • health_check.params.completion_slots는 NLU 힌트와 로깅에 쓰이며 TaskPolicy의 완료 판정에는 직접 쓰이지 않습니다.
  • 암시적 긍정·부정 slot 추론의 기본값은 일부 slot enum과 맞지 않을 수 있습니다.

검증

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

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

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

필수 회귀:

  • 인사 후 일상 질문을 중복하지 않음
  • 각 수집 노드에서 한 턴 한 질문
  • 식사·건강 slot 오배정 방지
  • 건강 complaint 후 증상 또는 이슈 최소 하나 수집
  • 자유 대화에서 조기 작별 금지
  • 명시적 종료 시 closure를 거쳐 종료
  • closure에서 새 이야기 시 적절한 단계로 재개
  • closure의 affirm/goodbye/thank/silence는 반복 작별 없이 종료
  • 연속 무응답 후 closure 이동
  • closure에 outgoing edge가 있어도 end_nodes에 유지
  • 재개 조건이 불일치하면 graph successor로 새지 않고 terminal 종료
  • closure turn limit에서는 재개 edge보다 Action END가 우선