4. 핵심 기술 난제

⚠ 2026-08-28 방향 전환 — 이 페이지보다 결정 기록이 우선한다

도메인을 다산콜센터 하나로 줄이고 외국인 고객 지원을 차별점으로 세웠다 (_project/decisions/201, 비공개). 아래 본문의 금융보험·쇼핑·질병관리본부 서술은 그 시점의 사실이라 지우지 않았다 — 절대 원칙 8(“실패를 지운 기록은 기록이 아니다”)과 같은 이유로, 계획이 바뀐 사실 자체가 기록이다.

이 페이지에서 바뀐 것: B-0 도메인 라우팅 난제가 사라졌다(라우팅할 대상이 없다). 대신 A-5 동시 통번역의 지연 예산이 새 난제로 들어온다. ⚠ 1차 범위 ⓑ(서툰 한국어를 정확히 전사)에서는 번역 경로가 없다 — 한국어를 한국어로 전사하므로 STT 지연만 얹힌다. ⓑ 를 먼저 하는 것이 지연 측면에서도 유리하다. 번역+TTS 왕복은 ⓐ 확장 시점의 문제다. 둘 다 아직 미측정이며, 기획서 4.3절에 예산 항목만 열어 두었다.

4.1 트리거 판정 — 언제 검색할 것인가

일반 RAG는 완성된 질문을 받는다. 스트리밍은 다르다.

0.4초  "아"
0.9초  "아 저번에"
1.6초  "아 저번에 가입할"
2.4초  "아 저번에 가입할 때 6개월"
3.1초  "아 저번에 가입할 때 6개월 할인 된다고 했는데"

검토할 전략

전략 방법 예상 문제
침묵 기반 N초 무음 시 검색 말이 느린 고객에서 지연
종결어미 기반 “~요”, “~까요”, “~는데” 패턴 중간에 끊어 말하면 오발동
길이 기반 토큰 N개 누적 시 의미 무관하게 발동
하이브리드 위 조합 + 디바운싱 튜닝 복잡
STT 엔드포인팅 기반 (3주차 v1 채택) Google STT is_final: true를 발화 종료 신호로 사용 자체 침묵 타이머를 또 두면 STT 자체 지연과 이중으로 쌓인다 — V4 실측(발화 종료 후 +346ms)이 이미 STT 내부 엔드포인팅 지연이므로 여기에 얹기만 하면 된다. 2026-08-25 팀 컨펌, _project/decisions/003-인터페이스-스키마-v2.md

“적절한 시점”의 정의 — 규칙 기반 채점을 위해 허용 창을 고정한다.

골든셋의 각 질문에 발화 종료 시각을 라벨링한다. 발화 종료 후 0 ~ 1,500ms 이내 발동을 “적절”로 판정한다. 0ms 이전(말 끝나기 전) 발동은 조기 발동, 1,500ms 초과는 지연 발동으로 각각 별도 집계한다.

⚠ 원래 800ms였으나, 침묵 기반 트리거(700~1,000ms 대기)는 800ms 창 안에서 거의 모든 발동이 구조적으로 “지연”이 되어 적절 발동률 0.85가 애초에 달성 불가능했다. 보완지시서 1번(안 A)에 따라 1,500ms로 확정(2026-08-25 팀 컨펌).

산식: STT 엔드포인팅 지연(is_final 도착까지 +346ms, V4 실측) + 트리거 판정·큐잉 여유(500ms) + 버퍼(≈650ms). 3주차 v1을 STT is_final 기반으로 잡기로 하면서(위 표) “침묵 대기 최대 1,000ms”라는 원래 근거는 STT 자체 지연(+346ms)으로 대체됐다 — 자체 침묵 타이머를 따로 두지 않기 때문이다.

침묵 임계값을 실측해 역산하는 안(안 B)은 검토했으나, 보유한 AI Hub 데이터가 발화 단위로 이미 잘려 있어 발화 간 실제 침묵 길이를 잴 수 없어 채택하지 않았다. 트리거 지연시간 분포(p50/p95)는 별도로 계속 기록한다 — 허용 창은 합/불 판정선일 뿐, 개선을 보여주는 건 분포다. (ai/apps/evaluation/harness.pyreport["trigger"]["latency_ms"]로 이미 계산한다.)

이 정의가 없으면 평가 설계 6.2절의 “모든 지표를 규칙으로 계산한다” 원칙을 지킬 수 없다. 1주차 골든셋 스펙에 포함한다.

4.2 STT 오류 내성 — 가장 중요한 실험

음성인식은 틀린다. 사람은 알아듣지만 검색은 실패한다.

실제 발화 STT 결과 문제 도메인
해지 해제 완전히 다른 조항 검색 금융보험
중도해지수수료 중도 해지 수수료 띄어쓰기로 형태소 분해 실패 금융보험
반품 반환품 완전히 다른 조항 검색 쇼핑
증상징후 증상 징후 띄어쓰기로 형태소 분해 실패 질병관리본부

4개 도메인마다 어휘가 다르다(금융 용어 vs 행정 용어 vs 상품명 vs 의학 용어). nori 사용자 사전에 도메인별 복합어를 추가하는 작업이 필요하며, 도메인 하나의 사전으로 4개를 모두 커버할 수 없다는 점을 실험 설계에 반영한다.

Elasticsearch가 필요해지는 이유

1. nori 형태소 분석기 → 띄어쓰기 오류 흡수
2. 자모 분해 필터      → 유사 발음 오인식 대응
3. dense_vector 필드   → 의미 기반 검색
4. RRF 병합            → 위 3개 결과 통합

대표 실험 (발표의 핵심 숫자)

STT 오류율을 통제하며 주입 → 구간별 성능 측정

오류율      0%    5%    10%   15%   20%
──────────────────────────────────────
BM25만      -     -     -     -     -
벡터만      -     -     -     -     -
하이브리드   -     -     -     -     -
C-5 마스킹  -     -     -     -     -   ← 재현율 곡선 추가

수치는 실측값으로 채운다. “오류율 10%에서 Recall@5가 0.48 → 0.66으로 복구” 형태의 문장 하나가 프로젝트 전체를 설명한다.

이 실험의 성격을 정확히 서술할 것 — 실제 데이터 부족을 대체하는 합성이 아니라, 구간별 비교를 위해 오류율을 통제한 설계다. 실제 통화로는 오류율 5%/10%/15% 곡선을 그릴 수 없다.

4.3 레이턴시 예산

두 지표를 분리해 둘 다 측정한다.

지표 구간 목표
내부 처리 지연 트리거 발동 → 카드 표시 p95 ≤ 1,000ms
E2E 체감 지연 발화 종료 → 카드 표시 측정·기록 (목표 미설정)

E2E에는 STT 부분 결과 반환 지연, 게이트웨이 홉, 브라우저 렌더링이 포함된다. 이 구간은 통제 밖이므로 목표를 걸지 않되, 통제 가능한 구간과 아닌 구간을 분리했다는 사실 자체를 성과로 기록한다.

내부 처리 예산

단계 목표 최적화 수단
트리거 판정 10ms 규칙 우선
검색 150ms 인덱스 워밍업, 필드 최소화
리랭킹 200ms 상위 20개만, 배치 추론
생성 첫 토큰 500ms 스트리밍 출력 — 카드는 점진 표시
전송 50ms WebSocket 유지 연결

카드 완성까지 1초를 기다리게 하지 않는다. 첫 토큰부터 흘려보내면 상담원 체감이 크게 달라진다.

실측 (2026-08-26) — 생성 모델을 최종적으로 EXAONE-4.0-1.2B(Ollama, think:false


← 개발목차로 돌아가기