Sohri Graph Builder 정책¶
이 문서는 현재 정책의 간결한 색인입니다. 세부 필드, 우선순위와 예외는 연결된
기준 문서에서 확인합니다. 구현과 설명이 다르면 현재 코드와 자동화 테스트를 먼저
확인하고, docs/refactor/와 release_notes.md는 과거 기록으로만 사용합니다.
핵심 원칙¶
- Scenario가 node, slot, transition과 도메인 지침을 소유합니다.
- Runtime이 상태 반영과 최종 node 이동을 통제합니다.
- Policy는 행동을 판단하고 NLG는 문장을 표현합니다.
- 이번 턴의 update를 반영한 뒤 transition을 평가합니다.
- 안전 위험과 사용자의 명시적 종료 의사를 일반 흐름보다 우선합니다.
- NLU는 현재 발화에 근거가 있는 entity만 반환해야 합니다.
- 사용자 profile과 Skill 결과는 데이터이며 system instruction이 아닙니다.
- LLM과 Skill 실패에는 사용자에게 반환할 안전 경로가 있어야 합니다.
전체 턴 흐름은 Architecture, 상태 반영 순서는 DSTManager, 이동 우선순위는 Transition을 기준으로 합니다.
입력, 안전과 fallback¶
- NLU는
intent,dialogue_act,entities,confidence를 만들며 State를 직접 변경하지 않습니다. - 명확한 자해·응급 신호는 즉시 안전 안내를 반환합니다. 약한 신호는
safety_watch만 기록하고 일반 응답에서 상황을 확인합니다. - Graph Builder는 실제 신고나 전화를 수행하지 않습니다.
- STT confidence가 session threshold 이하이면 LLM NLU를 생략하고
dialogue_act=null인not_understood경로로 보냅니다.
no_input¶
빈 사용자 입력, intent=empty 또는 dialogue_act=silence를 무응답으로 봅니다.
이전 턴 entity가 남아 있어도 실제 입력이 비어 있으면 무응답 판정이 우선합니다.
not_understood¶
dialogue_act=null인 의미 파악 실패를 이해 불가로 봅니다. 단, 실제 사용자 텍스트와
추출 entity가 함께 있으면 알아들은 정보가 있으므로 fallback으로 가로채지 않습니다.
두 fallback의 현재 공통 계약:
FallbackPolicy는 규칙 NLU 여부와 관계없이 LLM으로 전체 대화 맥락에 맞는 응답을 생성하고 현재 node를 유지합니다.responses.no_input과responses.not_understood는 정상 생성용 고정 문구가 아니라 LLM 호출 실패 시 안전망입니다. 선언이 없으면 언어별 공통 문구를 사용합니다.- 직전 질문의 질문 문장만 fallback anchor로 유지하며 같은 응답이면 최대 두 번 재생성합니다. 계속 중복되면 이력과 겹치지 않는 안전 문장을 선택합니다.
fallback_no_input_count와fallback_not_understood_count는 별도 관리하며 정상 발화에서 둘 다 초기화합니다.- fallback 턴은 논리적
turn_count에 포함하지 않습니다. - 재시도 예산은 session override, node
params.max_fallback_retries, 기본값 3 순으로 정합니다. 단, terminal node의 값0은 session override보다 우선합니다. - 예산 소진 시 Policy가 직접 종료하지 않습니다.
fallback_exhausted를 기록하고 일반 executor와TransitionEngine에 제어를 넘깁니다. Terminal target이 있으면 같은 턴에 이동·완료할 수 있고, 없으면 자동 종료를 보장하지 않습니다.
세부 계약은 FallbackPolicy와 low-confidence 처리를 봅니다.
Slot, 응답과 routing¶
- 현재 node의
collect_slots가 수집 완료 판단 범위입니다. 다만 Runtime은 NLU가 반환한 다른 비어 있지 않은 entity도 저장할 수 있으므로 prompt와 테스트로 범위를 제한해야 합니다. - Required slot은 진행을 막고 optional slot은 포기하고 진행할 수 있습니다.
params.skill이 있으면SkillExecutor, 아니면 유효한collect_slots가 있을 때TaskOrientedExecutor, 그 밖에는GeneralResponseExecutor를 사용합니다.- 정상 NLG에서
responses.default는 고정 출력이 아니라 전달할 의미의 기준 문장입니다. LLM 실패 시에는 그대로 반환될 수 있습니다. - Bot-first 시작에서는
responses.default가 있으면 NLU와 LLM 없이 그대로 초기 응답으로 사용합니다. - Task outcome별 response는 주로 LLM 실패 안전망입니다. 사용자 질문·요청·정정에 먼저 답하고, optional slot을 못 받았을 때 받았다고 말하지 않습니다.
- 공통 종료는
global_transitions, node별 조건 분기는next_nodes, 정상 경로는default_next로 표현합니다. 최종 이동과 완료는TransitionEngine이 결정합니다.
세부 문서:
API, Skill과 운영¶
- Client는 session을 만든 뒤 해당
session_id로 메시지를 보냅니다. - 완료 응답은 기본적으로
final_data.slots를 포함하고 history는 session의completion_options로 요청한 경우에만 포함합니다. 내부 context는 message 응답에서 제거합니다. - Skill update는
result_map또는allowed_updates에 허용된 값만 반영합니다. - Session runtime은 process memory에 있으므로 현재 Helm 계약은 1 replica와 multi-replica HPA 금지를 강제합니다.
- Secret은 저장소와 image에 넣지 않습니다.
현재 제한¶
- Graph validation만으로 모든 target, slot 참조와 condition 의미를 보장하지 않습니다.
- 완료된 Session에 대한 추가 message를 Runtime이 차단하지 않습니다.
- Session과 session별 runtime이 process-local이어서 수평 확장이 안전하지 않습니다.
- 배포 workflow·manifest와 일부 배포 계약 테스트의 on-prem 기대값이 현재 서로 일치하지 않습니다. 실제 배포 계약과 검증 가능한 제한은 배포 가이드에 명시합니다.
- Public session 조회에는 인증 middleware가 없고 내부 context를 반환하므로 신뢰할 수 없는 외부 네트워크에 그대로 노출하면 안 됩니다.