Gemini 3.8 TTS가 지시문까지 읽는다면 speech_metadata 확인하기

Gemini 3.8 Flash TTS에서 대본과 말투 지시를 분리하고 Interactions API 요청 및 음성 응답을 확인하는 이전 절차를 설명합니다.

세이지색 배경의 밝은 카드에 검은 선으로 그린 스텐실 시트와 Gemini 3.8 TTS 제목.

Gemini 3.8 Flash TTS에서는 읽을 말은 대본에, 지속적인 말투 지시는 음성 메타데이터에 넣습니다. 모델이 문자 그대로 읽을 대본으로 처리하는 텍스트에 ‘차분하게 말해’라는 지시를 넣으면 그 문장도 음성에 포함될 수 있습니다. Gemini 3.8 Flash TTS 이전 안내는 대본 텍스트와 말투 메타데이터를 구분합니다.

Google은 2026년 9월 22일 API 릴리스 노트에서 새 TTS 모델을 발표했습니다. 이 글은 공식 문서에 맞춘 Interactions REST API 이전 예시입니다. 요청 구조와 디코딩 로직은 로컬에서 확인할 수 있지만 실제 청취 시험, 음질 개선, 현재 Ofox의 해당 엔드포인트 지원을 주장하지 않습니다.

읽을 내용과 읽는 방식을 분리하기

정보이 예시에서 넣을 위치
청자가 들어야 할 말text 콘텐츠의 text 필드
차분하고 명료하게 등 지속적인 말투speech_metadata 주석의 style
선택한 음성generation_config.speech_config
음성 출력 요청response_format

지시가 짧아도 분리하면 요청을 점검하기 쉽고 대본과 혼동하지 않게 됩니다. 등장인물이 ‘차분하게 말해’라고 말하는 대본은 다릅니다. 실제 청자가 들어야 하는 말이므로 대본에 넣습니다.

모델 문서는 특정 시점의 발성 이벤트도 설명합니다. 과거 프롬프트 태그나 임의 주석이 모두 지원된다고 가정하지 말고 선택한 모델과 API의 현재 문서를 사용하세요.

요청부터 응답까지 하나의 API 형식 사용하기

다음 예시는 Interactions API를 사용합니다. input 배열과 annotations를 GenerateContent 본문이나 구형 SDK의 필드와 섞지 마세요. 해당 요청 형식은 공식 음성 생성 가이드를 따릅니다.

다음을 request.json으로 저장합니다. 짧은 영어 대본을 사용하는 예시를 그대로 유지했습니다.

{
  "model": "gemini-3.8-flash-tts",
  "input": [{
    "type": "user_input",
    "content": [{
      "type": "text",
      "text": "The next train leaves at noon.",
      "annotations": [{
        "type": "speech_metadata",
        "style": "calm and clear"
      }]
    }]
  }],
  "response_format": {"type": "audio"},
  "generation_config": {
    "speech_config": [{"voice": "Kore"}]
  }
}

접근 권한이 있는 직접 Google 계정의 요청은 다음과 같습니다.

curl --fail-with-body --silent --show-error \
  'https://generativelanguage.googleapis.com/v1beta/interactions' \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -H 'Content-Type: application/json' \
  --data-binary @request.json > response.json

본인의 키를 환경변수로 안전하게 전달하세요. 이 명령은 제공자 API를 실제 호출하며 사용 요금이 발생할 수 있습니다. 로컬 JSON 파싱 성공만으로 계정의 모델 접근이나 제공자의 요청 수락이 증명되지는 않습니다.

단일 화자 예시입니다. 공식 다중 화자 설정은 구조가 다르므로 위 speech_config 배열을 임의의 대화 스키마로 바꾸지 마세요. 각 대화 턴의 화자는 설정된 화자와 일치해야 합니다.

응답 확인 후 음성 디코딩하기

response.json에 저장된 HTTP 오류는 음성이 아닙니다. base64를 디코딩하기 전에 HTTP 결과와 응답 구조를 확인하세요. Interactions REST 응답에서는 model_output 단계와 그 content 블록을 살펴봅니다. SDK의 편의 속성인 output_audio가 원시 JSON에도 있다고 가정하지 마세요.

안전한 디코더는 다음을 확인해야 합니다.

  1. 오류 응답을 음성 파일로 쓰지 않습니다.
  2. model_output의 음성 콘텐츠를 선택하고 텍스트와 도구 콘텐츠는 제외합니다.
  3. 반환된 MIME 유형을 확인한 뒤 확장자를 정합니다.
  4. base64를 디코딩하고 원래 컨테이너 형식을 보존합니다.

이전 가이드는 비스트리밍 응답의 기본 출력이 WAV라고 설명합니다. 과거 raw PCM 예제의 WAV 헤더를 무조건 붙이지 마세요. 이미 유효한 WAV에 헤더를 다시 붙이면 파일이 손상될 수 있습니다. 다른 형식을 요청했다면 확장자만 바꾸지 말고 실제 MIME 유형과 컨테이너를 따릅니다.

첫 이전 시험은 작게 시작하기

화자 한 명, 짧은 대본, 말투 지시 하나로 시작하세요. 누락된 단어, 추가로 읽힌 지시문, 발음, 예상치 못한 목소리 변화를 듣고 확인합니다. 요청, 모델 ID, 시각, 출력 파일을 함께 보관하세요. 이는 제안하는 합격 기준이며 이 글에서 얻은 실험 결과는 아닙니다.

그다음 대본을 늘리거나 화자를 추가합니다. 한 번에 한 변수만 바꾸세요. 지시를 메타데이터로 옮기면서 음성, 대본 분할, API까지 동시에 바꾸면 원인을 찾기 어렵습니다.

내레이션 작업에서는 영상에 넣기 전에 음성과 정확한 대본을 비교합니다. 얼굴 없는 영상 제작 워크플로(영문)는 전체 제작 과정을 다룹니다. TTS 이전은 그중 한 단계이며 타이밍, 발음, 특정 음성 사용에 대한 동의까지 보장하지 않습니다.

다른 제공자를 경유하기 전 확인할 사항

OpenAI 호환 텍스트 엔드포인트가 있다고 Google Interactions API와 음성 메타데이터 필드가 지원되는 것은 아닙니다. 구체적인 음성 경로, 지원 모델 ID, 출력 형식을 확인하세요. 이 글의 직접 Google 예시는 Ofox 엔드포인트 설정법이 아닙니다.

모델 선택과 API 형식 이전을 분리하세요. Gemini 3.8 Flash-Lite TTS는 관련 모델이지만 모델 문자열을 바꾸기 전에 자체 문서에서 지원과 동작을 확인해야 합니다. 멀티모달 API 개요(영문)는 전반적 맥락을 제공하지만 현재 제공자 문서를 대신하지는 않습니다.

자주 묻는 질문

말투 지시를 소리 내어 읽는 이유는 무엇인가요?
새 모델은 입력 텍스트를 문자 그대로의 대본으로 처리합니다. 지속적인 말투 지시는 대본에 삽입하지 말고 문서화된 음성 메타데이터 위치에 넣으세요.
이 JSON을 GenerateContent에 복사해도 되나요?
아닙니다. 이 예시는 Interactions 입력과 주석 필드를 사용합니다. GenerateContent는 요청 구조가 다르므로 해당 API의 공식 예제를 처음부터 끝까지 사용하세요.
출력은 항상 raw PCM인가요?
아닙니다. 이전 안내는 비스트리밍 응답의 기본값이 WAV라고 설명합니다. 실제 응답 형식을 확인하고 WAV 헤더를 두 번 넣지 마세요.