콘텐츠로 이동

분석과 영속화

대화 연결 시 dialog 행을 만들고, 턴이 진행될 때 EPD·USER·BOT·DM 응답과 분석 결과를 PostgreSQL에 기록합니다. 기본 대화 경로와 OpenAI Realtime 경로는 입력 방식은 다르지만 공통 저장 서비스를 사용합니다.

기본 SOHRI 턴의 기록

시점 주요 기록
연결 수립 dialog, 인증에 따른 workspace/api key/member, started_at
EPD END 수락 dialog_epd, STT 텍스트·점수·confidence·duration·음성 경로
DM 호출 전 USER dialog_message, STT confidence
DM 응답 후 BOT dialog_message, DM 원본 응답, 키워드·슬롯 등 응답 파생값
분석 완료 감정·치매·우울·음성 바이오마커 결과
최종화 일반 대화 요약, 대화 단위 바이오마커 요약

USER 메시지는 DM보다 먼저 저장됩니다. DM 서비스는 응답을 받은 뒤 BOT 메시지와 응답 데이터를 저장하고 호출자에게 반환합니다. 따라서 이후 바지인이 generation을 취소해도 이미 완료된 USER/BOT 저장과 DM 호출은 롤백하지 않습니다. 취소는 클라이언트 출력만 억제합니다.

분석 모드

sohri.analysis.deferred-enabled가 분석 시점을 결정합니다.

즉시 분석 (false)

정상 SOHRI 턴에서는 DM/TTS/dialog_response가 끝나 입력 gate와 USER lease를 반납한 다음 USER WAV를 Vocal Biomarkers API로 분석합니다. 결과를 저장하고 다음 이벤트를 보냅니다.

  • emotion_result
  • dementia_result
  • depression_result
  • biomarker_result

OpenAI Realtime USER 기록은 세션별 직렬 record tail에서 저장됩니다. 즉시 분석 작업은 별도 future로 등록되고, 대화 최종화가 설정된 timeout까지 실제 성공 여부를 기다립니다.

지연 분석 (true)

턴 처리 중 WAV 참조와 message ID를 DeferredAnalysisStore에 누적합니다. 대화 최종화 시 항목별 분석을 병렬 실행하고 전체 flush 결과를 확인합니다. OpenAI Realtime의 임시 WAV는 분석 후 삭제합니다.

지연 모드에서는 최종화 시작·완료 시 analysis_processing, analysis_complete를 보냅니다. 연결이 이미 닫혔다면 DB 후처리는 계속되지만 이벤트는 전송하지 않습니다.

OpenAI Realtime 기록

OpenAI 엔진은 provider의 발화·응답 ID를 상관키로 사용합니다.

  1. speech_stopped에서 USER 오디오를 임시 WAV로 캡처합니다.
  2. transcription 완료 시 USER EPD 성격의 기록과 USER 메시지를 비동기로 저장합니다.
  3. 완료 또는 incomplete인 assistant output만 BOT 메시지로 저장합니다.
  4. cancelled/failed output은 스트림을 닫지만 BOT 기록으로 확정하지 않습니다.
  5. BOT 오디오가 누적 상한을 넘지 않았다면 메시지 저장 후 아카이빙 훅을 호출합니다.

세션별 ConversationRecordSink tail이 USER/BOT 기록 순서를 보장합니다. 최종화는 이 tail을 최대 5초 기다리므로 종료 신호가 마지막 기록을 앞지르는 위험을 줄입니다. timeout이어도 최종화 자체는 계속합니다.

취소 발화 오염 방지

EPD가 barge_in_phase=cancelled로 끝낸 발화를 PERSIST 모드로 보존하면 dialog_message.speech_phase=CANCELLED를 기록합니다. 이 오디오는 진짜 사용자 발화일 수도 있지만 잔류 TTS 에코일 수도 있으므로 다음 소비자는 CONFIRMED를 화이트리스트로 조회합니다.

  • 일반 대화 요약 입력
  • 대화 단위 바이오마커 요약 입력

블랙리스트 방식이 아니므로 미래의 새 speech phase가 분석 근거로 자동 유입되지 않습니다.

오디오 아카이빙

아카이빙은 대화 기능과 독립된 선택 기능입니다.

  • SOHRI USER: dialog_epd를 USER message에 연결하고 Pub/Sub 작업을 발행
  • OpenAI USER: 선택 플래그가 켜지면 GCS/DB 직접 보관
  • BOT: 실제로 송신된 오디오만 GCS/DB 직접 보관
  • 스트리밍 BOT: 정상 completed일 때만 송신 PCM을 WAV로 조립해 보관

아카이빙 실패는 대화, 저장, 세션 종료를 실패시키지 않으며 로그와 메트릭으로만 드러납니다. 종료 단계는 종료·정리를 참고하세요.