About

AI 아바타 SDK 는 「어디까지 떼어 낼 수 있나」 로 고른다 — Anam 3모드와 떼어 낼수록 늘어나는 책임

full · custom_llm · passthrough 를 붙여 보며 걸린 것 — 400 에러, PCM 형식, 그리고 API 키는 서버에

AI 아바타 서비스를 고를 때 얼굴 품질부터 비교하게 된다. 직접 붙여 보고 생각이 바뀌었다. 먼저 볼 건 어디까지 떼어 낼 수 있나다. 그리고 떼어 낼수록 우리 쪽 코드가 무거워진다.

이 글을 읽으면 Anam 의 세 모드 중 무엇을 고를지, 고른 뒤 무엇을 직접 챙겨야 하는지 정리된다. 하나 더. API 키는 브라우저에 두지 않는다.

시작은 400 에러였다

app10 에 Anam 테스터를 만들면서 처음엔 아바타만 지정해 봤다(avatarId 만). 기본 WebRTC 연결에서 400 avatar_only_requires_integration 으로 거절된다. 얼굴만 쓰려면 목소리를 정하거나, 오디오를 직접 넣겠다고(passthrough) 밝혀야 한다. 여기서 「모드」 라는 게 보이기 시작했다.

세 모드

STTLLMTTSFacefullAnamAnamAnamAnamcustom_llmAnamyouAnamAnampassthroughyouyouyouAnamThe more stages you take over, the more code lands in your browser and server
모드 personaConfig Anam 이 맡는 것 우리가 맡는 것
full voiceId + llmId + systemPrompt STT · LLM · TTS · 얼굴 없음
custom_llm llmId: CUSTOMER_CLIENT_V1 STT · TTS · 얼굴 대답 생성 → talk() / createTalkMessageStream()
passthrough enableAudioPassthrough: true 얼굴만 STT · LLM · TTS 전부. PCM 을 sendAudioChunk() 로

custom_llm 은 MESSAGE_HISTORY_UPDATED 를 듣고 우리 LLM 을 부른다. 사용자가 끼어들면 그 LLM 스트림도 우리가 끊어야 한다. Anam 이 대신 끊어 주지 않는다.

passthrough 는 오디오 형식을 맞추는 일이 생긴다. PCM s16le · 16kHz · mono 를 base64 조각으로 보내고 endSequence() 로 끝을 알린다. 마이크 쪽도 브라우저가 주는 webm/opus 를 WAV 로 바꾸는 코드를 직접 썼다. 생각보다 일이다.

그래서 언제 무엇을

  • 대화하는 얼굴이 일단 필요하고, 대답은 Anam 쪽 LLM 으로 충분하다 → full

  • 우리 데이터 · 우리 프롬프트로 대답해야 한다(사내 문서 검색, 상담 흐름) → custom_llm. 대부분은 여기가 현실적인 선이다

  • 목소리까지 우리 것이어야 한다(클로닝한 목소리, 다른 TTS) → passthrough. 오디오 형식 · 끼어들기 · 동기화를 전부 떠안는다

다른 아바타 서비스(HeyGen, Tavus 등)도 LLM · TTS 교체를 지원하는지는 이번에 문서로 확인하지 못했다. 비교할 때는 같은 질문 하나면 된다. 「어느 단계부터 우리가 맡을 수 있고, 그때 무엇이 우리 쪽으로 넘어오나」.

API 키는 서버에

Anam 공식 JavaScript quickstart 는 로컬 HTML 데모라서 API 키를 브라우저 스크립트에 넣고 세션 토큰을 받아 온다. 데모로는 편하다. 그대로 배포하면 키가 누구에게나 보인다.

app10 은 이렇게 나눴다.

  • API 키는 서버에만 둔다

  • 서버가 personaConfig 를 담아 잠깐 쓰는 세션 토큰을 발급한다. 브라우저는 그 토큰으로 WebRTC 만 연다

  • 모드도 서버가 정한다. 브라우저가 personaConfig 를 마음대로 못 바꾼다. 모르는 mode 가 오면 full 로 떨어뜨린다

모드별로 personaConfig 가 맞게 나가는지는 request spec(WebMock)으로 확인했다. 실제 키로 세 모드를 다 연결해 보는 건 아직이다. passthrough 에 16kHz 가 아닌 24kHz PCM 을 넣으면 어떻게 깨지는지는 직접 보고 나서 덧붙이겠다.

아바타 SDK 를 붙이면서 모드 선택이나 키 관리 구조가 고민이라면 negabaro 에 물어봐도 된다 (문의).

핵심 개념

1

아바타만 지정하면 400 — 목소리를 정하거나 passthrough 를 밝힌다

2

대부분은 custom_llm — 우리 LLM 을 쓰고 끼어들기 때 스트림을 직접 끊는다

3

passthrough 는 PCM s16le · 16kHz · mono 를 base64 조각으로, 끝은 endSequence()

4

API 키는 서버에, 브라우저엔 세션 토큰만. 모드도 서버가 정한다

사용 사례

사내 문서로 대답하는 안내 아바타 — custom_llm 클로닝한 목소리로 말하는 아바타 — passthrough
← 말하는 AI 아바타는 모델 하나가 아니다 — STT · LLM · TTS 끝에 얼굴을 붙인 파이프라인, 적은 지연의 합 FaceFusion 은 방법론이 아니라 부품 조립기다 — 얼굴 바꾸는 기술 4계열 지도 →