Gemini Live API 支援使用 gemini-3.5-transcribe-live 模型進行低延遲的即時語音轉文字轉錄。透過 WebSockets 連線至 Live API,或使用 Google Gen AI SDK,即可串流連續音訊輸入內容,並在語音出現時接收即時文字轉錄稿。
開發人員平台 (例如 Agora、Fishjam、LiveKit、Pipecat、Vercel 和 Vision Agents) 運用 Gemini Live API,可讓開發人員輕鬆建構及部署高效能的語音介面。這些平台會在幕後管理複雜的即時媒體串流基礎架構,讓開發人員專心打造使用者體驗。
真人服務專員與即時轉錄
兩者都使用 Live API 雙向串流連線,但即時轉錄功能是專用的低延遲語音辨識管道,而非對話式代理程式。
| 功能 | 線上服務專員 | 即時轉錄 |
|---|---|---|
| 主要作用 | 對話式助理會聆聽、推理並回覆。 | 即時語音轉文字管道,可轉錄輸入的音訊。 |
| 回覆方式 | 語音音訊和文字 (response_modalities=["AUDIO"])。 |
串流文字轉錄稿 (response_modalities=["TEXT"])。 |
| 互動風格 | 以輪流對話的形式進行,可偵測暫停和中斷。 | 在說話者說話時,持續處理串流。 |
| 支援的功能 | 函式呼叫、Google 搜尋、系統指令。 | 語音偏好設定 (custom_vocabulary)、語言偵測、手動和混合 VAD、智慧轉錄。 |
| 輸入串流 | 多模態:音訊、影片、圖像、文字。 | 音訊輸入 (原始 16 位元 PCM)。 |
開始使用
下列範例示範如何使用 gemini-3.5-transcribe-live 開啟雙向串流工作階段,並接收即時轉錄內容。
Python
import asyncio
from google import genai
from google.genai import types
client = genai.Client()
model = "gemini-3.5-transcribe-live"
config = types.LiveConnectConfig(
response_modalities=["TEXT"],
input_audio_transcription=types.AudioTranscriptionConfig(
language_codes=[], # Automatic language detection
),
)
async def main():
async with client.aio.live.connect(model=model, config=config) as session:
print("Session established with Live Transcription")
# Receive transcription events
async for response in session.receive():
server_content = response.server_content
if server_content and server_content.input_transcription:
print("Transcript:", server_content.input_transcription.text)
if __name__ == "__main__":
asyncio.run(main())
JavaScript
import { GoogleGenAI, Modality } from '@google/genai';
const ai = new GoogleGenAI({});
const model = 'gemini-3.5-transcribe-live';
const config = {
responseModalities: [Modality.TEXT],
inputAudioTranscription: {
languageCodes: [], // Automatic language detection
},
};
async function main() {
const session = await ai.live.connect({
model: model,
config: config,
callbacks: {
onopen: () => console.log('Connected to Live Transcription'),
onmessage: (message) => {
const content = message.serverContent;
if (content?.inputTranscription) {
console.log('Transcript:', content.inputTranscription.text);
}
},
onerror: (e) => console.error('Error:', e.message),
onclose: (e) => console.log('Connection closed:', e.reason),
},
});
}
main();
WebSocket
const API_KEY = "YOUR_API_KEY";
const MODEL_NAME = "gemini-3.5-transcribe-live";
const WS_URL = `wss://generativelanguage.googleapis.com/ws/google.ai.generativelanguage.v1beta.GenerativeService.BidiGenerateContent?key=${API_KEY}`;
const websocket = new WebSocket(WS_URL);
websocket.onopen = () => {
console.log('WebSocket connected');
const setupMessage = {
setup: {
model: `models/${MODEL_NAME}`,
generationConfig: {
responseModalities: ['TEXT'],
},
inputAudioTranscription: {
languageCodes: []
}
}
};
websocket.send(JSON.stringify(setupMessage));
};
websocket.onmessage = (event) => {
const response = JSON.parse(event.data);
const content = response.serverContent;
if (content?.inputTranscription) {
console.log('Transcript:', content.inputTranscription.text);
}
};
暫定和最終轉錄稿
音訊串流傳送至 Live API 時,伺服器會在 server_content 中發出兩個互補的轉錄欄位:
interim_input_transcription:低延遲,在說話者說話時更新推測的部分假設。這些部分更新會快速進行,延遲時間極短。使用interim_input_transcription轉譯即時 UI 字幕或預覽字幕。input_transcription:說話者暫停、輪流說話完成或語音完成時,系統會發出最終轉錄稿。發出後,這段文字代表模型對該語音片段的權威轉錄內容。在智慧轉錄模式下,這會包括經過清理和格式化的回覆。
以下範例說明如何顯示串流中繼部分結果,以及提交最終轉錄稿:
Python
async def receive_transcripts(session):
async for response in session.receive():
server_content = response.server_content
if not server_content:
continue
# Real-time interim hypothesis (updates dynamically as user speaks)
if server_content.interim_input_transcription:
interim_text = server_content.interim_input_transcription.text
print(f"\r[Interim] {interim_text}", end="", flush=True)
# Finalized transcript (emitted on speech completion)
if server_content.input_transcription:
final_text = server_content.input_transcription.text
print(f"\n[Final] {final_text}")
JavaScript
onmessage: (message) => {
const content = message.serverContent;
if (!content) return;
if (content.interimInputTranscription) {
// Update live subtitle preview on screen
renderInterimPreview(content.interimInputTranscription.text);
}
if (content.inputTranscription) {
// Append final committed transcript to chat history
commitFinalTranscript(content.inputTranscription.text);
}
};
WebSocket
websocket.onmessage = (event) => {
const response = JSON.parse(event.data);
const content = response.serverContent;
if (content?.interimInputTranscription) {
console.log('[Interim]:', content.interimInputTranscription.text);
}
if (content?.inputTranscription) {
console.log('[Final]:', content.inputTranscription.text);
}
};
正在傳送音訊
透過有效連線串流音訊區塊,以原始 16 位元 PCM 音訊格式傳輸。
- 音訊格式:16 kHz 的原始 16 位元 PCM (單聲道,小端序)。
- 分塊大小:以 100 毫秒 (1,024 到 2,048 個影格) 為單位傳送音訊。
MIME 類型:
audio/pcm;rate=16000(或相符的取樣率)。
Python
# Stream a raw PCM audio chunk
await session.send_realtime_input(
audio=types.Blob(
data=audio_chunk_bytes,
mime_type="audio/pcm;rate=16000"
)
)
# Signal the end of the audio stream when finished
await session.send_realtime_input(audio_stream_end=True)
JavaScript
// Send base64-encoded PCM audio chunk
session.sendRealtimeInput({
audio: {
data: audioChunkBase64,
mimeType: 'audio/pcm;rate=16000'
}
});
// Signal stream end
session.sendRealtimeInput({
audioStreamEnd: true
});
WebSocket
// Send base64-encoded PCM audio chunk
websocket.send(JSON.stringify({
realtimeInput: {
audio: {
data: audioChunkBase64,
mimeType: 'audio/pcm;rate=16000'
}
}
}));
// Signal stream end
websocket.send(JSON.stringify({
realtimeInput: {
audioStreamEnd: true
}
}));
轉錄功能
自動偵測語言
根據預設,省略 language_codes 或將 language_codes=[] 設為 language_codes=[],即可啟用自動語言辨識功能。模型會動態偵測語音中的語言,包括多語言對話和交替使用不同語言的情況。
Python
config = types.LiveConnectConfig(
response_modalities=["TEXT"],
input_audio_transcription=types.AudioTranscriptionConfig(
language_codes=[],
),
)
JavaScript
const config = {
responseModalities: [Modality.TEXT],
inputAudioTranscription: {
languageCodes: [],
},
};
WebSocket
const setupMessage = {
setup: {
model: 'models/gemini-3.5-transcribe-live',
generationConfig: {
responseModalities: ['TEXT'],
},
inputAudioTranscription: {
languageCodes: [],
},
},
};
websocket.send(JSON.stringify(setupMessage));
特定語言提示
提供明確的 BCP-47 語言代碼 (例如西班牙文為 ["es-ES"],法文為 ["fr-FR"]),將辨識結果偏向特定語言 (請參閱「支援的語言」)。
Python
config = types.LiveConnectConfig(
response_modalities=["TEXT"],
input_audio_transcription=types.AudioTranscriptionConfig(
language_codes=["es-ES"],
),
)
JavaScript
const config = {
responseModalities: [Modality.TEXT],
inputAudioTranscription: {
languageCodes: ['es-ES'],
},
};
WebSocket
const setupMessage = {
setup: {
model: 'models/gemini-3.5-transcribe-live',
generationConfig: {
responseModalities: ['TEXT'],
},
inputAudioTranscription: {
languageCodes: ['es-ES'],
},
},
};
websocket.send(JSON.stringify(setupMessage));
自訂詞彙偏誤
提供最多 1,000 個詞組、專有名詞、品牌名稱或術語的清單,custom_vocabulary讓語音辨識器優先辨識特定術語 (通常最多 100 個字詞可達到最佳效果)。
Python
config = types.LiveConnectConfig(
response_modalities=["TEXT"],
input_audio_transcription=types.AudioTranscriptionConfig(
language_codes=[],
custom_vocabulary=["Gemini", "Kubernetes", "BigQuery"],
),
)
JavaScript
const config = {
responseModalities: [Modality.TEXT],
inputAudioTranscription: {
languageCodes: [],
customVocabulary: ['Gemini', 'Kubernetes', 'BigQuery'],
},
};
WebSocket
const setupMessage = {
setup: {
model: 'models/gemini-3.5-transcribe-live',
generationConfig: {
responseModalities: ['TEXT'],
},
inputAudioTranscription: {
languageCodes: [],
customVocabulary: ['Gemini', 'Kubernetes', 'BigQuery'],
},
},
};
websocket.send(JSON.stringify(setupMessage));
智慧轉錄
使用 input_audio_transcription 中的 mode 參數設定轉錄輸出格式:
VERBATIM(預設):逐字轉錄所有說出的內容,保留原始的贅字 (例如「嗯」、「呃」、「像」)、重複內容和錯誤開頭。SMART(智慧轉錄):整理並編排轉錄稿,方便閱讀:- 移除口語障礙:移除贅字、口吃和錯誤開頭。
- 即時自動修正:自然地解決口語修正問題。
- 結構化格式:自動設定清單、項目符號、數字、日期和段落分隔符號的格式。
- 文法和大小寫:自然地使用大寫字母,並潤飾標點符號。
Python
config = types.LiveConnectConfig(
response_modalities=["TEXT"],
input_audio_transcription=types.AudioTranscriptionConfig(
mode="SMART",
),
)
JavaScript
const config = {
responseModalities: [Modality.TEXT],
inputAudioTranscription: {
mode: 'SMART',
},
};
WebSocket
const setupMessage = {
setup: {
model: 'models/gemini-3.5-transcribe-live',
generationConfig: {
responseModalities: ['TEXT'],
},
inputAudioTranscription: {
mode: 'SMART',
},
},
};
websocket.send(JSON.stringify(setupMessage));
語音活動偵測 (VAD) 策略
自動 VAD (預設)
根據預設,伺服器端自動語音活動偵測功能會偵測說話者何時開始和停止說話。
混合 VAD
混合 VAD 結合伺服器端自動語音開始偵測和用戶端語音結束偵測,可零延遲完成回合:
- 伺服器端自動 VAD 仍會啟用,並使用前置音訊填補功能準確偵測語音開頭,避免截斷開頭的字詞。
- 用戶端 VAD 偵測到靜音:當本機裝置上的 VAD 偵測到說話者停止說話時,用戶端會立即傳送
audio_stream_end訊號。 - 快速完成:伺服器會將
audio_stream_end視為立即完成提示,略過預設的伺服器端靜音等待時間,並以最短延遲時間傳回最終轉錄稿。 - 備援:如果用戶端 VAD 無法觸發,伺服器端 VAD 會自動備援。
Python
config = types.LiveConnectConfig(
response_modalities=["TEXT"],
input_audio_transcription=types.AudioTranscriptionConfig(),
)
async with client.aio.live.connect(model=model, config=config) as session:
# Stream audio chunks...
await session.send_realtime_input(
audio=types.Blob(data=chunk, mime_type="audio/pcm;rate=16000")
)
# When client-side VAD detects end of speech, send audio_stream_end:
await session.send_realtime_input(audio_stream_end=True)
JavaScript
const config = {
responseModalities: [Modality.TEXT],
inputAudioTranscription: {},
};
// Stream audio...
session.sendRealtimeInput({
audio: { data: chunkBase64, mimeType: 'audio/pcm;rate=16000' }
});
// When client VAD detects end of speech, send audioStreamEnd:
session.sendRealtimeInput({
audioStreamEnd: true
});
WebSocket
const setupMessage = {
setup: {
model: 'models/gemini-3.5-transcribe-live',
generationConfig: {
responseModalities: ['TEXT'],
},
inputAudioTranscription: {},
},
};
websocket.send(JSON.stringify(setupMessage));
// Stream audio...
websocket.send(JSON.stringify({
realtimeInput: {
audio: { data: chunkBase64, mimeType: 'audio/pcm;rate=16000' }
}
}));
// When client VAD detects end of speech, send audioStreamEnd:
websocket.send(JSON.stringify({
realtimeInput: {
audioStreamEnd: true
}
}));
手動 VAD (按下開始交談)
如果是對講機介面或一按即說按鈕,請完全停用自動 VAD,並使用 activity_start 和 activity_end 明確控制轉彎界線:
Python
config = types.LiveConnectConfig(
response_modalities=["TEXT"],
realtime_input_config=types.RealtimeInputConfig(
automatic_activity_detection=types.AutomaticActivityDetection(
disabled=True
)
),
input_audio_transcription=types.AudioTranscriptionConfig(),
)
async with client.aio.live.connect(model=model, config=config) as session:
# Button pressed: signal speech start
await session.send_realtime_input(activity_start=types.ActivityStart())
# Stream audio chunks...
await session.send_realtime_input(audio=types.Blob(data=chunk, mime_type="audio/pcm;rate=16000"))
# Button released: signal speech end
await session.send_realtime_input(activity_end=types.ActivityEnd())
JavaScript
const config = {
responseModalities: [Modality.TEXT],
realtimeInputConfig: {
automaticActivityDetection: {
disabled: true,
},
},
inputAudioTranscription: {},
};
// Signal speech start
session.sendRealtimeInput({ activityStart: {} });
// Stream audio...
// Signal speech end
session.sendRealtimeInput({ activityEnd: {} });
WebSocket
const setupMessage = {
setup: {
model: 'models/gemini-3.5-transcribe-live',
generationConfig: {
responseModalities: ['TEXT'],
},
realtimeInputConfig: {
automaticActivityDetection: {
disabled: true,
},
},
inputAudioTranscription: {},
},
};
websocket.send(JSON.stringify(setupMessage));
// Button pressed: signal speech start
websocket.send(JSON.stringify({
realtimeInput: {
activityStart: {},
},
}));
// Stream audio...
websocket.send(JSON.stringify({
realtimeInput: {
audio: { data: chunkBase64, mimeType: 'audio/pcm;rate=16000' },
},
}));
// Button released: signal speech end
websocket.send(JSON.stringify({
realtimeInput: {
activityEnd: {},
},
}));
用戶端應用程式中的臨時權杖
如果是用戶端對伺服器的應用程式 (例如直接從麥克風串流的行動或網路應用程式),請使用臨時權杖,避免在用戶端程式碼中公開 API 金鑰。
在伺服器上建立受限的臨時權杖,然後再啟動用戶端連線:
Python
import datetime
from google import genai
client = genai.Client()
expire_time = datetime.datetime.now(tz=datetime.timezone.utc) + datetime.timedelta(minutes=30)
token = client.auth_tokens.create(
config={
"uses": 1,
"expire_time": expire_time,
"live_connect_constraints": {
"model": "gemini-3.5-transcribe-live",
"config": {
"response_modalities": ["TEXT"],
"input_audio_transcription": {
"language_codes": [],
},
},
},
}
)
JavaScript
import { GoogleGenAI } from '@google/genai';
const client = new GoogleGenAI({});
const expireTime = new Date(Date.now() + 30 * 60 * 1000).toISOString();
const token = await client.authTokens.create({
config: {
uses: 1,
expireTime: expireTime,
liveConnectConstraints: {
model: 'gemini-3.5-transcribe-live',
config: {
responseModalities: ['TEXT'],
inputAudioTranscription: {
languageCodes: [],
},
},
},
},
});
REST
curl -X POST "https://generativelanguage.googleapis.com/v1beta/auth_tokens" \
-H "x-goog-api-key: ${GEMINI_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"uses": 1,
"expireTime": "YYYY-MM-DDTHH:MM:SSZ",
"liveConnectConstraints": {
"model": "models/gemini-3.5-transcribe-live",
"config": {
"responseModalities": ["TEXT"],
"inputAudioTranscription": {
"languageCodes": []
}
}
}
}'
支援的語言
Gemini 3.5 Transcribe Live 支援下列語言和 BCP-47 語言代碼:
| 語言 | BCP-47 代碼 | 語言 | BCP-47 代碼 |
|---|---|---|---|
| 南非荷蘭文 | af-ZA |
日文 | ja-JP |
| 阿姆哈拉文 | am-ET |
爪哇語 | jv-ID |
| 阿拉伯文 (埃及) | ar-EG |
Kabuverdianu | kea-CV |
| 亞美尼亞文 | hy-AM |
卡納達文 | kn-IN |
| 阿薩姆文 | as-IN |
哈薩克文 | kk-KZ |
| 亞塞拜然文 | az-AZ |
韓文 | ko-KR |
| 白俄羅斯語 | be-BY |
吉爾吉斯文 | ky-KG |
| 孟加拉文 (孟加拉) | bn-BD |
拉脫維亞文 | lv-LV |
| 孟加拉文 (印度) | bn-IN |
林格拉文 | ln-CD |
| 波士尼亞文 | bs-BA |
立陶宛文 | lt-LT |
| 保加利亞文 | bg-BG |
馬其頓文 | mk-MK |
| 保加利亞文 (阿羅馬尼亞文) | rup-BG |
馬來文 | ms-MY |
| 緬甸文 | my-MM |
馬拉雅拉姆文 | ml-IN |
| 粵語 (繁體) | yue-Hant-HK |
馬爾他文 | mt-MT |
| 加泰隆尼亞文 | ca-ES |
中文 (簡體) | cmn-Hans-CN |
| 宿霧文 | ceb |
馬拉地文 | mr-IN |
| 中部高棉文 | km-KH |
蒙古文 | mn-MN |
| 克羅埃西亞文 | hr-HR |
尼泊爾文 | ne-NP |
| 捷克文 | cs-CZ |
挪威文 | nb-NO |
| 丹麥文 | da-DK |
奧里雅文 | or-IN |
| 荷蘭文 | nl-NL |
波蘭文 | pl-PL |
| 英文 (英國) | en-GB |
葡萄牙文 (巴西) | pt-BR |
| 英文 (印度) | en-IN |
葡萄牙文 (葡萄牙) | pt-PT |
| 英文 (美國) | en-US |
旁遮普文 | pa-IN |
| 愛沙尼亞文 | et-EE |
旁遮普文 (古爾穆基字母) | pa-Guru-IN |
| 波斯文 | fa-IR |
羅馬尼亞文 | ro-RO |
| 菲律賓文 | fil-PH |
俄文 | ru-RU |
| 芬蘭文 | fi-FI |
塞爾維亞文 | sr-RS |
| 法文 | fr-FR |
信德文 (阿拉伯字母) | sd-Arab-IN |
| 加里西亞文 | gl-ES |
斯洛伐克文 | sk-SK |
| 喬治亞文 | ka-GE |
斯洛維尼亞文 | sl-SI |
| 德文 | de-DE |
西班牙文 (拉丁美洲) | es-419 |
| 希臘文 | el-GR |
西班牙文 (美國) | es-US |
| 古吉拉特文 | gu-IN |
斯瓦希里文 (肯亞) | sw-KE |
| 豪薩文 | ha-NG |
瑞典文 | sv-SE |
| 希伯來文 | he-IL |
塔吉克文 | tg-TJ |
| 北印度文 | hi-IN |
泰盧固文 | te-IN |
| 匈牙利文 | hu-HU |
泰文 | th-TH |
| 冰島文 | is-IS |
土耳其文 | tr-TR |
| 印度英語 | en-IN |
烏克蘭文 | uk-UA |
| 印尼文 | id-ID |
烏茲別克文 | uz-UZ |
| 義大利文 | it-IT |
越南文 | vi-VN |
參數參照
使用 input_audio_transcription 和 realtime_input_config 中的欄位設定即時轉錄:
| 參數 | 類型 | 說明 |
|---|---|---|
language_codes |
字串陣列 | BCP-47 語言代碼 (例如 ["en-US"])。如果省略或空白 ([]),模型會自動偵測語言並處理多語言語音。 |
custom_vocabulary |
字串陣列 | 最多可提供 1,000 個自訂字詞、縮寫、品牌名稱或專有名詞,以調整語音辨識結果。 |
mode |
字串 | 轉錄模式:"VERBATIM" (預設) 或 "SMART" (智慧轉錄)。如果設為 "SMART",模型會移除贅字、編排清單格式,並修正語句不流暢之處。 |
automatic_activity_detection.disabled |
布林值 | 設為 true 可停用自動語音活動偵測功能,並手動傳送 activityStart 和 activityEnd 信號。 |
伺服器回應欄位
| 欄位 | 說明 |
|---|---|
server_content.interim_input_transcription |
使用者說話時,系統會持續發出低延遲的暫時性部分轉錄假設。 |
server_content.input_transcription |
語音輪流說話結束時發出的最終權威輸入轉錄稿。 |
限制
- 工作階段持續時間:即時轉錄工作階段最多可連續串流 10 分鐘。
- 說話者區分:直播工作階段不支援說話者區分功能。如要進行說話者區分,請使用非串流的 音訊轉錄端點。
- 字詞層級時間戳記:Live API 不支援字詞層級時間戳記。Live API 會發出語句層級的時間戳記 (
interim_input_transcription和input_transcription)。 - 自訂詞彙:您最多可以在
custom_vocabulary中提供 1,000 個字詞,但通常最多 100 個字詞就能獲得最佳結果。 - 模式相容性:智慧轉錄 (
"mode": "SMART") 會移除贅字並格式化意圖感知文字,但無法與字詞註解搭配使用。
後續步驟
- 如要瞭解非串流音訊檔案,請參閱 Gemini Transcribe 說明文件。
- 如要瞭解對話式語音代理程式,請參閱 Live API 總覽。
- 如要瞭解如何即時翻譯語音,請參閱即時翻譯指南。
- 如要瞭解 Live API 串流的定價,請參閱定價頁面。
- 請參閱 Live API 功能指南。