Live API capabilities guide

这是一份全面的指南,介绍了 Live API 提供的功能和配置。 如需查看概述和常见用例的示例代码,请参阅开始使用 Live API 页面。

准备工作

  • 熟悉核心概念:如果您尚未这样做,请先阅读开始使用 Live API 页面。本文将向您介绍 Live API 的基本原理、运作方式以及不同的实现方法
  • 在 AI Studio 中试用 Live API:在开始构建之前,您可能会发现试用 Google AI Studio 中的 Live API 非常有用。如需在 Google AI Studio 中使用实时 API,请选择 Stream

建立连接

以下示例展示了如何使用 API 密钥创建连接:

Python

import asyncio
from google import genai

client = genai.Client()

model = "gemini-2.5-flash-native-audio-preview-12-2025"
config = {"response_modalities": ["AUDIO"]}

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

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

JavaScript

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

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

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,
  });

  console.debug("Session started");
  // Send content...

  session.close();
}

main();

互动模式

以下部分提供了 Live API 中不同输入和输出模态的示例和支持上下文。

发送和接收音频

最常见的音频示例是音频转音频入门指南中介绍了此示例。

音频格式

Live API 中的音频数据始终是原始的小端字节序 16 位 PCM。音频输出始终使用 24kHz 的采样率。输入音频的原始采样率为 16kHz,但 Live API 会在需要时重新采样,因此可以发送任何采样率。如需传达输入音频的采样率,请将每个包含音频的 Blob 的 MIME 类型设置为类似 audio/pcm;rate=16000 的值。

正在发送短信

以下是发送文字的方法:

Python

message = "Hello, how are you?"
await session.send_client_content(turns=message, turn_complete=True)

JavaScript

const message = 'Hello, how are you?';
session.sendClientContent({ turns: message, turnComplete: true });

增量内容更新

使用增量更新来发送文本输入、建立会话上下文或恢复会话上下文。对于简短的上下文,您可以发送逐轮互动来表示确切的事件序列:

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 })

对于较长的上下文,建议提供单个消息摘要,以释放上下文窗口,以便进行后续互动。如需了解加载会话上下文的其他方法,请参阅会话恢复

音频转录

除了模型回答之外,您还可以收到音频输出和音频输入的转写内容。

如需启用模型音频输出的转写功能,请在设置配置中发送 output_audio_transcription。转写语言是从模型的回答中推断出来的。

Python

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

client = genai.Client()
model = "gemini-2.5-flash-native-audio-preview-12-2025"

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-2.5-flash-native-audio-preview-12-2025';

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-2.5-flash-native-audio-preview-12-2025"

config = {
    "response_modalities": ["AUDIO"],
    "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-2.5-flash-native-audio-preview-12-2025';

const config = {
  responseModalities: [Modality.AUDIO],
  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.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();

流式传输音频和视频

更改语音和语言

原生音频输出模型支持我们的文字转语音 (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 支持多种语言原生音频输出模型会自动选择合适的语言,不支持明确设置语言代码。

原生音频功能

我们最新的模型支持原生音频输出,可提供自然、逼真的语音和改进的多语言性能。原生音频还支持共情(可感知情绪)对话主动音频(模型可智能决定何时响应输入)和“思考”等高级功能。

共情对话

借助此功能,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-native-audio-preview-12-2025 支持思考能力,默认启用动态思考。

thinkingBudget 参数用于为模型提供指导,帮助其了解在生成回答时可使用的思考 token 数量。您可以通过将 thinkingBudget 设置为 0 来停用思考功能。如需详细了解模型的 thinkingBudget 配置,请参阅思考预算文档

Python

model = "gemini-2.5-flash-native-audio-preview-12-2025"

config = types.LiveConnectConfig(
    response_modalities=["AUDIO"]
    thinking_config=types.ThinkingConfig(
        thinking_budget=1024,
    )
)

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-native-audio-preview-12-2025';
const config = {
  responseModalities: [Modality.AUDIO],
  thinkingConfig: {
    thinkingBudget: 1024,
  },
};

async function main() {

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

  // Send audio input and receive audio

  session.close();
}

main();

此外,您还可以在配置中将 includeThoughts 设置为 true,以启用思路总结。如需了解详情,请参阅思考总结

Python

model = "gemini-2.5-flash-native-audio-preview-12-2025"

config = types.LiveConnectConfig(
    response_modalities=["AUDIO"]
    thinking_config=types.ThinkingConfig(
        thinking_budget=1024,
        include_thoughts=True
    )
)

JavaScript

const model = 'gemini-2.5-flash-native-audio-preview-12-2025';
const config = {
  responseModalities: [Modality.AUDIO],
  thinkingConfig: {
    thinkingBudget: 1024,
    includeThoughts: true,
  },
};

语音活动检测 (VAD)

语音活动检测 (VAD) 可让模型识别用户何时在说话。这对于创建自然对话至关重要,因为这使用户可以随时中断模型。

当 VAD 检测到中断时,系统会取消并舍弃正在进行的生成操作。会话历史记录中仅保留已发送给客户端的信息。服务器随后会发送一条 BidiGenerateContentServerContent 消息来报告中断情况。

然后,Gemini 服务器会舍弃所有待处理的函数调用,并发送一条 BidiGenerateContentServerContent 消息,其中包含已取消调用的 ID。

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。可以使用设置配置realtimeInputConfig.automaticActivityDetection 字段配置 VAD。

当音频串流暂停超过一秒时(例如,因为用户关闭了麦克风),应发送 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

或者,您也可以在设置消息中将 realtimeInputConfig.automaticActivityDetection.disabled 设置为 true,以停用自动 VAD。在此配置中,客户端负责检测用户语音,并在适当的时间发送 activityStartactivityEnd 消息。此配置中未发送 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: {} })

Token 计数

您可以在返回的服务器消息的 usageMetadata 字段中找到消耗的 token 总数。

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 的以下限制。

响应模态

在会话配置中,您只能为每个会话设置一种回答模态(TEXTAUDIO)。同时设置这两个参数会导致配置出错提示。这意味着,您可以将模型配置为以文本或音频进行回答,但不能在同一会话中同时使用这两种方式。

客户端身份验证

Live API 默认仅提供服务器到服务器的身份验证。如果您要使用客户端到服务器的方法来实现 Live API 应用,则需要使用临时令牌来降低安全风险。

会话时长

纯音频会话时长不得超过 15 分钟,音频加视频会话时长不得超过 2 分钟。不过,您可以配置不同的会话管理技术,以无限延长会话时长。

上下文窗口

会话的上下文窗口限制为:

  • 对于原生音频输出模型,为 12.8 万个 token
  • 其他 Live API 模型的令牌数量为 32,000

支持的语言

Live API 支持以下 70 种语言。

语言 BCP-47 代码 语言 BCP-47 代码
南非荷兰语 af 卡纳达语 kn
阿尔巴尼亚语 sq 哈萨克语 kk
阿姆哈拉语 am 高棉语 km
阿拉伯语 ar 韩语 ko
亚美尼亚语 hy 老挝语 lo
阿萨姆语 as 拉脱维亚语 lv
阿塞拜疆语 az 立陶宛语 lt
巴斯克语 eu 马其顿语 mk
白俄罗斯语 be 马来语 ms
孟加拉语 bn 马拉雅拉姆语 ml
波斯尼亚语 bs 马拉地语 mr
保加利亚语 bg 蒙古语 mn
加泰罗尼亚语 ca 尼泊尔语 ne
中文 zh 挪威语 no
克罗地亚语 hr 奥里亚语 or
捷克语 cs 波兰语 pl
丹麦语 da 葡萄牙语 pt
荷兰语 nl 旁遮普语 pa
英语 en 罗马尼亚语 ro
爱沙尼亚语 et 俄语 ru
菲律宾语 fil 塞尔维亚语 sr
芬兰语 fi 斯洛伐克语 sk
法语 fr 斯洛文尼亚语 sl
加利西亚语 gl 西班牙语 es
格鲁吉亚语 ka 斯瓦希里语 sw
德语 de 瑞典语 sv
希腊语 el 泰米尔语 ta
古吉拉特语 gu 泰卢固语 te
希伯来语 iw 泰语 th
印地语 hi 土耳其语 tr
匈牙利语 hu 乌克兰语 uk
冰岛语 is 乌尔都语 ur
印度尼西亚语 id 乌兹别克语 uz
意大利语 it 越南语 vi
日语 ja 祖鲁语 zu

后续步骤