콘텐츠로 이동

03. 노드 스키마 정리

이 문서는 당시 schema 정리 기록입니다. 현재 SeniMate 선언값은 SeniMate 시나리오dm/scenario/senimate.json을 기준으로 확인하세요.

dm/scenario/senimate.jsongreeting_introduction

이전

{
  "id": "greeting_introduction",
  "name": "인사및소개",
  "description": "고객을 환영하고 SeniMate 서비스를 소개. 자기소개는 '저는 SeniMate이에요'처럼 '-이에요' 톤을 쓰세요('라고 합니다'는 쓰지 마세요). 먼저 인사와 서비스 소개 ",
  "params": {
    "max_turns": 3,
    "service_name": "SeniMate",
    "conversation_type": "health_check"
  },
  "default_next": "daily_life_check"
}

문제:

  • description 에 노드 목적, 말투 규칙, 금지 표현이 섞여 있다. 문장이 끝나지 않은 채로 끝난다.
  • service_name, conversation_type코드에서 전혀 읽지 않는다. 죽은 스키마다.
  • responses 가 없어 LLM 생성이 실패하면 기댈 문장이 없다.
  • 인사 문구가 시나리오에 없다. GreetingExecutor 안에 있었다.

이후

{
  "id": "greeting_introduction",
  "name": "인사및소개",
  "description": "첫 인사 노드. 이름을 밝히고 무엇을 하는 서비스인지 한 문장으로 알린 뒤, 이야기를 나눠도 괜찮은지 부담 없이 확인한다. 다음 노드에서 물어볼 일상 질문을 여기서 미리 하지 않는다.",
  "responses": {
    "default": "안녕하세요, 저는 SeniMate이에요. 어르신 안부도 여쭙고 이야기도 나누려고 왔어요. 잠깐 말씀 나눠도 괜찮으실까요?",
    "no_input": "잘 안 들리셨을까요? 천천히 말씀해 주셔도 괜찮아요.",
    "not_understood": "제가 잘 못 알아들었어요. 한 번만 다시 말씀해 주시겠어요?"
  },
  "params": {
    "max_turns": 3,
    "max_fallback_retries": 2
  },
  "next_nodes": [
    {
      "action": "stay",
      "condition": { "field": "system.node_turns", "operator": "equals", "value": 1 }
    }
  ],
  "default_next": "daily_life_check"
}

필드별 판단

description — 목적만 남긴다

노드가 무엇을 달성해야 하는지하지 말아야 할 것만 쓴다.

마지막 문장 "다음 노드에서 물어볼 일상 질문을 여기서 미리 하지 않는다"가 핵심이다. GreetingExecutor 가 하던 실수를 LLM 이 반복하지 않도록 명시한다.

말투 규칙(-이에요 톤)은 노드가 아니라 페르소나이므로 prompts.bot 19번 항목으로 옮겼다. 모든 노드에 적용되어야 하는 규칙을 한 노드의 description 에 두면 다른 노드에서 지켜지지 않는다.

responses — 추가

역할
default 인사 기본 문장. LLM 생성의 기준이자 실패 시 fallback
no_input 무응답일 때 (02 참고)
not_understood 이해 불가일 때

params — 미사용 키 제거

판단
max_turns 유지. _turn_limit_reached() 가 읽는다
max_fallback_retries 추가. FallbackPolicy 가 읽는다
service_name 제거. 코드에서 참조 없음
conversation_type 제거. 코드에서 참조 없음

grep -rn "service_name\|conversation_type" dm/ --include=*.py 로 확인했다. 다른 노드에 남아 있는 max_silence_retries 도 같은 이유로 미사용이며 해당 노드 정리 단계에서 제거한다.

next_nodes — 추가

첫 턴에 인사만 하고 사용자의 답을 같은 노드에서 받기 위한 조건이다. 예전에는 GreetingExecutorSTAY_CURRENT 로 처리하던 동작을 그래프로 옮겼다.

{ "action": "stay", "condition": { "field": "system.node_turns", "operator": "equals", "value": 1 } }

system.node_turnsdst_conditions.py 가 조건 평가 컨텍스트에 노출하는 값이다. 세션 시작 시 1, 노드에 머물 때마다 apply_node_transition() 이 증가시킨다.

노드 스키마 기준 (정리)

첫 노드를 다루며 정한 기준이다. 다음 노드에도 적용한다.

두어야 하는 것

필드 언제
id, description 항상
name 표시가 필요할 때
responses.default 항상. LLM 실패 시 기댈 문장이 필요하다
responses.no_input / not_understood 사용자 응답을 기다리는 노드
params.max_turns 항상. 무한 체류 방지
params.max_fallback_retries 도입 당시 기본값(2)과 달라야 할 때만. 현재 기본값은 3
collect_slots 슬롯을 수집하는 노드만
next_nodes / default_next 흐름 표현

두지 않는 것

  • 코드가 읽지 않는 키 (service_name, conversation_type, max_silence_retries)
  • 모든 노드에 공통인 말투·페르소나 규칙 → prompts.bot
  • 다음 노드가 해야 할 질문
  • v2 에서 제거된 필드 (actions, conditions, visible, stage, params.slots)