יצירת המרת טקסט לדיבור (TTS)

‫Gemini API יכול להפוך קלט טקסט לאודיו עם דובר אחד או כמה דוברים באמצעות יכולות יצירת הטקסט לדיבור (TTS) של Gemini. אפשר לשלוט ביצירת המרת טקסט לדיבור. כלומר, אפשר לשלב מטא-נתונים מובְנים של תור (‎speech_metadata) ותגי קול מוטבעים כדי להגדיר את הסגנון, המבטא, הקצב והטון של האודיו.

יכולת ה-TTS שונה מיצירת דיבור שמתבצעת באמצעות Live API, שנועד לאודיו אינטראקטיבי ולא מובנה, ולתשומות ולתפוקות מולטי-מודאליות. ‫Live API מצטיין בהקשרים דינמיים של שיחות, אבל TTS דרך Gemini API מותאם לתרחישים שבהם נדרש דיבור מדויק של טקסט עם שליטה מפורטת בסגנון ובצליל, כמו יצירת פודקאסטים או ספרי אודיו.

במדריך הזה מוסבר איך ליצור אודיו עם דובר אחד או עם כמה דוברים מטקסט באמצעות Gemini 3.8 Flash TTS (gemini-3.8-flash-tts) ו-Gemini 3.8 Flash-Lite TTS (gemini-3.8-flash-lite-tts).

לפני שמתחילים

חשוב לוודא שאתם משתמשים במודל Gemini TTS שמופיע בקטע מודלים נתמכים. כדי לקבל את התוצאות הטובות ביותר, כדאי לעיין במאמר מתי כדאי להשתמש באיזה מודל כדי לבחור את המודל המתאים ביותר לעומס העבודה שלכם.

מומלץ לבדוק את מודלי ה-TTS של Gemini ב-AI Studio לפני שמתחילים לפתח.

TTS עם דובר יחיד

כדי להמיר טקסט לאודיו של דובר יחיד באמצעות מודלים של Gemini 3.8 TTS, צריך להעביר את התמליל המדויק ב-parts[].text, לצרף סגנון ברמת התור ב-parts[].speech_metadata ולהגדיר את הקול ב-speechConfig.voiceConfig. אפשר להעביר שם של קול מובנה מראש, מזהה של ספריית קולות מורחבת, מזהה של עיצוב קול בהתאמה אישית (voice_...) או מזהה של שכפול קול (voice_... או voicekey_... אופציונלי ללא שמירת מצב).

בדוגמה הזו, האודיו שנוצר על ידי המודל נשמר בקובץ WAV:

Python

from google import genai

client = genai.Client()

response = client.models.generate_content(
    model="gemini-3.8-flash-tts",
    contents=[{
        "role": "user",
        "parts": [{
            "text": "Have a wonderful day!",
            "speech_metadata": {"style": "cheerful and friendly"},
        }],
    }],
    config={
        "response_modalities": ["AUDIO"],
        "speech_config": {
            "voice_config": {"voice": "Kore"}
        },
    },
)

data = response.candidates[0].content.parts[0].inline_data.data
with open("out.wav", "wb") as f:
    f.write(data)

JavaScript

import {GoogleGenAI} from '@google/genai';
import * as fs from 'node:fs';

async function main() {
   const ai = new GoogleGenAI({});

   const response = await ai.models.generateContent({
      model: 'gemini-3.8-flash-tts',
      contents: [{
         role: 'user',
         parts: [{
            text: 'Have a wonderful day!',
            speechMetadata: { style: 'cheerful and friendly' },
         }],
      }],
      config: {
         responseModalities: ['AUDIO'],
         speechConfig: {
            voiceConfig: { voice: 'Kore' },
         },
      },
   });

   const data = response.candidates?.[0]?.content?.parts?.[0]?.inlineData?.data;
   const audioBuffer = Buffer.from(data, 'base64');

   fs.writeFileSync('out.wav', audioBuffer);
}
await main();

REST

curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.8-flash-tts:generateContent" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{
        "contents": [{
          "role": "user",
          "parts": [{
            "text": "Have a wonderful day!",
            "speech_metadata": {
              "style": "cheerful and friendly"
            }
          }]
        }],
        "generationConfig": {
          "responseModalities": ["AUDIO"],
          "speechConfig": {
            "voiceConfig": {
              "voice": "Kore"
            }
          }
        }
    }' | jq -r '.candidates[0].content.parts[0].inlineData.data' | \
          base64 --decode > out.wav

המרת טקסט לדיבור (TTS) עם כמה דוברים

כדי ליצור דו-שיח בין כמה רמקולים, מגדירים שני רמקולים ב-multiSpeakerVoiceConfig.speakerVoiceConfigs באמצעות prebuiltVoiceConfig ומעבירים כל תור לדיבור כ-part נפרד עם speech_metadata שמציין גם את speaker וגם את style האופציונלי ברמת התור:

Python

from google import genai

client = genai.Client()

response = client.models.generate_content(
    model="gemini-3.8-flash-tts",
    contents=[{
        "role": "user",
        "parts": [
            {
                "text": "How's it going today Jane?",
                "speech_metadata": {
                    "speaker": "Joe",
                    "style": "cheerful and friendly",
                },
            },
            {
                "text": "Not too bad, how about you? Ready to test these new voices?",
                "speech_metadata": {
                    "speaker": "Jane",
                    "style": "calm and relaxed",
                },
            },
        ],
    }],
    config={
        "response_modalities": ["AUDIO"],
        "speech_config": {
            "multi_speaker_voice_config": {
                "speaker_voice_configs": [
                    {
                        "speaker": "Joe",
                        "voice_config": {
                            "prebuilt_voice_config": {"voice_name": "Puck"}
                        },
                    },
                    {
                        "speaker": "Jane",
                        "voice_config": {
                            "prebuilt_voice_config": {"voice_name": "Kore"}
                        },
                    },
                ]
            }
        },
    },
)

data = response.candidates[0].content.parts[0].inline_data.data
with open("out.wav", "wb") as f:
    f.write(data)

JavaScript

import {GoogleGenAI} from '@google/genai';
import * as fs from 'node:fs';

async function main() {
   const ai = new GoogleGenAI({});

   const response = await ai.models.generateContent({
      model: 'gemini-3.8-flash-tts',
      contents: [{
         role: 'user',
         parts: [
            {
               text: "How's it going today Jane?",
               speechMetadata: {
                  speaker: 'Joe',
                  style: 'cheerful and friendly',
               },
            },
            {
               text: 'Not too bad, how about you? Ready to test these new voices?',
               speechMetadata: {
                  speaker: 'Jane',
                  style: 'calm and relaxed',
               },
            },
         ],
      }],
      config: {
         responseModalities: ['AUDIO'],
         speechConfig: {
            multiSpeakerVoiceConfig: {
               speakerVoiceConfigs: [
                  {
                     speaker: 'Joe',
                     voiceConfig: {
                        prebuiltVoiceConfig: { voiceName: 'Puck' },
                     },
                  },
                  {
                     speaker: 'Jane',
                     voiceConfig: {
                        prebuiltVoiceConfig: { voiceName: 'Kore' },
                     },
                  },
               ],
            },
         },
      },
   });

   const data = response.candidates?.[0]?.content?.parts?.[0]?.inlineData?.data;
   const audioBuffer = Buffer.from(data, 'base64');

   fs.writeFileSync('out.wav', audioBuffer);
}

await main();

REST

curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.8-flash-tts:generateContent" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [{
      "role": "user",
      "parts": [
        {
          "text": "How'\''s it going today Jane?",
          "speech_metadata": {
            "speaker": "Joe",
            "style": "cheerful and friendly"
          }
        },
        {
          "text": "Not too bad, how about you? Ready to test these new voices?",
          "speech_metadata": {
            "speaker": "Jane",
            "style": "calm and relaxed"
          }
        }
      ]
    }],
    "generationConfig": {
      "responseModalities": ["AUDIO"],
      "speechConfig": {
        "multiSpeakerVoiceConfig": {
          "speakerVoiceConfigs": [
            {
              "speaker": "Joe",
              "voiceConfig": {
                "prebuiltVoiceConfig": { "voiceName": "Puck" }
              }
            },
            {
              "speaker": "Jane",
              "voiceConfig": {
                "prebuiltVoiceConfig": { "voiceName": "Kore" }
              }
            }
          ]
        }
      }
    }
  }' | jq -r '.candidates[0].content.parts[0].inlineData.data' | \
      base64 --decode > out.wav

שליטה בסגנון הדיבור באמצעות מטא-נתונים ותגים

‫Gemini 3.8 TTS מתייחס לשדה text כאל תמליל מילה במילה. כדי לשלוט בהעברה בלי שההוראות לבימוי יוקראו בקול רם, צריך לפצל את ההוראות לפי היקף:

  • הגייה רציפה ברמת הפנייה (speech_metadata.style): כדי להוסיף רגשות, סגנון הגייה, פרוזודיה, קצב ועוצמת קול שרלוונטיים לכל הפנייה, משתמשים בתג speech_metadata.style (לדוגמה, "style": "whispered urgently",‏ "style": "out of breath" או "style": "warm and enthusiastic").
  • אירועים בנקודת זמן מסוימת (תגים מוטבעים): מציבים פרצי קול רגעיים שאינם דיבור או הפסקות ישירות בתוך התמליל באמצעות סוגריים זוויתיים (לדוגמה, "Wait... <short pause> did you hear that? <sigh>" או "Excuse me <cough> as I was saying...").

במדריך לכתיבת הנחיות מפורטות שיטות מומלצות מקיפות.

אפשרויות קוליות

‫Gemini 3.8 TTS תומך בארבע דרכים לבחור או ליצור קולות:

  1. קולות מוכנים מראש: 30 קולות שנבחרו בקפידה ומפורטים בטבלה הבאה.
  2. ספריית קולות מורחבת: מאות קולות נוספים בשפות, במבטאים ובארכיטיפים של דמויות שניתן לגשת אליהם באמצעות client.voices.list() (GET /v1beta/voices).
  3. ‫Voice design: יצירת דמות קולית בהתאמה אישית מתיאור בשפה טבעית ב-Google AI Studio או באמצעות POST /v1beta/voices (type="prompted", שמחזירה מזהה voice_... קבוע ותצוגה מקדימה של sample_audio WAV ב-CreateVoice וב-GetVoice).
  4. רפליקציה של קולות: שכפול של קול הדובר מאודיו של הפניה והסכמה ב-Google AI Studio או באמצעות POST /v1beta/voices (type="replicated", store=True מתמשך כברירת מחדל או store=False אופציונלי בלי שמירת מצב).

מגבלות וערכי TTL של קולות מותאמים אישית

הכתבה מצב אחסון מכסה / מגבלה שמירה (TTL)
קולות עם מצב (voice_..., בהנחיה או בשכפול) store=True 200 קולות לכל פרויקט (משותפים בין קולות שנוצרו מהנחיות וקולות ששוכפלו) שנה ממועד השימוש האחרון*
מפתחות קוליים ללא מצב (voicekey_..., משוכפלים) store=False בניהול של לקוח 7 ימים

* הארכת משך הזמן לשימוש: חלון השמירה של שנה מתאפס בכל פעם שהקול נמצא בשימוש פעיל (על ידי סינתזת דיבור עם הקול או שימוש בו כקול בסיס ליצירת רמיקס). קולות שלא הייתה בהם פעילות במשך שנה נמחקים באופן אוטומטי.

קולות שנוצרו מראש

‫Zephyr -- Bright ‫Puck – Upbeat ‫Charon -- אינפורמטיבי
‫Kore – Firm ‫Fenrir – נרגש ‫Leda – צעיר/ה
‫Orus -- Firm ‫Aoede – Breezy ‫Callirrhoe – נינוח
Autonoe -- Bright ‫Enceladus – Breathy ‫Iapetus -- Clear
Umbriel – נינוח ‫Algieba – Smooth Despina -- Smooth
Erinome -- Clear ‫Algenib -- מחוספס ‫Rasalgethi -- Informative
‫Laomedeia -- שמח ‫Achernar -- Soft ‫Alnilam -- Firm
‫Schedar – Even ‫Gacrux -- Mature ‫Pulcherrima -- Forward
Achird -- Friendly ‫Zubenelgenubi – רגוע ‫Vindemiatrix – עדין
Sadachbia -- Lively Sadaltager -- Knowledgeable ‫Sulafat -- Warm

ספריית קולות מורחבת וסינון

בנוסף ל-30 הקולות המוצגים בטבלה שלמעלה, ספריית הקולות המורחבת כוללת מאות קולות נוספים בשפות שונות, עם מבטאים אזוריים, דמויות וסגנונות שונים. אתם יכולים לעיין בספריית הקולות המלאה, לסנן אותה ולשמוע דוגמאות שלה באופן אינטראקטיבי ב-Google AI Studio, או לשלוח אליה שאילתות באופן פרוגרמטי באמצעות client.voices.list() (GET /v1beta/voices, באמצעות google-genai גרסה 2.25.0 ואילך / @google/genai גרסה 2.24.0 ואילך).

‫ListVoices מחזירה את הקולות המותאמים אישית ששמרתם (בסדר מהחדש לישן), ואחריהם את הקולות המוכנים מראש שמתאימים לקריטריונים של המסנן. כשמעבירים כמה ערכים למסנן רשימה, המערכת מחזירה את הקולות שתואמים לכל ערך במסנן הזה (OR), ואילו פרמטרים נפרדים של מסנן משולבים עם AND:

פרמטר סוג תיאור
language_code list[str] תגי שפה בתקן BCP-47 (לדוגמה, ["en-US", "en-GB"]). התאמה מדויקת לא תלוית-רישיות.
region_code list[str] קודים אזוריים לפי תקן ISO 3166-1 alpha-2 או UN M.49 (לדוגמה, ["US", "GB"]).
accent list[str] תיאור(ים) של מבטא אזורי (לדוגמה, ["American", "British"]).
gender list[str] הצגת המגדר הנתפס ("female", "male" או "neutral").
pitch list[str] סיווג גובה הקול ("low",‏ "medium" או "high").
persona list[str] פרסונה קולית או ארכיטיפ של דמות (לדוגמה, ["Warm, Friendly"], ["Narrator"]).
‫contexts (context ב-REST) list[str] דומיין לשימוש אופטימלי (לדוגמה, ["Audiobook", "Conversational", "News"]).
‫type (type_ ב-Python) list[str] סינון לפי מקור הקול: "prebuilt",‏ "prompted" (עיצוב קול) או "replicated" (רפליקציה של קולות).
search str חיפוש מחרוזת משנה בטקסט חופשי התאים ל-display_name ול-description ללא הבחנה בין אותיות רישיות לאותיות קטנות.
page_size int המספר המקסימלי של קולות שמוחזרים לכל דף (ברירת מחדל 50, מקסימום 1000).
page_token str טוקן מ-response.next_page_token לאחזור של דף התוצאות הבא.

Python

from google import genai

client = genai.Client()

# Filter the Voice Library by language, gender, pitch, domain context, and keyword
response = client.voices.list(
    language_code=["en-US", "en-GB"],
    gender=["female"],
    pitch=["medium", "low"],
    contexts=["Audiobook", "Conversational"],
    type_=["prebuilt"],
    search="warm",
    page_size=50,
)

for voice in response.voices or []:
    print(
        f"{voice.id} | {voice.display_name} ({voice.language_code},"
        f" {voice.accent}, {voice.gender}, pitch={voice.pitch}):"
        f" {voice.description}"
    )

JavaScript

import { GoogleGenAI } from "@google/genai";

const ai = new GoogleGenAI();

// Filter the Voice Library by language, gender, pitch, domain context, and keyword
const response = await ai.voices.list({
  language_code: ["en-US", "en-GB"],
  gender: ["female"],
  pitch: ["medium", "low"],
  contexts: ["Audiobook", "Conversational"],
  type: ["prebuilt"],
  search: "warm",
  page_size: 50,
});

for (const voice of response.voices ?? []) {
  console.log(
    `${voice.id} | ${voice.display_name} (${voice.language_code}, ${voice.accent}, ${voice.gender}, pitch=${voice.pitch}): ${voice.description}`
  );
}

REST

curl -G "https://generativelanguage.googleapis.com/v1beta/voices" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  --data-urlencode "language_code=en-US" \
  --data-urlencode "language_code=en-GB" \
  --data-urlencode "gender=female" \
  --data-urlencode "pitch=medium" \
  --data-urlencode "context=Audiobook" \
  --data-urlencode "type=prebuilt" \
  --data-urlencode "search=warm" \
  --data-urlencode "page_size=50"

שפות נתמכות

מודלי ה-TTS מזהים את שפת הקלט באופן אוטומטי. ‫Gemini 3.8 Flash TTS (gemini-3.8-flash-tts) תומך ביותר מ-130 שפות, ו-Gemini 3.8 Flash-Lite TTS (gemini-3.8-flash-lite-tts) תומך ביותר מ-100 שפות:

שפה Gemini 3.8 Flash TTS Gemini 3.8 Flash-Lite TTS
אצ'ה (כתב ערבי) ✔️ ✔️
אפריקאנס ✔️ ✔️
אקאן ✔️ ✔️
אמהרית ✔️ ✔️
ארמנית ✔️ ✔️
אסאמית ✔️ ✔️
עוואדי ✔️ ✔️
באלינזית ✔️ ✔️
בנגלית ✔️ ✔️
בנג'אר (כתב ערבי) ✔️ —
בנג'אר (כתב לטיני) ✔️ ✔️
בשקירית ✔️ —
בסקית ✔️ ✔️
בלארוסית ✔️ ✔️
במבה ✔️ —
בוג'פורי ✔️ ✔️
בוסנית ✔️ ✔️
בוגינזית ✔️ ✔️
בולגרית ✔️ ✔️
בורמזית ✔️ —
קנטונזית ✔️ ✔️
קטלאנית ✔️ ✔️
סבואנו ✔️ ✔️
כורדית מרכזית ✔️ ✔️
צ'אטיסגארי ✔️ ✔️
סינית (כתב האן) ✔️ ✔️
סינית (כתב האנט) ✔️ ✔️
טטארית של חצי האי קרים ✔️ —
קרואטית ✔️ ✔️
צ'כית ✔️ ✔️
דנית ✔️ ✔️
הולנדית ✔️ ✔️
דיולה ✔️ —
דזונקה ✔️ —
ערבית מצרית ✔️ ✔️
אנגלית ✔️ ✔️
אסטונית ✔️ ✔️
פיליפינית ✔️ ✔️
פינית ✔️ —
צרפתית ✔️ ✔️
גליציאנית ✔️ ✔️
גאנדה ✔️ ✔️
גאורגית ✔️ ✔️
גרמנית ✔️ ✔️
יוונית ✔️ ✔️
גוארני ✔️ —
גוג'ראטי ✔️ ✔️
קריאולית האיטית ✔️ ✔️
מונגולית חלחה ✔️ ✔️
האוסה ✔️ ✔️
עברית ✔️ ✔️
הינדי ✔️ ✔️
הונגרית ✔️ ✔️
איסלנדית ✔️ ✔️
איגבו ✔️ —
אילוקו ✔️ ✔️
אינדונזית ✔️ ✔️
פרסית איראנית ✔️ ✔️
איטלקית ✔️ ✔️
יפנית ✔️ ✔️
ג'אווה ✔️ ✔️
קביל ✔️ —
קאמבה ✔️ ✔️
קנאדה ✔️ ✔️
קשמירית (כתב ערבי) ✔️ ✔️
קשמירית (כתב דוונאגרי) ✔️ ✔️
קזחית ✔️ ✔️
חמרית ✔️ ✔️
קיקויו ✔️ ✔️
קינירואנדה ✔️ ✔️
קונגו ✔️ ✔️
קוריאנית ✔️ ✔️
קירגיזית ✔️ ✔️
לאו ✔️ ✔️
לטגאלית ✔️ —
לינגלה ✔️ ✔️
ליטאית ✔️ —
לוקסמבורגית ✔️ —
מקדונית ✔️ ✔️
מגאהי ✔️ ✔️
מאיטילית ✔️ ✔️
מליאלאם ✔️ ✔️
מלטית ✔️ ✔️
מניפורית ✔️ ✔️
מראטהית ✔️ ✔️
מיננגקבאו (כתב ערבי) ✔️ ✔️
מיננגקבאו (כתב לטיני) ✔️ —
מיזו ✔️ ✔️
נפאלית (שפה נפרדת) ✔️ ✔️
פולפולדה ניגרית ✔️ ✔️
צפון אזרית ✔️ ✔️
סוטו צפונית ✔️ ✔️
אוזבקית צפונית ✔️ ✔️
‏נורבגית ספרותית ✔️ ✔️
נורווגית (Nynorsk) ✔️ ✔️
ניאנג'ה ✔️ ✔️
אוקסיטנית ✔️ —
אורייה (שפה נפרדת) ✔️ ✔️
פנגסינאן ✔️ —
פרסית (אפגניסטן) ✔️ ✔️
פולנית ✔️ ✔️
פורטוגזית ✔️ ✔️
פנג'אבי ✔️ ✔️
רומנית ✔️ ✔️
רוסית ✔️ ✔️
סנטלי ✔️ ✔️
סרבית ✔️ ✔️
סינדהית ✔️ —
סינהאלה ✔️ ✔️
סלובקית ✔️ ✔️
סלובנית ✔️ —
סומלית ✔️ —
אזרית דרומית ✔️ ✔️
פאשטו דרומית ✔️ ✔️
ססוטו ✔️ —
ספרדית ✔️ ✔️
ערבית רגילה (כתב ערבי) ✔️ ✔️
ערבית רגילה (תסריט Latn) ✔️ ✔️
לטבית רגילה ✔️ ✔️
מלאית תקנית ✔️ ✔️
סוואהילי (שפה נפרדת) ✔️ —
סוואטי ✔️ —
שוודית ✔️ —
טג'יקית ✔️ —
טמילית ✔️ ✔️
טלוגו ✔️ ✔️
תאית ✔️ —
תיגרינית ✔️ —
אלבנית טוסק ✔️ —
טורקית ✔️ ✔️
אויגור ✔️ —
וייטנאמית ✔️ ✔️

מודלים נתמכים

מודל דובר יחיד מערכת רמקולים עיצוב קולי רפליקציה של קולות
‫Gemini 3.8 Flash TTS (gemini-3.8-flash-tts) ✔️ ✔️ ✔️ ✔️
‫Gemini 3.8 Flash-Lite TTS ‏ (gemini-3.8-flash-lite-tts) ✔️ ✔️ ✔️ ✔️
תצוגה מקדימה של Gemini 3.1 Flash TTS ✔️ ✔️ — —
Gemini 2.5 Pro Preview TTS ✔️ ✔️ — —

מתי כדאי להשתמש בכל מודל

שני מודלי ה-TTS של Gemini 3.8 חולקים את אותה סכימת API ואת אותו פורמט הנחיות, כך שאפשר לעבור ביניהם באמצעות שינוי של פרמטר אחד:

  • משתמשים ב-Gemini 3.8 Flash TTS (gemini-3.8-flash-tts) כשחשובים לכם במיוחד איכות אקוסטית מקסימלית, משחק ניואנסי ושליטה בהבעה. הוא אידיאלי לעבודות יצירתיות ברמה של אולפן, לדיאלוגים מורכבים עם כמה דוברים, לתגי קול חזקים, להגייה מסובכת, לניבים אזוריים או של מיעוטים ולקריינות ארוכות שדורשות יציבות מושלמת של הקול ושל טון החדר.
  • שימוש ב-Gemini 3.8 Flash-Lite TTS (gemini-3.8-flash-lite-tts) כפתרון מהיר וחסכוני במקום gemini-3.1-flash-tts-preview. הוא מותאם להפקה בכמות גדולה, לשיחות עם נציגים קוליים, לתכונות של קריאה בקול רם, לרפליקציה של קולות מהימנה ולדיבור יומיומי בשפה אחת בשפות מרכזיות.

מדריך להעברת נתונים (מיגרציה)

אם משדרגים ממודלים קודמים של גרסת טרום-השקה (gemini-3.1-flash-tts-preview או gemini-2.5-pro-preview-tts) ל-Gemini 3.8 TTS (gemini-3.8-flash-tts או gemini-3.8-flash-lite-tts), כדאי לעיין בחמישה השינויים העיקריים הבאים:

  1. הפרדת הסגנון מהתמליל: מעבירים את ההוראות לגבי משחק רציף, טון, פרוזודיה וקצב (כמו "whispering", "out of breath" או "speaking slowly") מטקסט פשוט אל speech_metadata.style. התמליל צריך להיות בדיוק כמו text, בתוספת תגיות קוליות מוטבעות.
  2. עיצוב פרסונות מראש באמצעות עיצוב קול: מחליפים בלוקים של "Audio Profile" או "Director's Notes" עם כמה פסקאות בקול מותאם אישית שנוצר בעיצוב קול, ואז מעבירים את מזהה voice_... דרך בקשות ה-TTS עם מחרוזות style מינימליות או ריקות.
  3. שימוש בתורות דיבור מובנות: בדיאלוג עם כמה דוברים, מעבירים part אחד לכל תור דיבור עם speech_metadata.speaker במקום להטמיע קידומות Speaker: ... בתוך בלוק טקסט אחד.
  4. שימוש בסוגריים זוויתיים לתגי דיבור מוטבעים: משתמשים בסוגריים זוויתיים (<laugh>,‏ <sigh>, ‏ <cough>, ‏ <breath>, ‏ <short pause>) לציון נקודות בזמן שבהן יש קולות אנושיים והפסקות. אל תשתמשו בתגי אפקטים קוליים שאינם קוליים (כמו מחיאות כפיים או חבטות).
  5. התחשבות בפלט WAV (AUDIO_WAV) שמוגדר כברירת מחדל בבקשות unary: בניגוד ל-gemini-3.1-flash-tts-preview (שמחזיר PCM גולמי ללא כותרת AUDIO_L16 כברירת מחדל), מודלים של Gemini 3.8 TTS מחזירים אודיו מלא בפורמט WAV (AUDIO_WAV) עם כותרת RIFF (24 kHz, מונו, 16-bit PCM) בבקשות unary:
    • אם הקוד שלכם עטף בעבר בייטים של PCM גולמיים בכותרת WAV (לדוגמה, באמצעות מודול wave של Python או חבילת wav של Node), צריך להסיר את העטיפה הידנית של הכותרת ולכתוב את הבייטים של האודיו המפוענח ישירות לקובץ .wav.
    • אם צינור עיבוד הנתונים הקיים שלכם דורש אודיו PCM גולמי ללא כותרת, mu-law או A-law, צריך להגדיר במפורש את response_format.audio.mime_type ל-"AUDIO_L16", ל-"AUDIO_MULAW" או ל-"AUDIO_ALAW" (לדוגמה, {"response_format": {"audio": {"mime_type": "AUDIO_L16"}}} ב-generateContent או {"response_format": {"type": "audio", "mime_type": "audio/l16"}} ב-Interactions API). פורמטים של פלט אודיו

מדריך לכתיבת פרומפטים

מודלים של Gemini 3.8 TTS מתייחסים לטקסט הקלט אך ורק כתמליל מילולי. בניגוד למודלים קודמים של תצוגה מקדימה שבהם הוראות הבמה היו מוטמעות בטקסט פשוט, ב-Gemini 3.8 TTS ההוראות ברמת התור (speech_metadata) מופרדות מתגי קול מוטבעים בנקודת זמן מסוימת.

שדה סגנון לעומת תגים מוטבעים

כדאי לפצל את הוראות הביצוע לפי היקף:

  • העברה ברמת הפנייה (speech_metadata.style): מכניסים מאפייני העברה מתמשכת – כמו רגש, פרוזודיה, קצב כללי או סגנון העברה (למשל "whispering", "out of breath", "muttering" או "sarcastic") – לשדה style של speech_metadata. כדי ליצור דמות יציבה וביצועים עקביים לאורך השיחה, כדאי לעצב את האישיות מראש בעיצוב הקול ולהשתמש בstyle רק לשינויים אופציונליים ברמת התור.
  • אירועים בנקודת זמן מסוימת (תגים מוטבעים): כדי להוסיף לטקסט תמלול פרצי קול רגעיים שאינם דיבור, נשימות או הפסקות, משתמשים בסוגריים זוויתיים (<cough>, <breath>, <sigh>, <short pause>). כדי לקבל את איכות האודיו הכי גבוהה, משתמשים בסוגריים זוויתיים (<...>) ומוסיפים רק קולות אנושיים ולא אפקטים קוליים שאינם קולות.
היקף איפה למקם דוגמאות
ברמת הפנייה (נמשך לאורך הפנייה) speech_metadata.style "angry tone",‏ "speaking rapidly",‏ "out of breath",‏ "whispers",‏ "sarcastic"
נקודת זמן (מתרחש במילה ספציפית) בתוך הטקסט ב-text (<...>) "<cough> Thank you all for coming tonight! <throat-clearing> As I was saying..."

קצב ופסק זמן

אתם יכולים לשלוט בקצב ובשקט בשלוש רמות של פירוט:

  • סימני פיסוק ושלוש נקודות: השתמשו בפסיקים, במקפים (--) ובשלוש נקודות (...) כדי ליצור היסוס טבעי בשיחה.
  • תגי השהיה בתוך השורה: מוסיפים את התגים <short pause> או <long pause> בנקודות המדויקות בתסריט שבהן הדובר צריך להשהות את הדיבור: text Hold on, let me think... <short pause> Alright, I've got it.
  • קצב ברמת התור: מגדירים את הערך "style": "speaking rapidly" או "style": "speaking slowly" ב-speech_metadata כדי לשלוט בקצב הדיבור לאורך כל התור.

פרוזודיה וגובה הצליל

משתמשים בתג speech_metadata.style כדי לשלוט בהטעמה, בגובה הטון ובאינטונציה לאורך תור (לדוגמה, "style": "high pitch, cheerful and excited inflection" או "style": "monotone and flat"). אם יש שינוי ברגש או בהטעמה באמצע הדיאלוג, צריך לפצל את התסריט לתורות נפרדות עם ערכי style שונים לכל תור.

הדגשה

כדי להדגיש מילות מפתח ספציפיות בטקסט התמליל, אפשר להשתמש באותיות רישיות בשילוב עם סימני פיסוק ותגי דיבור מוטבעים:

This is a VERY important point!
It was a VERY long day <sigh> ... nobody listens anymore.

פרצי קול וצלילים שאינם דיבור

מציבים קולות אנושיים שהם לא דיבור בתוך סוגריים זוויתיים (<...>) בנקודה המדויקת שבה צריך להשמיע את הצליל. תגי קול מומלצים:

<argh> <breath> <heavy breath> <exhales>
<cackle> <cheer> <chuckle> / <chuckles> <cough>
<cry> <gasp> <giggle> <groan>
<growl> <grunt> <grr> <hiss>
<laugh> / <laughter> <moan> <pant> <pff> / <phew>
<scream> <shout> <shriek> <sigh> / <sighs>
<sneeze> <snicker> <snort> <sob>
<throat-clearing> <tsk> <whimper> <whispers> / <whispering>
<yawn> <short pause> <long pause>

ערוצים אחוריים ודיבור חופף

בדיאלוג עם כמה דוברים, כדי ליצור ערוצים משניים טבעיים או דיבור חופף בלי ליצור תור נפרד לכל תגובה, אפשר להוסיף את התגובות של המאזין בין תווי צינור (|reaction|) בתוך תור הדיבור של הדובר.

  • החלפת מסרים קצרה בערוץ האחורי: תגובות קצרות של המאזינים (|oh hmm|, |oh really?|, |absolutely|) במהלך התור של הדובר הפעיל:
    • תור 1 (דובר א'): "So the launch is Thursday |oh hmm| Are we actually ready?"
    • תור 2 (דובר ב'): "Ready enough |oh really?| The last blocker cleared this morning."
    • תור 3 (דובר א'): "Then let's ship it |absolutely| and watch the dashboards."
  • חפיפה ודיבור לסירוגין: כדי לדמות דיבור בו-זמני או לסירוגין בין שני דוברים, משתמשים בכמה מקטעים עם קו אנכי (האפשרות הזו מתאימה במיוחד ל-gemini-3.8-flash-tts):
    • ספירה לאחור/פזמון בו-זמנית: "Let's surprise him on three |ok| ready?" ואז "one. two. three. |happy| happy |birthday| birthday!"
    • חפיפה מלאה בין הדוברים: "Hello |oh| there |my| it |goodness| must |gracious| be |would| almost |you| time |look| for |at that| dinner"

עקביות בין יצירות ומה כדאי להימנע ממנו

כדי לשמור על יציבות הזהות הקולית לאורך השיחה, חשוב להקפיד על ההנחיות הבאות:

  • כדאי לעצב את פרסונות הקול מראש בעיצוב הקול במקום להשתמש בבלוקים ארוכים של סגנון: פסקה ארוכה "Audio Profile" ורשימה עם כמה תבליטים "Director's Notes" שהועברו ממודלים קודמים הם הגורם הכי נפוץ לשינוי בקול. כדי ליצור דמות voice_... מותאמת אישית וקבועה, אפשר להשתמש באותה אינטואיציה יצירתית מראש בעיצוב הקול, ואז להשתמש במזהה הקול הזה בשיחות ה-TTS.
  • הסתמכות על נקודת הייחוס הקולית ליציבות (השמטת מטא-הוראות): מודלים של Gemini 3.8 TTS מאומנים להסתמך קודם על נקודת הייחוס הקולית. אל תכללו הוראות שאומרות למודל לשמור על יציבות הקול (כמו "do not switch speaker identity" או "maintain identical timbre") – טקסט נוסף בהנחיה מגדיל את הסחף. כדאי להשמיט הוראות סגנון מיותרות ולאפשר למודל להשתנות באופן טבעי סביב הנקודה היציבה שמופיעה ברפרנס הקולי.
  • אל תנסו לשנות מאפיינים קבועים של הדובר ב-style: אל תציינו ב-speech_metadata.style שינויים בגיל, במגדר, בשמות או במבטא קבוע. במקום זאת, אפשר לבחור קול אזורי מתוך ספריית הקולות המורחבת או ליצור קול באמצעות עיצוב קול.
  1. יוצרים את הדמות פעם אחת: יוצרים את הדמות בעיצוב קול או בוחרים קול אזורי מתוך ספריית הקולות המורחבת שתואם לשפת היעד ולדמות.
  2. כתיבת תמלילים של דיבור טבעי עם שיבושי דיבור: כדי שהתמליל יישמע טבעי ככל האפשר, כדאי לכתוב את text כמו תמליל של דיבור אמיתי – כולל שיבושי דיבור והיסוסים שקורים בשיחה (לדוגמה, "Oh uh yeah I think... hm, so that's interesting").
  3. קודם בודקים TTS רגיל: מסנתזים את התמליל עם שדה style ריק – ברוב הבקשות לא צריך לתת הוראות style בכלל.
  4. הוספת הנחיות קצרות style רק לשינויים קלים: מוסיפים מחרוזת style קצרה (למשל "casual, friendly" או "muttering, then reassuring") רק לתפניות שבהן צריך לבצע התאמה ספציפית של התוצאה, ומשתמשים באותה מחרוזת קצרה בדיוק בתפניות שונות כשרוצים לקבל תוצאה עקבית.

סוכנים קוליים ודיאלוגים רב-שלביים

כשמפתחים סוכני קול לשיחות בזמן אמת או אפליקציות רב-שלביות:

  • להתקשר שיחת TTS אחת בכל תור כשהנתונים מגיעים בחלקים ממודל שפה גדול (LLM).
  • מאפשרים ל-voice שהוגדר (מוכן מראש, מתוכנן voice_... או משוכפל voice_... / voicekey_...) לשמור את זהות הדובר לאורך כל התורות – לא לשלוח מחדש תיאור ארוך של דמות בכל תור.
  • משאירים את השדה style לכל תור ריק, או שולחים מחרוזת קצרה וקבועה (למשל "casual, friendly") לכל השיחה.
  • לפצל תשובות ארוכות של נציגים לתשובות קצרות יותר, במקום להשתמש בהנחיות סגנון חזקות יותר.

יצירת דיבור בסטרימינג

אפשר להזרים אודיו שנוצר בזמן שהוא מסונתז על ידי המודל. בשונה מבקשות unary (שמחזירות קובץ WAV מלא עם כותרת RIFF), בקשות סטרימינג מחזירות נתחי PCM ליניאריים גולמיים של 16 ביט בפורמט little-endian (AUDIO_L16 / audio/L16;codec=pcm;rate=24000,‏ 24‎ kHz, מונו) ללא כותרת כברירת מחדל, כך שאפשר להפעיל או לחבר ברצף נתחי אודיו ללא כותרות של קונטיינר:

Python

from google import genai

client = genai.Client()

response_stream = client.models.generate_content_stream(
    model="gemini-3.8-flash-tts",
    contents=[{
        "role": "user",
        "parts": [{
            "text": "Have a wonderful day!",
            "speech_metadata": {"style": "cheerful and friendly"},
        }],
    }],
    config={
        "response_modalities": ["AUDIO"],
        "speech_config": {
            "voice_config": {"voice": "Kore"}
        },
    },
)

for chunk in response_stream:
    try:
        data = chunk.candidates[0].content.parts[0].inline_data.data
        # data contains raw PCM bytes (24kHz, 1-channel, 16-bit)
    except (IndexError, AttributeError):
        pass

JavaScript

import {GoogleGenAI} from '@google/genai';

async function main() {
   const ai = new GoogleGenAI({});

   const responseStream = await ai.models.generateContentStream({
      model: 'gemini-3.8-flash-tts',
      contents: [{
         role: 'user',
         parts: [{
            text: 'Have a wonderful day!',
            speechMetadata: { style: 'cheerful and friendly' },
         }],
      }],
      config: {
         responseModalities: ['AUDIO'],
         speechConfig: {
            voiceConfig: { voice: 'Kore' },
         },
      },
   });

   for await (const chunk of responseStream) {
      const data = chunk.candidates?.[0]?.content?.parts?.[0]?.inlineData?.data;
      if (data) {
         const audioBuffer = Buffer.from(data, 'base64');
         // Process the audio buffer
      }
   }
}
await main();

REST

curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.8-flash-tts:streamGenerateContent" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{
        "contents": [{
          "role": "user",
          "parts": [{
            "text": "Have a wonderful day!",
            "speech_metadata": {
              "style": "cheerful and friendly"
            }
          }]
        }],
        "generationConfig": {
          "responseModalities": ["AUDIO"],
          "speechConfig": {
            "voiceConfig": {
              "voice": "Kore"
            }
          }
        }
    }'

פורמטים של פלט אודיו

מודלים של Gemini 3.8 TTS משתמשים בפורמטים שונים של אודיו כברירת מחדל, בהתאם לסוג הבקשה: unary או streaming:

  • בקשות אונריות (models.generate_content): מחזירות אודיו מלא בפורמט WAV (AUDIO_WAV) עם כותרת RIFF (24 kHz, מונו, 16-bit signed little-endian PCM). אפשר לכתוב את בייטים של האודיו המפוענח ישירות לקובץ .wav בלי להוסיף ידנית קובץ WAV.
  • בקשות סטרימינג (models.generate_content_stream / streamGenerateContent): כברירת מחדל, מחזירים נתחים של Linear PCM (AUDIO_L16) גולמי ללא כותרות (24‎ kHz, מונו, 16 ביט, PCM מסוג little-endian) כדי שאפשר יהיה להזרים את הנתחים או לשרשר אותם ברציפות ללא כותרות של קונטיינר בכל נתח.

אפשר לשנות את קידוד האודיו ואת קצב הדגימה של הפלט באמצעות generationConfig.responseFormat.audio:

ערך של mimeType פורמט תיאור
"AUDIO_WAV" (ברירת מחדל אונרית) ‫WAV (audio/wav) קובץ WAV מלא עם כותרת RIFF (24 kHz, מונו, 16-bit PCM).
"AUDIO_L16" (ברירת המחדל של סטרימינג) ‫Linear PCM‏ (audio/l16) ‫PCM לינארי גולמי של 16 ביט חתום בפורמט little-endian ללא כותרת. הבחירה המתאימה לסטרימינג, לצינורות אודיו מותאמים אישית או לשרשור של קליפים רב-שלביים.
"AUDIO_MULAW" ‫μ-law (audio/basic / audio/mulaw) אודיו דחוס בתקן G.711 μ-law. נפוץ בטלפוניה בצפון אמריקה וביפן (8 kHz).
"AUDIO_ALAW" A-law (audio/alaw) אודיו דחוס בפורמט G.711 A-law. בדרך כלל משתמשים בפורמט הזה בטלפוניה אירופית ובינלאומית (8kHz).

אפשר גם לציין sampleRate (לדוגמה, 24000,‏ 16000 או 8000 הרץ; ברירת המחדל היא 24000 הרץ).

בדוגמה הבאה מוצגת בקשה לכותרת של PCM גולמי ב-16 ביט (AUDIO_L16) בתדר של 24kHz:

Python

from google import genai

client = genai.Client()

response = client.models.generate_content(
    model="gemini-3.8-flash-tts",
    contents=[{
        "role": "user",
        "parts": [{
            "text": "Have a wonderful day!",
            "speech_metadata": {"style": "cheerful and friendly"},
        }],
    }],
    config={
        "response_modalities": ["AUDIO"],
        "response_format": {
            "audio": {
                "mime_type": "AUDIO_L16",
                "sample_rate": 24000,
            }
        },
        "speech_config": {
            "voice_config": {"voice": "Kore"}
        },
    },
)

data = response.candidates[0].content.parts[0].inline_data.data
with open("out.pcm", "wb") as f:
    f.write(data)

JavaScript

import {GoogleGenAI} from '@google/genai';
import * as fs from 'node:fs';

async function main() {
   const ai = new GoogleGenAI({});

   const response = await ai.models.generateContent({
      model: 'gemini-3.8-flash-tts',
      contents: [{
         role: 'user',
         parts: [{
            text: 'Have a wonderful day!',
            speechMetadata: { style: 'cheerful and friendly' },
         }],
      }],
      config: {
         responseModalities: ['AUDIO'],
         responseFormat: {
            audio: {
               mimeType: 'AUDIO_L16',
               sampleRate: 24000,
            },
         },
         speechConfig: {
            voiceConfig: { voice: 'Kore' },
         },
      },
   });

   const data = response.candidates?.[0]?.content?.parts?.[0]?.inlineData?.data;
   const audioBuffer = Buffer.from(data, 'base64');

   fs.writeFileSync('out.pcm', audioBuffer);
}
await main();

REST

curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.8-flash-tts:generateContent" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{
        "contents": [{
          "role": "user",
          "parts": [{
            "text": "Have a wonderful day!",
            "speech_metadata": {
              "style": "cheerful and friendly"
            }
          }]
        }],
        "generationConfig": {
          "responseModalities": ["AUDIO"],
          "responseFormat": {
            "audio": {
              "mimeType": "AUDIO_L16",
              "sampleRate": 24000
            }
          },
          "speechConfig": {
            "voiceConfig": {
              "voice": "Kore"
            }
          }
        }
    }' | jq -r '.candidates[0].content.parts[0].inlineData.data' | \
          base64 --decode > out.pcm

מגבלות

  • מודלים של TTS מקבלים קלט של טקסט בלבד ומפיקים פלט של אודיו בלבד.
  • יצירה של כמה דוברים בבקשה אחת (multiSpeakerVoiceConfig) תומכת בעד 2 דוברים באמצעות קולות מוכנים מראש. כדי לשלב קולות מותאמים אישית (voice_...) או קולות משוכפלים (voice_... / voicekey_...) בדיאלוג של כמה דמויות, צריך לבצע סינתזה של כל תור דיבור בנפרד. מכיוון שבקשות unary מחזירות audio/wav עם כותרת RIFF של 44 בייט כברירת מחדל, צריך לבקש PCM גולמי (AUDIO_L16) או להסיר את כותרת ה-WAV מכל תור לפני שמשלבים את מסגרות האודיו של PCM ב-24kHz.
  • מכסות אחסון וערכי TTL של קולות בהתאמה אישית:
    • קולות עם מצב (store=True, בהנחיה או בשכפול): עד 200 קולות לכל פרויקט עם אורך חיים של שנה.
    • מפתחות קוליים ללא שמירת מצב (store=False, voicekey_...): אורך חיים (TTL) של 7 ימים (time-to-live).
  • בקטע שפות נתמכות מפורטות השפות שנתמכות.

המאמרים הבאים