Live API capabilities guide

คู่มือนี้ครอบคลุมความสามารถและการกําหนดค่าที่ใช้ได้กับ Live API ดูภาพรวมและโค้ดตัวอย่างสำหรับ Use Case ที่พบบ่อยได้ในหน้าเริ่มต้นใช้งาน Live API

ก่อนเริ่มต้น

  • ทำความคุ้นเคยกับแนวคิดหลัก: อ่านหน้าเริ่มต้นใช้งาน Live API ก่อนหากยังไม่ได้อ่าน บทแนะนำนี้จะอธิบายหลักการพื้นฐานของ Live API, วิธีการทํางาน และความแตกต่างระหว่างรูปแบบต่างๆ กับวิธีการสร้างเสียงที่เกี่ยวข้อง (เสียงแบบเนทีฟหรือแบบแคสเคดครึ่ง)
  • ลองใช้ Live API ใน AI Studio: คุณอาจพบว่าการลองใช้ Live API ใน Google AI Studio มีประโยชน์ก่อนที่จะเริ่มสร้าง หากต้องการใช้ Live API ใน Google AI Studio ให้เลือกสตรีม

การสร้างการเชื่อมต่อ

ตัวอย่างต่อไปนี้แสดงวิธีสร้างการเชื่อมต่อด้วยคีย์ API

Python

import asyncio
from google import genai

client = genai.Client()

model = "gemini-live-2.5-flash-preview"
config = {"response_modalities": ["TEXT"]}

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:
        print("Session started")

if __name__ == "__main__":
    asyncio.run(main())

JavaScript

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

const ai = new GoogleGenAI({});
const model = 'gemini-live-2.5-flash-preview';
const config = { responseModalities: [Modality.TEXT] };

async function main() {

  const session = await ai.live.connect({
    model: model,
    callbacks: {
      onopen: function () {
        console.debug('Opened');
      },
      onmessage: function (message) {
        console.debug(message);
      },
      onerror: function (e) {
        console.debug('Error:', e.message);
      },
      onclose: function (e) {
        console.debug('Close:', e.reason);
      },
    },
    config: config,
  });

  // Send content...

  session.close();
}

main();

รูปแบบการโต้ตอบ

ส่วนต่อไปนี้แสดงตัวอย่างและบริบทสนับสนุนสำหรับรูปแบบอินพุตและเอาต์พุตต่างๆ ที่มีให้ใช้งานใน Live API

การส่งและการรับข้อความ

วิธีรับส่งข้อความมีดังนี้

Python

import asyncio
from google import genai

client = genai.Client()
model = "gemini-live-2.5-flash-preview"

config = {"response_modalities": ["TEXT"]}

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:
        message = "Hello, how are you?"
        await session.send_client_content(
            turns={"role": "user", "parts": [{"text": message}]}, turn_complete=True
        )

        async for response in session.receive():
            if response.text is not None:
                print(response.text, end="")

if __name__ == "__main__":
    asyncio.run(main())

JavaScript

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

const ai = new GoogleGenAI({});
const model = 'gemini-live-2.5-flash-preview';
const config = { responseModalities: [Modality.TEXT] };

async function live() {
  const responseQueue = [];

  async function waitMessage() {
    let done = false;
    let message = undefined;
    while (!done) {
      message = responseQueue.shift();
      if (message) {
        done = true;
      } else {
        await new Promise((resolve) => setTimeout(resolve, 100));
      }
    }
    return message;
  }

  async function handleTurn() {
    const turns = [];
    let done = false;
    while (!done) {
      const message = await waitMessage();
      turns.push(message);
      if (message.serverContent && message.serverContent.turnComplete) {
        done = true;
      }
    }
    return turns;
  }

  const session = await ai.live.connect({
    model: model,
    callbacks: {
      onopen: function () {
        console.debug('Opened');
      },
      onmessage: function (message) {
        responseQueue.push(message);
      },
      onerror: function (e) {
        console.debug('Error:', e.message);
      },
      onclose: function (e) {
        console.debug('Close:', e.reason);
      },
    },
    config: config,
  });

  const inputTurns = 'Hello how are you?';
  session.sendClientContent({ turns: inputTurns });

  const turns = await handleTurn();
  for (const turn of turns) {
    if (turn.text) {
      console.debug('Received text: %s\n', turn.text);
    }
    else if (turn.data) {
      console.debug('Received inline data: %s\n', turn.data);
    }
  }

  session.close();
}

async function main() {
  await live().catch((e) => console.error('got error', e));
}

main();

การอัปเดตเนื้อหาเพิ่มเติม

ใช้การอัปเดตแบบเพิ่มเพื่อส่งอินพุตข้อความ สร้างบริบทของเซสชัน หรือกู้คืนบริบทของเซสชัน สำหรับบริบทสั้นๆ คุณสามารถส่งการโต้ตอบแบบทีละขั้นเพื่อแสดงลำดับเหตุการณ์ที่แน่นอนได้ ดังนี้

Python

turns = [
    {"role": "user", "parts": [{"text": "What is the capital of France?"}]},
    {"role": "model", "parts": [{"text": "Paris"}]},
]

await session.send_client_content(turns=turns, turn_complete=False)

turns = [{"role": "user", "parts": [{"text": "What is the capital of Germany?"}]}]

await session.send_client_content(turns=turns, turn_complete=True)

JavaScript

let inputTurns = [
  { "role": "user", "parts": [{ "text": "What is the capital of France?" }] },
  { "role": "model", "parts": [{ "text": "Paris" }] },
]

session.sendClientContent({ turns: inputTurns, turnComplete: false })

inputTurns = [{ "role": "user", "parts": [{ "text": "What is the capital of Germany?" }] }]

session.sendClientContent({ turns: inputTurns, turnComplete: true })

สำหรับบริบทที่ยาวขึ้น เราขอแนะนำให้ระบุสรุปข้อความเดียวเพื่อเพิ่มพื้นที่ว่างในกรอบเวลาบริบทสำหรับการโต้ตอบครั้งต่อๆ ไป ดูวิธีอื่นในการโหลดบริบทเซสชันได้ที่การกลับมาทำงานของเซสชัน

การส่งและการรับเสียง

ตัวอย่างเสียงที่พบบ่อยที่สุดอย่างเสียงเป็นเสียงจะอยู่ในคู่มือการเริ่มต้นใช้งาน

ต่อไปนี้คือตัวอย่างการแปลงเสียงเป็นข้อความที่อ่านไฟล์ WAV ส่งไฟล์ในรูปแบบที่ถูกต้อง และรับเอาต์พุตข้อความ

Python

# Test file: https://storage.googleapis.com/generativeai-downloads/data/16000.wav
# Install helpers for converting files: pip install librosa soundfile
import asyncio
import io
from pathlib import Path
from google import genai
from google.genai import types
import soundfile as sf
import librosa

client = genai.Client()
model = "gemini-live-2.5-flash-preview"

config = {"response_modalities": ["TEXT"]}

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:

        buffer = io.BytesIO()
        y, sr = librosa.load("sample.wav", sr=16000)
        sf.write(buffer, y, sr, format='RAW', subtype='PCM_16')
        buffer.seek(0)
        audio_bytes = buffer.read()

        # If already in correct format, you can use this:
        # audio_bytes = Path("sample.pcm").read_bytes()

        await session.send_realtime_input(
            audio=types.Blob(data=audio_bytes, mime_type="audio/pcm;rate=16000")
        )

        async for response in session.receive():
            if response.text is not None:
                print(response.text)

if __name__ == "__main__":
    asyncio.run(main())

JavaScript

// Test file: https://storage.googleapis.com/generativeai-downloads/data/16000.wav
// Install helpers for converting files: npm install wavefile
import { GoogleGenAI, Modality } from '@google/genai';
import * as fs from "node:fs";
import pkg from 'wavefile';
const { WaveFile } = pkg;

const ai = new GoogleGenAI({});
const model = 'gemini-live-2.5-flash-preview';
const config = { responseModalities: [Modality.TEXT] };

async function live() {
  const responseQueue = [];

  async function waitMessage() {
    let done = false;
    let message = undefined;
    while (!done) {
      message = responseQueue.shift();
      if (message) {
        done = true;
      } else {
        await new Promise((resolve) => setTimeout(resolve, 100));
      }
    }
    return message;
  }

  async function handleTurn() {
    const turns = [];
    let done = false;
    while (!done) {
      const message = await waitMessage();
      turns.push(message);
      if (message.serverContent && message.serverContent.turnComplete) {
        done = true;
      }
    }
    return turns;
  }

  const session = await ai.live.connect({
    model: model,
    callbacks: {
      onopen: function () {
        console.debug('Opened');
      },
      onmessage: function (message) {
        responseQueue.push(message);
      },
      onerror: function (e) {
        console.debug('Error:', e.message);
      },
      onclose: function (e) {
        console.debug('Close:', e.reason);
      },
    },
    config: config,
  });

  // Send Audio Chunk
  const fileBuffer = fs.readFileSync("sample.wav");

  // Ensure audio conforms to API requirements (16-bit PCM, 16kHz, mono)
  const wav = new WaveFile();
  wav.fromBuffer(fileBuffer);
  wav.toSampleRate(16000);
  wav.toBitDepth("16");
  const base64Audio = wav.toBase64();

  // If already in correct format, you can use this:
  // const fileBuffer = fs.readFileSync("sample.pcm");
  // const base64Audio = Buffer.from(fileBuffer).toString('base64');

  session.sendRealtimeInput(
    {
      audio: {
        data: base64Audio,
        mimeType: "audio/pcm;rate=16000"
      }
    }

  );

  const turns = await handleTurn();
  for (const turn of turns) {
    if (turn.text) {
      console.debug('Received text: %s\n', turn.text);
    }
    else if (turn.data) {
      console.debug('Received inline data: %s\n', turn.data);
    }
  }

  session.close();
}

async function main() {
  await live().catch((e) => console.error('got error', e));
}

main();

และนี่คือตัวอย่างข้อความเป็นเสียง คุณสามารถรับเสียงได้โดยตั้งค่า AUDIO เป็นรูปแบบการตอบกลับ ตัวอย่างนี้จะบันทึกข้อมูลที่รับเป็นไฟล์ WAV

Python

import asyncio
import wave
from google import genai

client = genai.Client()
model = "gemini-live-2.5-flash-preview"

config = {"response_modalities": ["AUDIO"]}

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:
        wf = wave.open("audio.wav", "wb")
        wf.setnchannels(1)
        wf.setsampwidth(2)
        wf.setframerate(24000)

        message = "Hello how are you?"
        await session.send_client_content(
            turns={"role": "user", "parts": [{"text": message}]}, turn_complete=True
        )

        async for response in session.receive():
            if response.data is not None:
                wf.writeframes(response.data)

            # Un-comment this code to print audio data info
            # if response.server_content.model_turn is not None:
            #      print(response.server_content.model_turn.parts[0].inline_data.mime_type)

        wf.close()

if __name__ == "__main__":
    asyncio.run(main())

JavaScript

import { GoogleGenAI, Modality } from '@google/genai';
import * as fs from "node:fs";
import pkg from 'wavefile';
const { WaveFile } = pkg;

const ai = new GoogleGenAI({});
const model = 'gemini-live-2.5-flash-preview';
const config = { responseModalities: [Modality.AUDIO] };

async function live() {
  const responseQueue = [];

  async function waitMessage() {
    let done = false;
    let message = undefined;
    while (!done) {
      message = responseQueue.shift();
      if (message) {
        done = true;
      } else {
        await new Promise((resolve) => setTimeout(resolve, 100));
      }
    }
    return message;
  }

  async function handleTurn() {
    const turns = [];
    let done = false;
    while (!done) {
      const message = await waitMessage();
      turns.push(message);
      if (message.serverContent && message.serverContent.turnComplete) {
        done = true;
      }
    }
    return turns;
  }

  const session = await ai.live.connect({
    model: model,
    callbacks: {
      onopen: function () {
        console.debug('Opened');
      },
      onmessage: function (message) {
        responseQueue.push(message);
      },
      onerror: function (e) {
        console.debug('Error:', e.message);
      },
      onclose: function (e) {
        console.debug('Close:', e.reason);
      },
    },
    config: config,
  });

  const inputTurns = 'Hello how are you?';
  session.sendClientContent({ turns: inputTurns });

  const turns = await handleTurn();

  // Combine audio data strings and save as wave file
  const combinedAudio = turns.reduce((acc, turn) => {
    if (turn.data) {
      const buffer = Buffer.from(turn.data, 'base64');
      const intArray = new Int16Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / Int16Array.BYTES_PER_ELEMENT);
      return acc.concat(Array.from(intArray));
    }
    return acc;
  }, []);

  const audioBuffer = new Int16Array(combinedAudio);

  const wf = new WaveFile();
  wf.fromScratch(1, 24000, '16', audioBuffer);
  fs.writeFileSync('output.wav', wf.toBuffer());

  session.close();
}

async function main() {
  await live().catch((e) => console.error('got error', e));
}

main();

รูปแบบเสียง

ข้อมูลเสียงใน Live API จะเป็น PCM 16 บิตแบบ Little Endian แบบดิบเสมอ เอาต์พุตเสียงจะใช้อัตราการสุ่มตัวอย่าง 24kHz เสมอ เสียงอินพุตจะอยู่ที่ 16kHz โดยค่าเริ่มต้น แต่ Live API จะสุ่มตัวอย่างใหม่หากจำเป็นเพื่อให้ส่งอัตราตัวอย่างใดก็ได้ หากต้องการระบุอัตราตัวอย่างของเสียงอินพุต ให้ตั้งค่าประเภท MIME ของ Blob ที่มีเสียงแต่ละรายการเป็นค่าอย่างเช่น audio/pcm;rate=16000

การถอดเสียงเป็นคำ

คุณเปิดใช้การถอดเสียงเป็นคำของเอาต์พุตเสียงของโมเดลได้โดยส่ง output_audio_transcription ในการกำหนดค่าการตั้งค่า ระบบจะอนุมานภาษาในการถอดเสียงจากคำตอบของโมเดล

Python

import asyncio
from google import genai
from google.genai import types

client = genai.Client()
model = "gemini-live-2.5-flash-preview"

config = {"response_modalities": ["AUDIO"],
        "output_audio_transcription": {}
}

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:
        message = "Hello? Gemini are you there?"

        await session.send_client_content(
            turns={"role": "user", "parts": [{"text": message}]}, turn_complete=True
        )

        async for response in session.receive():
            if response.server_content.model_turn:
                print("Model turn:", response.server_content.model_turn)
            if response.server_content.output_transcription:
                print("Transcript:", response.server_content.output_transcription.text)

if __name__ == "__main__":
    asyncio.run(main())

JavaScript

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

const ai = new GoogleGenAI({});
const model = 'gemini-live-2.5-flash-preview';

const config = {
  responseModalities: [Modality.AUDIO],
  outputAudioTranscription: {}
};

async function live() {
  const responseQueue = [];

  async function waitMessage() {
    let done = false;
    let message = undefined;
    while (!done) {
      message = responseQueue.shift();
      if (message) {
        done = true;
      } else {
        await new Promise((resolve) => setTimeout(resolve, 100));
      }
    }
    return message;
  }

  async function handleTurn() {
    const turns = [];
    let done = false;
    while (!done) {
      const message = await waitMessage();
      turns.push(message);
      if (message.serverContent && message.serverContent.turnComplete) {
        done = true;
      }
    }
    return turns;
  }

  const session = await ai.live.connect({
    model: model,
    callbacks: {
      onopen: function () {
        console.debug('Opened');
      },
      onmessage: function (message) {
        responseQueue.push(message);
      },
      onerror: function (e) {
        console.debug('Error:', e.message);
      },
      onclose: function (e) {
        console.debug('Close:', e.reason);
      },
    },
    config: config,
  });

  const inputTurns = 'Hello how are you?';
  session.sendClientContent({ turns: inputTurns });

  const turns = await handleTurn();

  for (const turn of turns) {
    if (turn.serverContent && turn.serverContent.outputTranscription) {
      console.debug('Received output transcription: %s\n', turn.serverContent.outputTranscription.text);
    }
  }

  session.close();
}

async function main() {
  await live().catch((e) => console.error('got error', e));
}

main();

คุณเปิดใช้การถอดเสียงเป็นคำของอินพุตเสียงได้โดยส่ง input_audio_transcription ในการกำหนดค่าการตั้งค่า

Python

import asyncio
from pathlib import Path
from google import genai
from google.genai import types

client = genai.Client()
model = "gemini-live-2.5-flash-preview"

config = {
    "response_modalities": ["TEXT"],
    "input_audio_transcription": {},
}

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:
        audio_data = Path("16000.pcm").read_bytes()

        await session.send_realtime_input(
            audio=types.Blob(data=audio_data, mime_type='audio/pcm;rate=16000')
        )

        async for msg in session.receive():
            if msg.server_content.input_transcription:
                print('Transcript:', msg.server_content.input_transcription.text)

if __name__ == "__main__":
    asyncio.run(main())

JavaScript

import { GoogleGenAI, Modality } from '@google/genai';
import * as fs from "node:fs";
import pkg from 'wavefile';
const { WaveFile } = pkg;

const ai = new GoogleGenAI({});
const model = 'gemini-live-2.5-flash-preview';

const config = {
  responseModalities: [Modality.TEXT],
  inputAudioTranscription: {}
};

async function live() {
  const responseQueue = [];

  async function waitMessage() {
    let done = false;
    let message = undefined;
    while (!done) {
      message = responseQueue.shift();
      if (message) {
        done = true;
      } else {
        await new Promise((resolve) => setTimeout(resolve, 100));
      }
    }
    return message;
  }

  async function handleTurn() {
    const turns = [];
    let done = false;
    while (!done) {
      const message = await waitMessage();
      turns.push(message);
      if (message.serverContent && message.serverContent.turnComplete) {
        done = true;
      }
    }
    return turns;
  }

  const session = await ai.live.connect({
    model: model,
    callbacks: {
      onopen: function () {
        console.debug('Opened');
      },
      onmessage: function (message) {
        responseQueue.push(message);
      },
      onerror: function (e) {
        console.debug('Error:', e.message);
      },
      onclose: function (e) {
        console.debug('Close:', e.reason);
      },
    },
    config: config,
  });

  // Send Audio Chunk
  const fileBuffer = fs.readFileSync("16000.wav");

  // Ensure audio conforms to API requirements (16-bit PCM, 16kHz, mono)
  const wav = new WaveFile();
  wav.fromBuffer(fileBuffer);
  wav.toSampleRate(16000);
  wav.toBitDepth("16");
  const base64Audio = wav.toBase64();

  // If already in correct format, you can use this:
  // const fileBuffer = fs.readFileSync("sample.pcm");
  // const base64Audio = Buffer.from(fileBuffer).toString('base64');

  session.sendRealtimeInput(
    {
      audio: {
        data: base64Audio,
        mimeType: "audio/pcm;rate=16000"
      }
    }
  );

  const turns = await handleTurn();

  for (const turn of turns) {
    if (turn.serverContent && turn.serverContent.outputTranscription) {
      console.log("Transcription")
      console.log(turn.serverContent.outputTranscription.text);
    }
  }
  for (const turn of turns) {
    if (turn.text) {
      console.debug('Received text: %s\n', turn.text);
    }
    else if (turn.data) {
      console.debug('Received inline data: %s\n', turn.data);
    }
    else if (turn.serverContent && turn.serverContent.inputTranscription) {
      console.debug('Received input transcription: %s\n', turn.serverContent.inputTranscription.text);
    }
  }

  session.close();
}

async function main() {
  await live().catch((e) => console.error('got error', e));
}

main();

สตรีมเสียงและวิดีโอ

เปลี่ยนเสียงและภาษา

โมเดล Live API แต่ละรุ่นรองรับชุดเสียงที่แตกต่างกัน การแสดงผลแบบแคสเคดครึ่งตัวรองรับ Puck, Charon, Kore, Fenrir, Aoede, Leda, Orus และ Zephyr เสียงแบบเนทีฟรองรับรายการที่ยาวกว่ามาก (เหมือนกับรายการรูปแบบ TTS) คุณฟังเสียงทั้งหมดได้ใน AI Studio

หากต้องการระบุเสียง ให้ตั้งค่าชื่อเสียงภายในออบเจ็กต์ speechConfig โดยเป็นส่วนหนึ่งของการกำหนดค่าเซสชัน

Python

config = {
    "response_modalities": ["AUDIO"],
    "speech_config": {
        "voice_config": {"prebuilt_voice_config": {"voice_name": "Kore"}}
    },
}

JavaScript

const config = {
  responseModalities: [Modality.AUDIO],
  speechConfig: { voiceConfig: { prebuiltVoiceConfig: { voiceName: "Kore" } } }
};

Live API รองรับหลายภาษา

หากต้องการเปลี่ยนภาษา ให้ตั้งค่ารหัสภาษาภายในออบเจ็กต์ speechConfig เป็นส่วนหนึ่งของการกำหนดค่าเซสชัน ดังนี้

Python

config = {
    "response_modalities": ["AUDIO"],
    "speech_config": {
        "language_code": "de-DE"
    }
}

JavaScript

const config = {
  responseModalities: [Modality.AUDIO],
  speechConfig: { languageCode: "de-DE" }
};

ความสามารถด้านเสียงแบบเนทีฟ

ความสามารถต่อไปนี้ใช้ได้กับเสียงต้นฉบับเท่านั้น ดูข้อมูลเพิ่มเติมเกี่ยวกับเสียงแบบเนทีฟได้ในเลือกรูปแบบและการสร้างเสียง

วิธีใช้เอาต์พุตเสียงแบบดั้งเดิม

หากต้องการใช้เอาต์พุตเสียงแบบเนทีฟ ให้กําหนดค่าโมเดลเสียงแบบเนทีฟรายการใดรายการหนึ่ง แล้วตั้งค่า response_modalities เป็น AUDIO

ดูตัวอย่างทั้งหมดได้ที่ส่งและรับเสียง

Python

model = "gemini-2.5-flash-preview-native-audio-dialog"
config = types.LiveConnectConfig(response_modalities=["AUDIO"])

async with client.aio.live.connect(model=model, config=config) as session:
    # Send audio input and receive audio

JavaScript

const model = 'gemini-2.5-flash-preview-native-audio-dialog';
const config = { responseModalities: [Modality.AUDIO] };

async function main() {

  const session = await ai.live.connect({
    model: model,
    config: config,
    callbacks: ...,
  });

  // Send audio input and receive audio

  session.close();
}

main();

การโต้ตอบที่สะท้อนถึงความรู้สึก

ฟีเจอร์นี้ช่วยให้ Gemini ปรับสไตล์การตอบกลับให้เข้ากับรูปแบบและโทนคำสั่ง

หากต้องการใช้กล่องโต้ตอบที่แสดงอารมณ์ ให้ตั้งค่าเวอร์ชัน API เป็น v1alpha และตั้งค่า enable_affective_dialog เป็น true ในข้อความการตั้งค่า

Python

client = genai.Client(http_options={"api_version": "v1alpha"})

config = types.LiveConnectConfig(
    response_modalities=["AUDIO"],
    enable_affective_dialog=True
)

JavaScript

const ai = new GoogleGenAI({ httpOptions: {"apiVersion": "v1alpha"} });

const config = {
  responseModalities: [Modality.AUDIO],
  enableAffectiveDialog: true
};

โปรดทราบว่าปัจจุบันมีเพียงโมเดลเอาต์พุตเสียงแบบเนทีฟเท่านั้นที่รองรับการสนทนาที่แสดงอารมณ์

เสียงแบบเชิงรุก

เมื่อเปิดใช้ฟีเจอร์นี้ Gemini จะตัดสินใจไม่ตอบกลับได้หากเนื้อหาไม่เกี่ยวข้อง

หากต้องการใช้ ให้ตั้งค่าเวอร์ชัน API เป็น v1alpha และกำหนดค่าช่อง proactivity ในข้อความการตั้งค่า แล้วตั้งค่า proactive_audio เป็น true

Python

client = genai.Client(http_options={"api_version": "v1alpha"})

config = types.LiveConnectConfig(
    response_modalities=["AUDIO"],
    proactivity={'proactive_audio': True}
)

JavaScript

const ai = new GoogleGenAI({ httpOptions: {"apiVersion": "v1alpha"} });

const config = {
  responseModalities: [Modality.AUDIO],
  proactivity: { proactiveAudio: true }
}

โปรดทราบว่าปัจจุบันมีเพียงรูปแบบเอาต์พุตเสียงแบบดั้งเดิมเท่านั้นที่รองรับเสียงแบบป้องกันไว้ล่วงหน้า

เอาต์พุตเสียงแบบดั้งเดิมที่มีการคิด

เอาต์พุตเสียงแบบเนทีฟรองรับความสามารถในการคิด ซึ่งพร้อมใช้งานผ่านโมเดล gemini-2.5-flash-exp-native-audio-thinking-dialog ที่แยกต่างหาก

ดูตัวอย่างทั้งหมดได้ที่ส่งและรับเสียง

Python

model = "gemini-2.5-flash-exp-native-audio-thinking-dialog"
config = types.LiveConnectConfig(response_modalities=["AUDIO"])

async with client.aio.live.connect(model=model, config=config) as session:
    # Send audio input and receive audio

JavaScript

const model = 'gemini-2.5-flash-exp-native-audio-thinking-dialog';
const config = { responseModalities: [Modality.AUDIO] };

async function main() {

  const session = await ai.live.connect({
    model: model,
    config: config,
    callbacks: ...,
  });

  // Send audio input and receive audio

  session.close();
}

main();

การตรวจจับกิจกรรมเสียงพูด (VAD)

การตรวจจับกิจกรรมเสียง (VAD) ช่วยให้โมเดลจดจำได้เมื่อมีคนพูด การดำเนินการนี้จำเป็นต่อการสร้างการสนทนาที่เป็นธรรมชาติ เนื่องจากช่วยให้ผู้ใช้ขัดจังหวะโมเดลได้ทุกเมื่อ

เมื่อ VAD ตรวจพบการหยุดชะงัก ระบบจะยกเลิกและทิ้งการสร้างที่กำลังดำเนินอยู่ เฉพาะข้อมูลที่ส่งไปยังไคลเอ็นต์แล้วเท่านั้นที่จะยังคงอยู่ในประวัติเซสชัน จากนั้นเซิร์ฟเวอร์จะส่งข้อความ BidiGenerateContentServerContent เพื่อรายงานการหยุดชะงัก

จากนั้นเซิร์ฟเวอร์ Gemini จะทิ้งการเรียกฟังก์ชันที่รอดำเนินการและส่งข้อความ BidiGenerateContentServerContent พร้อมรหัสของการเรียกที่ถูกยกเลิก

Python

async for response in session.receive():
    if response.server_content.interrupted is True:
        # The generation was interrupted

        # If realtime playback is implemented in your application,
        # you should stop playing audio and clear queued playback here.

JavaScript

const turns = await handleTurn();

for (const turn of turns) {
  if (turn.serverContent && turn.serverContent.interrupted) {
    // The generation was interrupted

    // If realtime playback is implemented in your application,
    // you should stop playing audio and clear queued playback here.
  }
}

VAD อัตโนมัติ

โดยค่าเริ่มต้น โมเดลจะดำเนินการ VAD กับสตรีมอินพุตเสียงแบบต่อเนื่องโดยอัตโนมัติ คุณสามารถกําหนดค่า VAD ได้ด้วยช่อง realtimeInputConfig.automaticActivityDetection ของการกําหนดค่าการตั้งค่า

เมื่อสตรีมเสียงหยุดชั่วคราวนานกว่า 1 วินาที (เช่น เนื่องจากผู้ใช้ปิดไมโครโฟน) คุณควรส่งเหตุการณ์ audioStreamEnd เพื่อล้างเสียงที่แคชไว้ โดยลูกค้าสามารถกลับมาส่งข้อมูลเสียงต่อได้ทุกเมื่อ

Python

# example audio file to try:
# URL = "https://storage.googleapis.com/generativeai-downloads/data/hello_are_you_there.pcm"
# !wget -q $URL -O sample.pcm
import asyncio
from pathlib import Path
from google import genai
from google.genai import types

client = genai.Client()
model = "gemini-live-2.5-flash-preview"

config = {"response_modalities": ["TEXT"]}

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:
        audio_bytes = Path("sample.pcm").read_bytes()

        await session.send_realtime_input(
            audio=types.Blob(data=audio_bytes, mime_type="audio/pcm;rate=16000")
        )

        # if stream gets paused, send:
        # await session.send_realtime_input(audio_stream_end=True)

        async for response in session.receive():
            if response.text is not None:
                print(response.text)

if __name__ == "__main__":
    asyncio.run(main())

JavaScript

// example audio file to try:
// URL = "https://storage.googleapis.com/generativeai-downloads/data/hello_are_you_there.pcm"
// !wget -q $URL -O sample.pcm
import { GoogleGenAI, Modality } from '@google/genai';
import * as fs from "node:fs";

const ai = new GoogleGenAI({});
const model = 'gemini-live-2.5-flash-preview';
const config = { responseModalities: [Modality.TEXT] };

async function live() {
  const responseQueue = [];

  async function waitMessage() {
    let done = false;
    let message = undefined;
    while (!done) {
      message = responseQueue.shift();
      if (message) {
        done = true;
      } else {
        await new Promise((resolve) => setTimeout(resolve, 100));
      }
    }
    return message;
  }

  async function handleTurn() {
    const turns = [];
    let done = false;
    while (!done) {
      const message = await waitMessage();
      turns.push(message);
      if (message.serverContent && message.serverContent.turnComplete) {
        done = true;
      }
    }
    return turns;
  }

  const session = await ai.live.connect({
    model: model,
    callbacks: {
      onopen: function () {
        console.debug('Opened');
      },
      onmessage: function (message) {
        responseQueue.push(message);
      },
      onerror: function (e) {
        console.debug('Error:', e.message);
      },
      onclose: function (e) {
        console.debug('Close:', e.reason);
      },
    },
    config: config,
  });

  // Send Audio Chunk
  const fileBuffer = fs.readFileSync("sample.pcm");
  const base64Audio = Buffer.from(fileBuffer).toString('base64');

  session.sendRealtimeInput(
    {
      audio: {
        data: base64Audio,
        mimeType: "audio/pcm;rate=16000"
      }
    }

  );

  // if stream gets paused, send:
  // session.sendRealtimeInput({ audioStreamEnd: true })

  const turns = await handleTurn();
  for (const turn of turns) {
    if (turn.text) {
      console.debug('Received text: %s\n', turn.text);
    }
    else if (turn.data) {
      console.debug('Received inline data: %s\n', turn.data);
    }
  }

  session.close();
}

async function main() {
  await live().catch((e) => console.error('got error', e));
}

main();

เมื่อใช้ send_realtime_input ทาง API จะตอบสนองต่อเสียงโดยอัตโนมัติตาม VAD ขณะที่ send_client_content จะเพิ่มข้อความลงในบริบทของโมเดลตามลําดับ แต่ send_realtime_input จะเพิ่มประสิทธิภาพเพื่อตอบสนองโดยเสียค่าใช้จ่ายในการเรียงลําดับแบบกำหนด

การกำหนดค่า VAD อัตโนมัติ

หากต้องการควบคุมกิจกรรม VAD ได้มากขึ้น คุณสามารถกําหนดค่าพารามิเตอร์ต่อไปนี้ ดูข้อมูลเพิ่มเติมได้ที่ข้อมูลอ้างอิง API

Python

from google.genai import types

config = {
    "response_modalities": ["TEXT"],
    "realtime_input_config": {
        "automatic_activity_detection": {
            "disabled": False, # default
            "start_of_speech_sensitivity": types.StartSensitivity.START_SENSITIVITY_LOW,
            "end_of_speech_sensitivity": types.EndSensitivity.END_SENSITIVITY_LOW,
            "prefix_padding_ms": 20,
            "silence_duration_ms": 100,
        }
    }
}

JavaScript

import { GoogleGenAI, Modality, StartSensitivity, EndSensitivity } from '@google/genai';

const config = {
  responseModalities: [Modality.TEXT],
  realtimeInputConfig: {
    automaticActivityDetection: {
      disabled: false, // default
      startOfSpeechSensitivity: StartSensitivity.START_SENSITIVITY_LOW,
      endOfSpeechSensitivity: EndSensitivity.END_SENSITIVITY_LOW,
      prefixPaddingMs: 20,
      silenceDurationMs: 100,
    }
  }
};

ปิดใช้ VAD อัตโนมัติ

หรือจะปิดใช้ VAD อัตโนมัติโดยการตั้งค่า realtimeInputConfig.automaticActivityDetection.disabled เป็น true ในข้อความการตั้งค่าก็ได้ ในการกำหนดค่านี้ ไคลเอ็นต์มีหน้าที่รับผิดชอบในการตรวจจับเสียงพูดของผู้ใช้และส่งข้อความ activityStart และ activityEnd ในเวลาที่เหมาะสม ระบบจะไม่ส่ง audioStreamEnd ในการกำหนดค่านี้ แต่ระบบจะแสดงข้อความ activityEnd แทนเพื่อระบุว่าสตรีมหยุดชะงัก

Python

config = {
    "response_modalities": ["TEXT"],
    "realtime_input_config": {"automatic_activity_detection": {"disabled": True}},
}

async with client.aio.live.connect(model=model, config=config) as session:
    # ...
    await session.send_realtime_input(activity_start=types.ActivityStart())
    await session.send_realtime_input(
        audio=types.Blob(data=audio_bytes, mime_type="audio/pcm;rate=16000")
    )
    await session.send_realtime_input(activity_end=types.ActivityEnd())
    # ...

JavaScript

const config = {
  responseModalities: [Modality.TEXT],
  realtimeInputConfig: {
    automaticActivityDetection: {
      disabled: true,
    }
  }
};

session.sendRealtimeInput({ activityStart: {} })

session.sendRealtimeInput(
  {
    audio: {
      data: base64Audio,
      mimeType: "audio/pcm;rate=16000"
    }
  }

);

session.sendRealtimeInput({ activityEnd: {} })

จํานวนโทเค็น

คุณดูจํานวนโทเค็นทั้งหมดที่ใช้ได้ในช่อง usageMetadata ของข้อความเซิร์ฟเวอร์ที่แสดงผล

Python

async for message in session.receive():
    # The server will periodically send messages that include UsageMetadata.
    if message.usage_metadata:
        usage = message.usage_metadata
        print(
            f"Used {usage.total_token_count} tokens in total. Response token breakdown:"
        )
        for detail in usage.response_tokens_details:
            match detail:
                case types.ModalityTokenCount(modality=modality, token_count=count):
                    print(f"{modality}: {count}")

JavaScript

const turns = await handleTurn();

for (const turn of turns) {
  if (turn.usageMetadata) {
    console.debug('Used %s tokens in total. Response token breakdown:\n', turn.usageMetadata.totalTokenCount);

    for (const detail of turn.usageMetadata.responseTokensDetails) {
      console.debug('%s\n', detail);
    }
  }
}

ความละเอียดของสื่อ

คุณสามารถระบุความละเอียดของสื่อสำหรับสื่ออินพุตได้โดยการตั้งค่าช่อง mediaResolution เป็นส่วนหนึ่งของการกำหนดค่าเซสชัน ดังนี้

Python

from google.genai import types

config = {
    "response_modalities": ["AUDIO"],
    "media_resolution": types.MediaResolution.MEDIA_RESOLUTION_LOW,
}

JavaScript

import { GoogleGenAI, Modality, MediaResolution } from '@google/genai';

const config = {
    responseModalities: [Modality.TEXT],
    mediaResolution: MediaResolution.MEDIA_RESOLUTION_LOW,
};

ข้อจำกัด

โปรดคำนึงถึงข้อจำกัดต่อไปนี้ของ Live API เมื่อวางแผนโปรเจ็กต์

รูปแบบการตอบกลับ

คุณตั้งค่ารูปแบบคำตอบได้เพียงรูปแบบเดียว (TEXT หรือ AUDIO) ต่อเซสชันในการกําหนดค่าเซสชัน การตั้งค่าทั้ง 2 รายการจะส่งผลให้เกิดข้อความแสดงข้อผิดพลาดในการกําหนดค่า ซึ่งหมายความว่าคุณสามารถกําหนดค่าโมเดลให้ตอบกลับด้วยข้อความหรือเสียงได้ แต่จะตอบกลับด้วยทั้ง 2 อย่างในเซสชันเดียวกันไม่ได้

การตรวจสอบสิทธิ์ไคลเอ็นต์

Live API มีการตรวจสอบสิทธิ์แบบเซิร์ฟเวอร์ต่อเซิร์ฟเวอร์เท่านั้นโดยค่าเริ่มต้น หากคุณกำลังติดตั้งใช้งานแอปพลิเคชัน Live API โดยใช้แนวทางแบบไคลเอ็นต์ต่อเซิร์ฟเวอร์ คุณต้องใช้โทเค็นชั่วคราวเพื่อลดความเสี่ยงด้านความปลอดภัย

ระยะเวลาเซสชัน

เซสชันเสียงเท่านั้นจะจำกัดไว้ที่ 15 นาที ส่วนเซสชันเสียงและวิดีโอจะจำกัดไว้ที่ 2 นาที อย่างไรก็ตาม คุณสามารถกําหนดค่าเทคนิคการจัดการเซสชันต่างๆ เพื่อขยายระยะเวลาเซสชันได้ไม่จํากัด

หน้าต่างบริบท

เซสชันมีขีดจํากัดของกรอบเวลาบริบทดังนี้

ภาษาที่รองรับ

Live API รองรับภาษาต่อไปนี้

ภาษา รหัส BCP-47 ภาษา รหัส BCP-47
เยอรมัน (เยอรมนี) de-DE อังกฤษ (ออสเตรเลีย)* en-AU
อังกฤษ (สหราชอาณาจักร)* en-GB อังกฤษ (อินเดีย) en-IN
อังกฤษ (อเมริกัน) en-US สเปน (สหรัฐอเมริกา) es-US
ฝรั่งเศส (ฝรั่งเศส) fr-FR ฮินดี (อินเดีย) hi-IN
โปรตุเกส (บราซิล) pt-BR อาหรับ (ทั่วไป) ar-XA
สเปน (สเปน)* es-ES ฝรั่งเศส (แคนาดา)* fr-CA
อินโดนีเซีย (อินโดนีเซีย) id-ID อิตาลี (อิตาลี) it-IT
ญี่ปุ่น (ญี่ปุ่น) ja-JP ตุรกี (ตุรกี) tr-TR
เวียดนาม (เวียดนาม) vi-VN เบงกาลี (อินเดีย) bn-IN
คุชราต (อินเดีย)* gu-IN กันนาดา (อินเดีย)* kn-IN
มราฐี (อินเดีย) mr-IN มาลายาลัม (อินเดีย)* ml-IN
ทมิฬ (อินเดีย) ta-IN เตลูกู (อินเดีย) te-IN
ดัตช์ (เนเธอร์แลนด์) nl-NL เกาหลี (เกาหลีใต้) ko-KR
จีนกลาง (จีน)* cmn-CN โปแลนด์ (โปแลนด์) pl-PL
รัสเซีย (รัสเซีย) ru-RU ไทย (ประเทศไทย) th-TH

ภาษาที่มีเครื่องหมายดอกจัน (*) ไม่พร้อมใช้งานสำหรับเสียงต้นฉบับ

ขั้นตอนถัดไป