Steven
Steven5 분 소요

AI 전사는 왜 기술 용어를 잘못 알아듣는가 (그리고 우리는 어떻게 고쳤나)

라이브 세션이 "what is the pointer in C++"를 "what is the point in life"로 받아적었습니다. 그 전사 기록에서 GeekBye v2.0.11까지 이어진 포렌식 추적기 — keyterm 바이어싱, 연결을 끊어버리던 타이밍 레이스, 그리고 우리의 수정이 역효과를 낸 날의 이야기입니다.

전사
안정성
엔지니어링
GeekBye 릴리스
AI 전사는 왜 기술 용어를 잘못 알아듣는가 (그리고 우리는 어떻게 고쳤나)

7월 2일, 우리는 테스트 세션을 돌리며 GeekBye에 소리 내어 간단한 질문을 던졌습니다. "What is the pointer in C++?" (C++의 포인터란 무엇인가?)

라이브 전사는 시적인 답을 내놓았습니다:

[23:16:37] You: Tell me, what is the point in life? [23:16:52] You: Handy Plus. [23:17:02] You: What the pointer in Plus Plus? [23:17:09] You: C.

"pointer in C++"(C++의 포인터)가 "point in life"(인생의 의미)로 둔갑한 것입니다. 같은 세션의 헬스 메트릭이 나머지를 말해줬습니다. 163초 동안 전사 연결 끊김 3회, 그리고 전사 기록에 뚫린 51초짜리 구멍. 그리고 나중에 가장 중요한 것으로 밝혀진 단서가 하나 더 있었습니다. 로컬에 저장된 오디오를 다시 전사해 공백을 메우는 세션 후 복구 패스는 이 문장을 거의 정확하게 알아들었습니다: "a pointer in plus, plus? What the pointer in plus, plus C++."

오디오는 멀쩡했습니다. 라이브 모델이 C++를 예상할 이유가 없었을 뿐입니다.

이 글은 GeekBye v2.0.11의 이야기를 실제 전사 기록과 프로덕션 로그로 풀어낸 것입니다.

음성 모델이 당신의 어휘를 잘못 알아듣는 이유

음성 인식은 예측 문제입니다. 애매한 오디오가 주어지면 모델은 가장 그럴듯한 단어를 고릅니다 — 범용 모델에게 "point in life"는 "pointer in C++"보다 훨씬 그럴듯한 문구입니다. 회의 전사에서 Kubernetes가 "cube and eddies"로 찍히는 걸 본 적 있는 엔지니어라면 누구나 이 실패를 만나봤습니다.

해결책은 더 좋은 마이크가 아닙니다. keyterm 바이어싱입니다. 세션이 시작되기 전에, 일반적으로는 드물지만 당신에게는 나올 법한 단어들을 모델에 알려주는 것이죠. 우리 음성 프로바이더는 세션당 최대 50개의 바이어싱 용어를 지원합니다. 여기서부터가 부끄러운 부분입니다. 그 용어를 전달하는 배관은 클라이언트, 백엔드, 프로바이더까지 스택 전체에 엔드투엔드로 이미 존재했습니다 — 그런데 거기에 값을 채워 넣는 것이 아무것도 없었습니다. 모든 세션이 도메인 도움 없이 맨몸으로 돌고 있었던 겁니다.

수정 1: 프로필이 모델의 어휘가 된다

GeekBye는 이미 당신의 도메인을 알고 있습니다 — 활성 프로필에 적혀 있으니까요. v2.0.11은 프로필의 이름과 설명에서 바이어싱 keyterm을 도출합니다. 기호가 들어간 용어(C++, Node.js), 약어(SQL, AWS), 카멜케이스 이름(TypeScript, PostgreSQL), 그리고 고유명사. 당신의 스택을 언급한 프로필은 이제 그 스택을 낯선 것이 아니라 예상되는 것으로 만듭니다.

수정이 모든 것을 악화시킨 날

첫 번째 버전은 대문자로 시작하는 모든 단어를 고유명사로 취급했습니다. 내부 테스트 빌드에서(이건 고객에게 도달한 적이 없습니다), 산문으로 작성된 프로필이 이런 바이어싱 목록을 모델에 보냈습니다:

Senior, Writing, Direct, For, Includes, Write, Role, Intent…

음성 모델을 "For"라는 단어 쪽으로 바이어스하는 것은 아예 바이어스하지 않는 것보다 나쁩니다. 바로 다음 테스트 세션에서, 또박또박 여러 번 발음한 "speak"라는 단어가 "Clicky", "Hey, Vicky", *"Peter Paderty"*로 돌아왔습니다. 이 교훈의 수업료는 오후 반나절이었습니다: 변별력 있는 용어로만 바이어스하라. 대문자로 시작하는 단어는 이제 문장 중간에 나타날 때만 카운트됩니다(진짜 고유명사 신호이기 때문입니다). 모든 단어가 대문자로 시작하는 markdown 헤딩은 절대 기여하지 않습니다. 같은 프로필은 이제 정확히 LinkedIn, AI, CEO, MCP를 도출합니다 — 그리고 검증 세션에서는 여러 언어를 빠르게 오가는 오디오를 199초 연속으로 정확하게 전사했습니다. 전사 세그먼트 189개, 오류 0건이었습니다.

수정 2: 연결을 끊어버리던 레이스

keyterm은 잘못 알아들은 단어들을 설명해 줬습니다. 하지만 세 번의 연결 끊김은 설명하지 못했습니다.

그 추적은 더 미묘한 곳으로 이어졌습니다. 우리 프로바이더는 자체 음성 활동 감지(VAD)에 따라 침묵 약 1초 시점에 전사를 커밋(확정)합니다. 우리 클라이언트 매달려 있는 문장 조각을 플러시하기 위해 침묵 250밀리초 시점에 안전 커밋을 보냅니다. 프로바이더가 이미 커밋했다는 확인이 되돌아오는 데는 1~3초가 걸립니다. 이 세 숫자로 계산해 보세요. 프로바이더가 먼저 커밋할 때마다 우리의 안전 커밋은 거의 빈 버퍼를 향해 발사됐고 — 거기에 대한 프로바이더의 반응은 정중한 거절이 아니었습니다. 연결을 끊어버렸습니다. 말하다 잠깐 멈출 때마다 동전 던지기였던 셈입니다.

v2.0.11은 이에 맞서 두 겹의 방어를 배포합니다:

  1. 앱에서: 커밋된 전사가 도착하면 클라이언트는 프로바이더의 버퍼가 방금 플러시됐다는 것을 알게 되고, 불필요한 안전 커밋을 건너뜁니다.
  2. 같은 날 백엔드에서: 앱과 프로바이더 사이에 있는 프록시가 프로바이더의 오디오 회계를 그대로 미러링합니다 — 모든 오디오 프레임과 모든 커밋 확인을 지연 없이 보고 있으므로, 프로바이더가 거부할 커밋은 아예 전달을 거부합니다. 이 방어는 아직 업데이트하지 않은 사용자를 포함해 모든 클라이언트 버전을 한꺼번에 보호합니다.

한 시간도 안 돼 프로덕션에서 작동하는 것을 확인했습니다. 가드는 버퍼 오디오 178ms256ms를 실은 운명이 정해진 커밋들을 가로챘습니다 — 그날 이전이었다면 하나하나가 확정된 연결 끊김이자 누군가의 회의 노트에 뚫린 구멍이었을 것들입니다. 그날 오후 60분짜리 연속 세션에서는 5번의 가로채기와 끊김 0회를 기록했습니다. 수정 전, 같은 날 아침에는 실제 사용자 한 명이 바로 이 버그와 싸우느라 6분 동안 녹음을 다섯 번이나 재시작했습니다.

함께 실리는 두 가지 작은 수정

AI 인사이트는 이제 알맹이가 쌓일 때까지 기다립니다. 초반의 뭉개진 조각들은 그동안 GeekBye의 라이브 제안 칩에 흘러들어가, 잘못 알아들은 C++ 질문에서 "Defining Life's Ultimate Purpose"(인생의 궁극적 목적 정의하기) 같은 주제를 자신만만하게 만들어냈습니다. 제안은 이제 세션에 진짜 대화의 질량이 쌓일 때까지 기다립니다.

복구된 텍스트에 올바른 화자가 붙습니다. 우리의 C++ 질문을 정확히 전사해낸 복구 패스는 그것을 "Them"(상대방)에게 귀속시켰습니다. 로컬에 저장되는 오디오 타임라인이 이제 누가 말하고 있었는지 기록하므로, 복구된 세그먼트는 You 또는 Them으로 올바르게 귀속됩니다.

스코어보드

지표 (추정이 아닌 실측) 수정 전 v2.0.11 + 백엔드 가드 이후
테스트 세션의 연결 끊김 163초 동안 3회 0
가장 긴 전사 공백 51초 검증 시 최악 공백 약 6초
"pointer in C++" "point in life" 정확히 인식, 바이어스된 어휘
프로바이더에 도달한 운명이 정해진 커밋 전부 0 (백엔드에서 가로챔)

실시간 음성 API 위에서 개발하고 있다면

이번 릴리스에서 다른 곳에도 적용할 수 있는 세 가지 교훈:

  1. 바이어싱 기능에 먹이를 줘라. STT 프로바이더가 keyterm/문구 힌트를 지원한다면, 작고 변별력 있는 어휘를 채워 넣는 것은 얻을 수 있는 가장 값싼 정확도 향상입니다 — 그리고 흔한 단어를 채워 넣는 것은 정확도 손실입니다.
  2. 네트워크 왕복의 불리한 쪽에서 프로바이더 자체 상태 머신과 레이스하지 마라. 우리 클라이언트는 250ms 대 3초의 정보 레이스에서 이길 수 없었습니다. 가드는 두 신호가 만나는 곳에 있어야 합니다 — 우리의 경우 백엔드 프록시였습니다.
  3. 배포 전에 라이브 빌드에서 검증하라. keyterm 리그레션을 잡아낼 수 있었던 것은, GeekBye의 모든 릴리스가 출시 전에 서명·공증된 빌드로 프로덕션을 상대로 테스트되기 때문입니다. 문제의 버전은 내부 머신 한 대에서 몇 시간 존재했을 뿐, 당신의 Mac에는 존재한 적이 없습니다.

GeekBye v2.0.11은 지금 배포 중입니다 — v2를 쓰고 있다면 자동 업데이트로 이미 적용되어 있습니다. 이번 릴리스의 기반이 된 안정성 작업은 나쁜 Wi-Fi에서 AI 노트테이커가 멈추는 이유GeekBye v2의 달라진 점을 참고하세요. 라이브 전사를 일상적으로 쓰는 방법은 GeekBye의 실시간 전사부터 시작하면 됩니다.