작성일
Gem3Park 개발기 5 — 허용 목록, 그리고 오디오 보조 설계를 줄인 이야기
동·호수를 현장 허용 목록으로 검증하게 된 계기, 첫 발화 오디오 fallback을 크게 만들었다가 모든 guided 턴의 '누락 시 전사만' 보조로 줄인 판단, 그리고 그 운영 수치를 정리했다.
Gem3Park 개발기 시리즈 5/8편. 전체 목록은 gem3park 태그에서 볼 수 있다.
존재하지 않는 동·호수는 열지 않는다
7월 8일에 현장의 동·호수 허용 목록을 도입했다. 단지마다 실제로 있는 동과 호수 조합이 정해져 있는데, 지금까지는 STT가 "그럴듯한 숫자"를 뽑으면 그대로 통과했다. 허용 목록 JSON은 단지 한 곳 분량만 1,200줄에 가까웠다. 단말(SIP) 식별자에 설정 파일을 연결해, 목록이 있는 단말에서만 검증이 켜진다.
검증은 이렇게 돌게 했다.
- 파싱한 동·호수가 허용 목록에 없으면 최근 발화 WAV를 Gemini로 한 번 다시 전사한다.
- 다시 전사한 결과도 허용 조합일 때만 슬롯과 명령에 반영한다.
- 같은 검사를 출입 명령을 만들기 직전에 한 번 더 한다.
동·호수는 브리지, 오케스트레이터, 컨트롤러 어느 경로로든 슬롯에 들어올 수 있었다. 그래서 GeminiBridge, GuidedOrchestrator, CallFlowController 세 곳과 명령 실행 직전을 모두 같은 validator로 묶었다. 판정 결과는 통화 요약의 buildingUnitVerifications에 남는다(텍스트 일치인지, 오디오 재전사로 맞았는지).
첫 발화를 놓치면 불필요한 재질문이 쌓인다
문제는 첫 턴이었다. 운영 보고서를 보면 방문 목적이 통째로 빠지거나, 핵심 단어가 빠지거나, 동·호수 숫자를 잘못 듣는 사례가 있었다. 원인을 따져 보니 두 가지였다. 하나는 안내 방송 재생 중 들어온 호출자의 입력이 에코 억제 때문에 전처리도 버퍼 적재도 STT 전달도 안 된다는 점이다. 억제는 "STT에 넣을지"의 정책이어야 하는데, "보관할지"까지 막고 있었다. 다른 하나는 첫 청취 창이 인사말과 비프음이 끝난 뒤에야 열린다는 점이다.
그래서 입력 캡처와 STT 전달을 분리하고, 첫 발화가 불완전하면 Gemini가 원음에서 방문 정보를 구조화해 뽑아 STT와 병합하는 구조를 만들었다.
안전장치가 기능보다 커졌다
7월 22일부터 27일까지 커밋이 52개였고, 그중 28개가 27일 하루에 몰렸다. Gemini 3.6 전환 커밋을 빼면 대부분이 첫 발화 복구를 안전하게 검증하고 켜기 위한 장치였다. 재생 검증용 입력이 중간에 바뀌지 않게 고정하는 장치, 감사 파일의 권한과 경합 처리, 25개 발화를 3개 프로파일로 비교하는 재생, 24시간·300 trigger의 shadow 게이트, 적용이 실패했을 때 되돌리는 절차가 그것이다.
런북에는 "원문 발화, 세션 ID, 동·호수, 차량번호를 터미널이나 보고서에 출력하지 않는다", "private 산출물은 0700 디렉터리와 0600 파일만 허용한다" 같은 규칙이 생겼다. 개인정보를 다루는 도구로서는 필요한 규칙이었다. 하지만 7월 29일에 다시 보니, 새로 생긴 운영 절차가 현장에 필요한 것보다 컸다. 게다가 Gemini 결과가 STT와 다르면 해당 필드를 버리고 unresolved로 처리하는 병합 규칙은, Gemini가 STT의 오류를 올바르게 고친 경우에도 그 결과를 버렸다. 정확도를 원음으로 판단하지 않고 두 모델의 일치 여부로 대신하고 있었다.
한 문장으로 줄이기
7월 30일에 범위를 한 문장으로 줄였다.
모든 guided 수집 턴에서 Google STT가 현재 필요한 동·호수 또는 방문 목적을 찾지 못했을 때만 Gemini가 같은 턴의 오디오를 한 번 전사하고, 그 전사문을 기존 판별 로직에 다시 넣어 누락 슬롯만 보충한다.
| 원칙 | 의미 |
|---|---|
| STT 우선 | Google STT와 기존 판별이 항상 먼저. LLM 전사는 빈 슬롯에만 쓰는 보조 증거 |
| 전사와 판단 분리 | Gemini는 옮겨 적기만 한다. 동·호수 추출, 목적 분류, 긴급 판정, 허용 목록 확인은 코드가 한다 |
| 누락 슬롯만 변경 | 이미 값이 있는 슬롯은 바꿀 수 없다 |
복잡한 구현은 7월 29일에 운영 중이던 코드로 되돌리고, 모든 턴에 대해 이 단순한 보조를 새로 붙였다. 전사문이 다시 파서와 허용 목록을 통과해야 하므로 안전 판단은 늘 코드에 남는다. Gemini가 실패해도 기존 재질문과 상담원 전환 흐름은 막히지 않는다.
운영에서 나온 숫자
2026년 7월 31일부터 8월 5일까지 통화 종료 요약 640건을 집계했다(저장소 포트폴리오 문서 기준).
| 지표 | 결과 |
|---|---|
| 보조 조건이 생긴 통화 | 408건 (63.8%) |
| 보조 전사 시도 | 574회 |
| 빈 슬롯에 실제로 반영 | 139회 (24.2%) |
| 정상 응답 지연 | 중앙값 3.86초, p95 5.09초 |
| 오류 | 62회 (timeout 30, abort 32) |
24.2%는 보조 결과가 빈 슬롯에 들어간 적용률이지, 전사 정확도나 최종 성공률의 향상 폭이 아니다. 3.86초는 통화 중에는 긴 대기다. 턴마다 한 번만 부르고 timeout을 둔 덕에 그 이상 늘지는 않았지만, 지연 자체를 줄이는 일은 남았다.