콘텐츠로 이동

카드 발급 신청 Node Graph

dm/scenario/card_issuance.json 기준의 정적 graph와 runtime routing입니다.

기본 흐름

카드 발급 신청 기본 흐름

SVG 원본 열기

Node schema

Node Terminal 주요 params collect_slots 기본 이동
welcome false max_turns=2 collect_personal_info
collect_personal_info false max_turns=4 이름, 생년월일 select_card_type
select_card_type false max_turns=3 카드 종류 income_verification
income_verification false max_turns=5 소득, 직장, 근무기간 address_collection
address_collection false max_turns=6 우편번호, 주소, 상세주소, 배송 final_confirmation
final_confirmation false max_turns=4 약관 동의 process_application
process_application false max_turns=2 최종 신청 확인 조건 분기
completion_approved true fallback 0 완료
completion_rejected true fallback 0 완료
application_cancelled true fallback 0 완료

정적 graph

flowchart LR
    W["welcome"] --> P["collect_personal_info"]
    P --> C["select_card_type"]
    C --> I["income_verification"]
    I --> A["address_collection"]
    A --> F["final_confirmation"]
    F --> X["process_application"]
    F --> CANCEL["application_cancelled"]
    X --> APPROVED["completion_approved"]
    X --> REJECTED["completion_rejected"]
    X --> CANCEL

정적 edge:

Source Target 선언
welcome collect_personal_info default_next
collect_personal_info select_card_type default_next
select_card_type income_verification default_next
income_verification address_collection default_next
address_collection final_confirmation default_next
final_confirmation process_application default_next
final_confirmation application_cancelled 조건부 target
process_application completion_approved 카드별 조건부 target 3개
process_application completion_rejected 조건부 target
process_application application_cancelled 조건부 target

NetworkX는 DiGraph이므로 process_application → completion_approved를 만드는 세 카드별 선언은 정적 graph에서 하나의 edge로 표현됩니다. Runtime은 원본 next_nodes 배열의 세 조건을 순서대로 각각 평가합니다.

welcome.next_nodes[].action=stay와 global transition은 정적 edge를 만들지 않습니다.

Runtime routing 우선순위

이 시나리오에서 중요한 순서:

Action END
→ global transition
→ Action STAY/GOTO
→ off-topic slot-node stay guard
→ node next_nodes condition
→ default_next
→ terminal 판정
→ graph successor fallback
→ 현재 node 유지

Global 취소·종료·fallback 소진 전이가 required slot 미수집으로 발생한 STAY_CURRENT보다 먼저 적용됩니다.

Welcome

flowchart TD
    START([Session start]) --> W["welcome"]
    W --> T{"system.node_turns = 1?"}
    T -- "예" --> STAY["action: stay"]
    STAY --> W
    T -- "아니오" --> PERSONAL["collect_personal_info"]

첫 빈 입력 턴에는 welcome에 머물러 인사를 제공합니다. 다음 사용자 응답 이후 collect_personal_info로 이동합니다.

선형 수집 구간

collect_personal_info
  required: name, birth_date
       ↓ all required filled
select_card_type
  required: card_type
income_verification
  required: annual_income, workplace, employment_months
address_collection
  required: postal_code, address, detailed_address, delivery_option
final_confirmation

각 Task node에서 required slot이 남아 있으면 executor가 STAY_CURRENT를 요청합니다. 모두 채워졌을 때만 default_next가 적용됩니다.

낮은 소득 처리

소득 기준 판정은 income_verification에서 하지 않습니다.

flowchart TD
    INPUT["annual_income 입력"] --> COLLECT{"workplace와<br/>employment_months도 채웠는가?"}
    COLLECT -- "아니오" --> STAY["income_verification 유지"]
    COLLECT -- "예" --> ADDRESS["address_collection"]
    ADDRESS --> TERMS["final_confirmation"]
    TERMS --> PROCESS["process_application"]
    PROCESS --> RESULT{"카드별 기준 판정"}

예를 들어 일반카드를 선택하고 연소득 1,000만원을 입력해도 직장명과 근무기간 수집을 계속합니다. 거절은 최종 신청 확인 이후에만 결정됩니다.

약관 동의

flowchart TD
    FINAL["final_confirmation"] --> CONSENT{"terms_agreed"}
    CONSENT -- "no" --> CANCEL["application_cancelled"]
    CONSENT -- "yes" --> PROCESS["process_application"]
    CONSENT -- "미수집" --> FINAL
Condition 결과
slots.terms_agreed == no 취소
user_wants_to_cancel global 또는 node-local 취소
user_wants_to_end global 또는 node-local 취소
required slot 완료, 취소 조건 없음 process_application

최종 신청 확인과 심사

flowchart TD
    PROCESS["process_application"] --> CONFIRM{"application_confirmed"}
    CONFIRM -- "no" --> CANCEL["application_cancelled"]
    CONFIRM -- "yes" --> CARD{"card_type"}
    CARD -- "standard" --> S{"income > 1999<br/>months > 5"}
    CARD -- "gold" --> G{"income > 3499<br/>months > 5"}
    CARD -- "platinum" --> P{"income > 7999<br/>months > 5"}
    S -- "예" --> OK["completion_approved"]
    G -- "예" --> OK
    P -- "예" --> OK
    S -- "아니오" --> NO["completion_rejected"]
    G -- "아니오" --> NO
    P -- "아니오" --> NO

Runtime의 승인 조건:

순서 Condition Target
1 application_confirmed == no 취소
2 standard AND income > 1999 AND months > 5 승인
3 gold AND income > 3499 AND months > 5 승인
4 platinum AND income > 7999 AND months > 5 승인
5 months < 6 OR 카드별 income 미달 거절

application_confirmed=yes는 Task node의 required slot을 완료시키는 값입니다. 승인 조건에는 반복하지 않고 이미 수집 완료된 사실을 전제로 합니다.

Global transition

이름 Condition Target
user_wants_to_cancel nlu.intent == user_wants_to_cancel application_cancelled
user_wants_to_end nlu.intent == user_wants_to_end application_cancelled
fallback_exhausted context.fallback_exhausted is not empty application_cancelled

Global transition은 모든 node에서 평가됩니다. 이미 application_cancelled에 있을 때 target이 현재 node와 같으면 self-target을 무시하고 terminal 판정으로 내려갑니다.

Terminal 처리

세 결과 node 모두 terminal: true입니다.

flowchart LR
    APPROVED["completion_approved"] --> DONE([Session complete])
    REJECTED["completion_rejected"] --> DONE
    CANCELLED["application_cancelled"] --> DONE

Terminal node는 executor가 해당 node의 응답을 만든 뒤 명시적 전이가 없으면 TransitionEnginesession_complete=true로 설정합니다.

응답과 node 이동 시점

한 턴은 이동 전 node에서 응답을 만든 뒤 transition을 적용합니다.

현재 node에서 NLU와 응답 생성
→ slot/context commit
→ transition condition 평가
→ current_node 변경

따라서 detailed 출력의 node A › B에서 같은 턴의 응답은 일반적으로 A의 설정으로 생성됩니다. B의 terminal 안내는 B가 현재 node인 다음 처리 시점에 적용됩니다.

관련 문서