콘텐츠로 이동

SeniMate Intent

dm/scenario/senimate_weather.json 기준의 현재 intent 설계입니다.

Registry

Scenario v2에는 intent registry가 없습니다. Intent 이름은 다음 위치에서 발견됩니다.

  1. global_transitions와 node condition
  2. prompts.nlu
  3. 런타임 공통 코드

따라서 slot처럼 한 블록만 보고 전체 intent 목록을 확인할 수 없습니다.

Routing에 직접 사용하는 intent

현재 scenario condition에서 흐름을 바꾸는 intent는 user_wants_to_end 하나입니다.

위치 조건 동작
global transition nlu.intent == user_wants_to_end 어느 node에서든 conversation_closure
general_conversation nlu.intent == user_wants_to_end closure 이동
general_conversation nlu.intent != user_wants_to_end 현재 node 유지
{
  "name": "user_wants_to_end",
  "target": "conversation_closure",
  "condition": {
    "field": "nlu.intent",
    "operator": "equals",
    "value": "user_wants_to_end"
  }
}

종료는 더 이상 EndIntentPolicy가 담당하지 않습니다. Executor가 응답을 만든 뒤 TransitionEngine이 global transition을 평가해 마무리 node로 이동합니다.

종료 권한

현재 종료 흐름:

사용자 종료 발화
→ NLU intent = user_wants_to_end
→ global transition
→ 현재 node가 전환 응답 생성
→ conversation_closure
→ 재개 조건이 없으면 terminal node 판정으로 session complete

다른 scenario가 종료 전이를 선언하지 않은 경우에만 runtime이 다음 세 신호를 보는 기본 전이를 보충합니다.

nlu.intent == user_wants_to_end
nlu.dialogue_act == goodbye
nlu.end_signal == true

그러나 SeniMate는 이름과 조건에 user_wants_to_end가 들어간 전이를 직접 선언합니다. 이 때문에 자동 보충은 실행되지 않고 현재 JSON의 intent 조건 하나만 사용합니다.

end_signal

nlu.end_signal은 intent가 아니라 현재 턴의 보조 boolean field입니다.

dst_nlu._mark_end_keyword_signal()이 명시적인 종료 keyword를 감지해 NLU raw 결과에 추가합니다.

Context가 아니라 NLU 결과에 두는 이유는 이전 턴의 종료 신호가 다음 턴까지 남지 않도록 하기 위해서입니다.

현재 SeniMate의 명시적 종료 전이는 nlu.end_signal을 조건에 포함하지 않습니다.

종료 intent 보정

다음 조건이면 NLU가 만든 종료 intent를 user_wants_to_continue로 바꿉니다.

intent = user_wants_to_end
dialogue_act = deny 또는 negate
명시적인 종료 keyword 없음

예:

"아니, 가지 마"

이 보정으로 작별 문맥의 과잉 종료를 줄입니다.

런타임 공통 intent

Intent 소비 위치 동작
empty FallbackPolicy 무응답으로 판정
unknown NLU 장애 fallback dialogue_act=null과 함께 이해 불가 처리
user_wants_to_continue 종료 intent 보정 종료 routing 방지
affirm, deny DialogAct.from_intent() dialog act fallback 추론

일상 node는 날씨, 수면, 외출, TV 같은 넓은 생활 발화를 daily_life로 받을 수 있습니다. 식사·건강 슬롯은 직전 질문과 현재 수집 대상을 기준으로만 채웁니다.

Dialog act와 구분

다음은 intent가 아니라 dialog act입니다.

affirm, deny, negate, confirm
question, request, repeat, help
greeting, thank, goodbye
silence, null

예:

"그래"

직전 질문에 따라:

  • 대화 가능 여부 동의: affirm
  • 마무리 제안 동의: user_wants_to_end intent + affirm act 가능
  • 부정 확인 질문에서 “없음” 확인: slot entity + affirm

Intent와 act를 하나의 label처럼 사용하지 않습니다.

현재 구조

정상 진행은 intent보다 node의 default_next, min_turns, slot 상태가 주도합니다.

greeting
→ daily_life
→ meal
→ health
→ general
→ closure

Intent의 핵심 역할은 종료입니다. 마무리 재개는 intent가 아니라 runtime이 계산한 system.conversation_resuming과 미수집 slot으로 결정합니다.

개선 후보

  • Scenario intent registry 도입 여부 검토
  • SeniMate 종료 전이에 goodbyenlu.end_signal 포함 여부 검토

관련 문서