프로덕션 음성 에이전트는 좋은 모델 하나로 완성되지 않습니다. LiveKit이 4코어·8GB 서버를 10~25개 동시 job의 시작점으로 제안하고, Vapi가 TTS·STT 장애에 대비해 2~3개 fallback provider를 권장하는 이유는 결국 성능보다 Orchestrator의 분리·복구 설계가 더 중요하기 때문입니다.
오케스트레이터는 모델 래퍼가 아니라 세션 운영체제입니다
실시간 음성 시스템에서 Orchestrator는 단순히 STT, LLM, TTS를 직렬 연결하는 코드가 아닙니다. 세션 생성, turn detection, barge-in 취소, timeout budget, provider health score, tool 실행 순서를 한 곳에서 결정하는 운영 계층이어야 합니다. LiveKit이 agent server를 worker pool로 운영하고 job마다 별도 프로세스를 두는 이유도 여기에 있습니다. 세션 경계가 명확해야 한 통화의 지연이나 크래시가 다른 통화의 품질을 오염시키지 않습니다.
STT Provider, LLM Router, TTS Engine은 반드시 교체 가능해야 합니다
프로덕션에서는 모델 품질보다 공급자 장애가 먼저 옵니다. 그래서 STT Provider, LLM Router, TTS Engine은 동일한 request/response 타입이 아니라 스트리밍 이벤트 인터페이스와 공통 에러 코드를 기준으로 추상화해야 합니다. Vapi가 voice fallback과 transcriber fallback을 각각 지원하고 서로 다른 provider 2~3개 구성을 권장하는 것도 같은 맥락입니다. Orchestrator는 기본 경로 외에 degraded mode, retry 가능 단계, 음성 품질 저하 허용 범위를 알고 있어야 합니다.
Tool Server는 함수 호출보다 트랜잭션 경계가 먼저입니다
LLM이 도구를 선택하는 순간부터는 자연어가 아니라 트랜잭션 설계 문제로 바뀝니다. Tool Server는 함수 스키마 검증, 권한 검사, 멱등 키, timeout, 재시도 가능 여부를 판정하고 결과를 구조화된 JSON으로 돌려줘야 합니다. 읽기 전용 조회형 도구와 실제 쓰기 도구를 분리하지 않으면 중복 예약, 잘못된 CRM 업데이트, 결제 재호출 같은 문제가 바로 발생합니다. Vapi의 custom tool과 code tool 패턴은 이 경계를 독립 서비스로 빼라는 신호에 가깝습니다.
State Store는 대화 로그가 아니라 실행 상태를 저장해야 합니다
Pipecat의 context aggregator가 보여주듯이 음성 에이전트 상태는 단순 transcript보다 훨씬 넓습니다. 사용자 발화, assistant가 실제로 말한 TTSText, tool 결과, 요약된 context, 미완료 작업, interruption 플래그가 함께 관리돼야 다음 turn이 정확해집니다. 그래서 State Store는 hot session state와 durable event log를 분리하는 편이 안전합니다. 짧은 대화 메모리는 low-latency 저장소에 두고, 장기 이력은 요약과 함께 비동기 적재해야 token 비용과 복구 시간이 함께 줄어듭니다.
에러 처리와 관측성은 같은 설계 문서에 있어야 합니다
retry 정책만 정의하고 tracing을 나중에 붙이면 원인 분석이 되지 않습니다. Orchestrator, STT Provider, LLM Router, Tool Server, TTS Engine을 turn 단위 trace로 묶고, 각 hop에서 latency, partial transcript, tool arguments, provider error code를 남겨야 병목이 보입니다. LiveKit은 로그 수집, health endpoint, graceful draining을 전제로 설명하고, Vapi Evals는 mock conversation과 tool-call 검증을 배포 전 품질 게이트로 넣을 수 있게 합니다. 특히 음성 출력은 재시도보다 fallback, tool 쓰기 작업은 fallback보다 idempotency가 우선이라는 규칙을 분리해서 가져가야 합니다.
BringTalk은 Zero Retention 경계 안에서 Context Injection을 설계합니다
BringTalk의 설계 원칙은 세션 판단을 Orchestrator에 두고, 고객 상태는 Context Injection으로 필요한 순간에만 주입하며, 민감정보는 Zero Retention 경계 밖으로 밀어내지 않는 것입니다. LQA나 FUA처럼 Golden Time이 중요한 시나리오일수록 CRM 이벤트와 최근 행동 데이터는 강하게 연결하되, 원문 PII와 내부 식별자는 Tool Server 뒤에서 마스킹하거나 별도 조회 토큰으로 치환하는 편이 안전합니다. 이렇게 해야 모델을 바꿔도 정책은 유지되고, 정책을 바꿔도 음성 파이프라인 전체를 다시 짜지 않아도 됩니다.
실제 통화 1건의 흐름 (예시)
1. 고객 전화 수신 → Orchestrator 세션 생성
2. STT: "안녕하세요, 워런티 확인하고 싶어요" → 텍스트 변환 (200ms)
3. LLM: 인텐트 분류 → warranty_check 도구 호출 결정 (300ms)
4. Tool Server: VIN 조회 → 워런티 상태 확인 (100ms)
5. LLM: 결과 기반 응답 생성 (200ms)
→ "고객님, 범퍼투범퍼 보증이 2026년 3월까지 유효합니다"
6. TTS: 텍스트 → 음성 변환 (150ms)
7. 전체 응답 지연: ~950ms (1초 이내 목표 달성)
이 흐름에서 Orchestrator는 단순 라우터가 아닌
세션 상태·도구 호출·fallback·tracing을 모두 관리하는
"세션 운영체제" 역할을 수행합니다.
