콘텐츠로 이동

일반 SOHRI 턴

정상 음성 턴은 EPD의 confirmed activity가 STT 텍스트를 포함한 END로 끝날 때 시작됩니다. EPD 자체가 STT를 수행하므로 별도 STT 왕복은 없습니다.

sequenceDiagram
    participant C as Client/Gateway
    participant S as Socket Backend
    participant E as EPD + STT
    participant G as DM Guard / Input Gate
    participant DB as PostgreSQL
    participant D as Graph Builder
    participant T as TTS Provider
    participant A as Immediate Analysis

    C->>S: Binary PCM
    S->>E: PCM + tts_playback 상태
    E-->>S: candidate(activityId)
    S-->>C: speech_candidate
    C->>S: tts_duck_applied
    S->>E: duck control
    E-->>S: confirmed(activityId)
    S-->>C: speech_started
    E-->>S: END + STT + confidence + WAV 경로

    S->>S: 발화 세대·텍스트·처리권 검증
    S->>G: USER lease 획득
    S->>S: response generation 시작
    S->>G: AudioInputGate.pause(token)
    Note over S,G: 이 시점부터 새 PCM 폐기

    par EPD 기록
        S->>DB: dialog_epd 저장
    and 턴 처리(가상 스레드)
        S->>DB: USER dialog_message 저장
        S-->>C: stt_result
        S-->>C: dm_processing
        opt 지연 분석 모드
            S->>S: WAV 분석 항목 누적
        end
        S->>D: /message(STT 관측값)
        D-->>S: DM 응답
        S->>DB: BOT 메시지·DM 응답 저장
        S->>T: 응답 텍스트 합성
        T-->>S: WAV 또는 PCM 스트림
        S-->>C: TTS 오디오
        S-->>C: dialog_response
    end

    S->>G: AudioInputGate.resume(token)
    S->>G: USER lease 반환
    opt 즉시 분석 모드
        S->>A: USER WAV 분석
        A->>DB: 감정·치매·우울·바이오마커 저장
        A-->>C: 분석 결과 이벤트
    end

END 수락 조건

입력 gate는 모든 END에서 닫히지 않습니다. 다음 검사를 모두 통과한 첫 END만 사용자 턴으로 수락합니다.

  • activity가 현재 발화 세대에 속함
  • END에 STT 결과가 있고 텍스트가 비어 있지 않음
  • 한 글자라면 응, 왜, 뭐 중 하나
  • 다른 USER 턴이 처리 중이 아니며 USER lease를 확보함
  • 비동기 실행 직전에도 발화 세대가 여전히 현재임

검사에서 탈락한 END는 gate를 닫지 않고, 보류했던 무응답 관찰을 재개합니다. 보조 처리권 (REQUERY, PERSIST)이 먼저 잡혀 있으면 정해진 정책에 따라 기다린 뒤 USER lease로 승격합니다.

저장과 출력 순서

  1. USER 메시지와 STT confidence를 저장합니다.
  2. stt_result, dm_processing을 보냅니다.
  3. 지연 분석 모드면 WAV 참조를 누적합니다.
  4. DM을 호출합니다. DM API 왕복과 BOT/DM 응답 저장은 한 단계로 취급합니다.
  5. 현재 response generation이면 TTS를 먼저 보내고 그 뒤 dialog_response를 보냅니다.
  6. finally에서 gate token과 USER lease를 반납합니다.
  7. 즉시 분석 모드라면 gate가 열린 뒤 분석을 실행합니다.

따라서 분석 지연이 다음 발화 입력을 막지 않습니다. 반대로 DM/TTS/dialog_response가 끝나기 전에는 다음 PCM이 EPD로 전달되지 않습니다.

실패와 재시도

DM 호출은 최대 3회 시도하며 실패 사이에 1초, 2초 대기합니다. 모든 시도가 실패하면 현재 generation에만 dialog_error를 보내고 턴을 종료합니다. TTS 실패는 tts_error로 soft-fail하며 저장된 대화 턴은 유지합니다. 어떤 분기에서도 gate와 lease는 finally에서 반납됩니다.

바지인으로 generation이 바뀐 경우는 바지인, 스트리밍 출력 순서는 TTS 스트리밍을 참고하세요.