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을 STTis_final기반으로 잡기로 하면서(위 표) “침묵 대기 최대 1,000ms”라는 원래 근거는 STT 자체 지연(+346ms)으로 대체됐다 — 자체 침묵 타이머를 따로 두지 않기 때문이다.침묵 임계값을 실측해 역산하는 안(안 B)은 검토했으나, 보유한 AI Hub 데이터가 발화 단위로 이미 잘려 있어 발화 간 실제 침묵 길이를 잴 수 없어 채택하지 않았다. 트리거 지연시간 분포(p50/p95)는 별도로 계속 기록한다 — 허용 창은 합/불 판정선일 뿐, 개선을 보여주는 건 분포다. (
ai/apps/evaluation/harness.py가report["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
/api/chat필수)로 확정하면서 첫 토큰 지연을 실제로 쟀다: 19~157ms, 목표 (500ms) 대비 크게 여유. 250토큰 전체 생성은 2.01~2.14초(목표 3~5초보다도 빠름). 중간 후보였던exaone3.5:2.4b는 3.63초, 최초 후보polyglot-ko-1.3b(HF Transformers, MPS)는 250토큰에 7.6~7.7초로 예산을 크게 벗어나 순서대로 교체했다 —_project/decisions/009·010, 3.1절.