콘텐츠로 이동

Sohri Graph Builder 정책

이 문서는 현재 정책의 간결한 색인입니다. 세부 필드, 우선순위와 예외는 연결된 기준 문서에서 확인합니다. 구현과 설명이 다르면 현재 코드와 자동화 테스트를 먼저 확인하고, docs/refactor/release_notes.md는 과거 기록으로만 사용합니다.

핵심 원칙

  1. Scenario가 node, slot, transition과 도메인 지침을 소유합니다.
  2. Runtime이 상태 반영과 최종 node 이동을 통제합니다.
  3. Policy는 행동을 판단하고 NLG는 문장을 표현합니다.
  4. 이번 턴의 update를 반영한 뒤 transition을 평가합니다.
  5. 안전 위험과 사용자의 명시적 종료 의사를 일반 흐름보다 우선합니다.
  6. NLU는 현재 발화에 근거가 있는 entity만 반환해야 합니다.
  7. 사용자 profile과 Skill 결과는 데이터이며 system instruction이 아닙니다.
  8. 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=nullnot_understood 경로로 보냅니다.

no_input

빈 사용자 입력, intent=empty 또는 dialogue_act=silence를 무응답으로 봅니다. 이전 턴 entity가 남아 있어도 실제 입력이 비어 있으면 무응답 판정이 우선합니다.

not_understood

dialogue_act=null인 의미 파악 실패를 이해 불가로 봅니다. 단, 실제 사용자 텍스트와 추출 entity가 함께 있으면 알아들은 정보가 있으므로 fallback으로 가로채지 않습니다.

두 fallback의 현재 공통 계약:

  • FallbackPolicy는 규칙 NLU 여부와 관계없이 LLM으로 전체 대화 맥락에 맞는 응답을 생성하고 현재 node를 유지합니다.
  • responses.no_inputresponses.not_understood는 정상 생성용 고정 문구가 아니라 LLM 호출 실패 시 안전망입니다. 선언이 없으면 언어별 공통 문구를 사용합니다.
  • 직전 질문의 질문 문장만 fallback anchor로 유지하며 같은 응답이면 최대 두 번 재생성합니다. 계속 중복되면 이력과 겹치지 않는 안전 문장을 선택합니다.
  • fallback_no_input_countfallback_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이 있으면 같은 턴에 이동·완료할 수 있고, 없으면 자동 종료를 보장하지 않습니다.

세부 계약은 FallbackPolicylow-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에 넣지 않습니다.

API, Skill, 배포, 검증과 테스트

현재 제한

  • Graph validation만으로 모든 target, slot 참조와 condition 의미를 보장하지 않습니다.
  • 완료된 Session에 대한 추가 message를 Runtime이 차단하지 않습니다.
  • Session과 session별 runtime이 process-local이어서 수평 확장이 안전하지 않습니다.
  • 배포 workflow·manifest와 일부 배포 계약 테스트의 on-prem 기대값이 현재 서로 일치하지 않습니다. 실제 배포 계약과 검증 가능한 제한은 배포 가이드에 명시합니다.
  • Public session 조회에는 인증 middleware가 없고 내부 context를 반환하므로 신뢰할 수 없는 외부 네트워크에 그대로 노출하면 안 됩니다.