تتيح واجهة برمجة التطبيقات Live API تفاعلات صوتية ثنائية الاتجاه بالفيديو مع Gemini بوقت استجابة منخفض، ما يتيح لك التحدث إلى Gemini مباشرةً أثناء بث فيديو أو مشاركة شاشتك. باستخدام واجهة برمجة التطبيقات Live API، يمكنك منح المستخدمين النهائيين تجربة محادثات صوتية طبيعية تشبه المحادثات بين البشر.
يمكنك تجربة Live API في Google AI Studio. لاستخدام Live API في Google AI Studio، اختَر البث.
طريقة عمل Live API
البث
تستخدِم واجهة برمجة التطبيقات Live API نموذج بث عبر اتصال WebSocket. عند التفاعل مع واجهة برمجة التطبيقات، يتم إنشاء اتصال دائم. يتم بث بياناتك (صوت أو فيديو أو نص) باستمرار إلى النموذج، ويتم بث ردّ النموذج (نص أو صوت) مرة أخرى في الوقت الفعلي من خلال عملية الربط نفسها.
يضمن هذا البث الثنائي وقت استجابة منخفضًا ويدعم ميزات مثل رصد النشاط الصوتي واستخدام الأدوات وإنشاء الكلام.
لمزيد من المعلومات عن واجهة برمجة التطبيقات الأساسية WebSockets API، يُرجى الاطّلاع على مرجع واجهة برمجة التطبيقات WebSockets API.
إنشاء العروض باستخدام Live API {:#building-with-live-api}ß
إنشاء اتصال
يوضّح المثال التالي كيفية إنشاء اتصال باستخدام مفتاح واجهة برمجة التطبيقات:
import asyncio
from google import genai
client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"
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())
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI({ apiKey: "GOOGLE_API_KEY" });
const model = 'gemini-2.0-flash-live-001';
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();
إرسال الرسائل النصية واستلامها
إليك كيفية إرسال الرسائل النصية واستلامها:
import asyncio
from google import genai
client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"
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())
import { GoogleGenAI, Modality } from '@google/genai';
const ai = new GoogleGenAI({ apiKey: "GOOGLE_API_KEY" });
const model = 'gemini-2.0-flash-live-001';
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 simple = 'Hello how are you?';
session.sendClientContent({ turns: simple });
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();
إرسال المحتوى الصوتي واستلامه
يمكنك إرسال الصوت من خلال تحويله إلى تنسيق PCM بسعة 16 بت ومعدل 16 كيلوهرتز وصوت أحادي. يقرأ المثال التالي ملف WAV ويرسله بالتنسيق الصحيح:
# 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(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"
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())
// 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({ apiKey: "GOOGLE_API_KEY" });
const model = 'gemini-2.0-flash-live-001';
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:
import asyncio
import wave
from google import genai
client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"
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 idx,response in async_enumerate(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())
import { GoogleGenAI, Modality } from '@google/genai';
const ai = new GoogleGenAI({ apiKey: "GOOGLE_API_KEY" });
const model = 'gemini-2.0-flash-live-001';
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 simple = 'Hello how are you?';
session.sendClientContent({ turns: simple });
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 بترميز little-endian وببتات 16. يستخدم إخراج الصوت دائمًا معدّل أخذ العينات 24 كيلوهرتز. يكون ملف الصوت المُدخل
بمعدل 16 كيلوهرتز تلقائيًا، ولكن ستعيد واجهة برمجة التطبيقات Live API تحليله إذا لزم الأمر
كي يتمكّن من إرسال أي معدل بيانات في الملف الصوتي. لنقل معدّل أخذ العينات للصوت الذي يتم إدخاله، اضبط
نوع MIME لكل Blob يحتوي على صوت على قيمة
مثل audio/pcm;rate=16000
.
تلقّي النصوص المُحوَّلة من مقاطع صوتية
يمكنك تفعيل ميزة تحويل الصوت إلى نص في إخراج الصوت من النموذج من خلال إرسال رمز
output_audio_transcription
في إعدادات الضبط. يتم تحديد لغة تحويل الصوت إلى نص
استنادًا إلى ردّ النموذج.
import asyncio
from google import genai
from google.genai import types
client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"
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())
يمكنك تفعيل ميزة تحويل الصوت إلى نص من خلال إرسال رمز
input_audio_transcription
في إعدادات الضبط.
import asyncio
from google import genai
from google.genai import types
client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"
config = {"response_modalities": ["TEXT"],
"realtime_input_config": {
"automatic_activity_detection": {"disabled": True},
"activity_handling": "NO_INTERRUPTION",
},
"input_audio_transcription": {},
}
async def main():
async with client.aio.live.connect(model=model, config=config) as session:
audio_data = Path("sample.pcm").read_bytes()
await session.send_realtime_input(activity_start=types.ActivityStart())
await session.send_realtime_input(
audio=types.Blob(data=audio_data, mime_type='audio/pcm;rate=16000')
)
await session.send_realtime_input(activity_end=types.ActivityEnd())
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())
بث الصوت والفيديو
تعليمات النظام
تتيح لك تعليمات النظام توجيه سلوك النموذج استنادًا إلى احتياجاتك وحالات الاستخدام المحدّدة. يمكن ضبط تعليمات النظام في إعدادات الإعداد وستظل سارية طوال الجلسة.
from google.genai import types
config = {
"system_instruction": types.Content(
parts=[
types.Part(
text="You are a helpful assistant and answer in a friendly tone."
)
]
),
"response_modalities": ["TEXT"],
}
تعديلات المحتوى المتزايدة
استخدِم التعديلات المتزايدة لإرسال الإدخال النصي أو إنشاء سياق الجلسة أو استعادة سياق الجلسة. بالنسبة إلى السياقات القصيرة، يمكنك إرسال تفاعلات تتعلّق بالاتّجاهات المتعلّقة بكل خطوة لتمثيل تسلسل الأحداث الدقيق:
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)
{
"clientContent": {
"turns": [
{
"parts":[
{
"text": ""
}
],
"role":"user"
},
{
"parts":[
{
"text": ""
}
],
"role":"model"
}
],
"turnComplete": true
}
}
بالنسبة إلى السياقات الأطول، ننصحك بتقديم ملخّص رسالة واحد لتفريغ فترة السياق للتفاعلات اللاحقة.
تغيير الصوت واللغة
تتيح واجهة برمجة التطبيقات Live API الأصوات التالية: Puck وCharon وKore وFenrir وAoede وLeda وOrus وZephyr.
لتحديد صوت، اضبط اسم الصوت ضمن عنصر speechConfig
كجزء
من إعدادات الجلسة:
from google.genai import types
config = types.LiveConnectConfig(
response_modalities=["AUDIO"],
speech_config=types.SpeechConfig(
voice_config=types.VoiceConfig(
prebuilt_voice_config=types.PrebuiltVoiceConfig(voice_name="Kore")
)
)
)
{
"voiceConfig": {
"prebuiltVoiceConfig": {
"voiceName": "Kore"
}
}
}
تتيح Live API لغات متعددة.
لتغيير اللغة، اضبط رمز اللغة ضمن عنصر speechConfig
كجزء من إعداد الجلسة:
from google.genai import types
config = types.LiveConnectConfig(
response_modalities=["AUDIO"],
speech_config=types.SpeechConfig(
language_code="de-DE",
)
)
استخدام الأداة مع Live API
يمكنك تحديد أدوات مثل طلب الدوالّ، تنفيذ الرموز البرمجية، وبحث Google باستخدام Live API.
استدعاء الدالة
يمكنك تحديد تعريفات الدوالّ كجزء من إعداد الجلسة. اطّلِع على الدليل التعليمي لاستدعاء الدوالّ لمعرفة المزيد من المعلومات.
بعد تلقّي طلبات الأداة، يجب أن يردّ العميل بقائمة بعناصر
FunctionResponse
باستخدام الطريقة session.send_tool_response
.
import asyncio
from google import genai
from google.genai import types
client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"
# Simple function definitions
turn_on_the_lights = {"name": "turn_on_the_lights"}
turn_off_the_lights = {"name": "turn_off_the_lights"}
tools = [{"function_declarations": [turn_on_the_lights, turn_off_the_lights]}]
config = {"response_modalities": ["TEXT"], "tools": tools}
async def main():
async with client.aio.live.connect(model=model, config=config) as session:
prompt = "Turn on the lights please"
await session.send_client_content(turns={"parts": [{"text": prompt}]})
async for chunk in session.receive():
if chunk.server_content:
if chunk.text is not None:
print(chunk.text)
elif chunk.tool_call:
function_responses = []
for fc in tool_call.function_calls:
function_response = types.FunctionResponse(
id=fc.id,
name=fc.name,
response={ "result": "ok" } # simple, hard-coded function response
)
function_responses.append(function_response)
await session.send_tool_response(function_responses=function_responses)
if __name__ == "__main__":
asyncio.run(main())
من طلب واحد، يمكن للنموذج إنشاء طلبات دالة متعددة والتعليمات البرمجية اللازمة لربط نواتج هذه الطلبات. يتم تنفيذ هذا الرمز البرمجي في بيئة تطوير اختباري ، ما يؤدي إلى إنشاء رسائل BidiGenerateContentToolCall لاحقة.
استدعاء الدوالّ غير المتزامنة
يتم تلقائيًا إيقاف التنفيذ مؤقتًا إلى أن تصبح نتائج كلّ معالجة للدالة متاحة، ما يضمن المعالجة التسلسلية. يعني ذلك أنّه لن تتمكّن من مواصلة التفاعل مع النموذج أثناء تنفيذ الدوالّ.
إذا كنت لا تريد حظر المحادثة، يمكنك توجيه النموذج إلى تنفيذ الدوالّ بشكل غير متزامن.
لإجراء ذلك، عليك أولاً إضافة behavior
إلى تعريفات الدوالّ:
# Non-blocking function definitions
turn_on_the_lights = {"name": "turn_on_the_lights", "behavior": "NON_BLOCKING"} # turn_on_the_lights will run asynchronously
turn_off_the_lights = {"name": "turn_off_the_lights"} # turn_off_the_lights will still pause all interactions with the model
سيضمن NON-BLOCKING
تشغيل الدالة بشكل غير متزامن بينما يمكنك
مواصلة التفاعل مع النموذج.
بعد ذلك، عليك إخبار النموذج بكيفية التصرف عند تلقّيه
FunctionResponse
باستخدام المَعلمة scheduling
. يمكن أن يكون:
- يمكنه إيقاف ما يفعله وإبلاغك بالردّ الذي تلقّاه على الفور
(
scheduling="INTERRUPT"
). - يُرجى الانتظار حتى ينتهي الجهاز من تنفيذ ما يفعله حاليًا
(
scheduling="WHEN_IDLE"
). - أو يمكنك عدم اتّخاذ أي إجراء واستخدام هذه المعلومات لاحقًا في المناقشة.
(
scheduling="SILENT"
)
# Non-blocking function definitions
function_response = types.FunctionResponse(
id=fc.id,
name=fc.name,
response={
"result": "ok",
"scheduling": "INTERRUPT" # Can also be WHEN_IDLE or SILENT
}
)
تنفيذ الرمز البرمجي
يمكنك تحديد تنفيذ الرمز البرمجي كجزء من إعدادات الجلسة. اطّلِع على الدليل التعليمي لتنفيذ الرموز البرمجية للتعرّف على مزيد من المعلومات.
import asyncio
from google import genai
from google.genai import types
client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"
tools = [{'code_execution': {}}]
config = {"response_modalities": ["TEXT"], "tools": tools}
async def main():
async with client.aio.live.connect(model=model, config=config) as session:
prompt = "Compute the largest prime palindrome under 100000."
await session.send_client_content(turns={"parts": [{"text": prompt}]})
async for chunk in session.receive():
if chunk.server_content:
if chunk.text is not None:
print(chunk.text)
model_turn = chunk.server_content.model_turn
if model_turn:
for part in model_turn.parts:
if part.executable_code is not None:
print(part.executable_code.code)
if part.code_execution_result is not None:
print(part.code_execution_result.output)
if __name__ == "__main__":
asyncio.run(main())
الاطّلاع على المعلومات الأساسية باستخدام "بحث Google"
يمكنك تفعيل ميزة "التأهّل" باستخدام "بحث Google" كجزء من إعدادات الجلسة. اطّلِع على الدليل التعليمي حول التأريض لمعرفة المزيد من المعلومات.
import asyncio
from google import genai
from google.genai import types
client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"
tools = [{'google_search': {}}]
config = {"response_modalities": ["TEXT"], "tools": tools}
async def main():
async with client.aio.live.connect(model=model, config=config) as session:
prompt = "When did the last Brazil vs. Argentina soccer match happen?"
await session.send_client_content(turns={"parts": [{"text": prompt}]})
async for chunk in session.receive():
if chunk.server_content:
if chunk.text is not None:
print(chunk.text)
# The model might generate and execute Python code to use Search
model_turn = chunk.server_content.model_turn
if model_turn:
for part in model_turn.parts:
if part.executable_code is not None:
print(part.executable_code.code)
if part.code_execution_result is not None:
print(part.code_execution_result.output)
if __name__ == "__main__":
asyncio.run(main())
الجمع بين عدة أدوات
يمكنك الجمع بين أدوات متعددة ضمن Live API:
prompt = """
Hey, I need you to do three things for me.
1. Compute the largest prime palindrome under 100000.
2. Then use Google Search to look up information about the largest earthquake in California the week of Dec 5 2024?
3. Turn on the lights
Thanks!
"""
tools = [
{"google_search": {}},
{"code_execution": {}},
{"function_declarations": [turn_on_the_lights, turn_off_the_lights]},
]
config = {"response_modalities": ["TEXT"], "tools": tools}
التعامل مع المقاطعات
يمكن للمستخدمين إيقاف إخراج النموذج في أي وقت. عندما يرصد نظام رصد أنشطة التعرّف على الصوت (VAD) انقطاعًا، يتم إلغاء عملية التعرّف الجارية ووضعها في المهملات. لا يتم الاحتفاظ في سجلّ الجلسات إلا بالمعلومات التي تم إرسالها إلى العميل من قبل. يُرسِل الخادم بعد ذلك رسالة BidiGenerateContentServerContent للإبلاغ عن انقطاع الاتصال.
بالإضافة إلى ذلك، يتخلّص خادم Gemini من أي طلبات وظائف في انتظار المراجعة ويُرسِل
رسالة BidiGenerateContentServerContent
تتضمّن أرقام تعريف المكالمات المُلغاة.
async for response in session.receive():
if response.server_content.interrupted is True:
# The generation was interrupted
ميزة "رصد النشاط الصوتي" (VAD)
يمكنك ضبط ميزة "اكتشاف النشاط الصوتي" (VAD) أو إيقافها.
استخدام ميزة "فصل الصوت عن المحتوى" التلقائية
بشكلٍ تلقائي، ينفِّذ النموذج ميزة "فصل الصوت عن المحتوى" على
بث إدخال صوتي متواصل. يمكن ضبط ميزة "توقُّف الصوت أثناء الصمت" باستخدام الحقل
realtimeInputConfig.automaticActivityDetection
إعدادات الضبط.
عند إيقاف بث الصوت مؤقتًا لأكثر من ثانية (على سبيل المثال،
بسبب إيقاف المستخدم للميكروفون)، يجب إرسال حدث
audioStreamEnd
لحذف أي صوت محفوظ مؤقتًا. يمكن للعميل استئناف إرسال data
الصوتية في أي وقت.
# 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(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"
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())
باستخدام send_realtime_input
، ستستجيب واجهة برمجة التطبيقات للصوت تلقائيًا استنادًا
إلى ميزة "تحديد مصدر الصوت". في حين أنّ send_client_content
تضيف الرسائل إلى سياق النموذج بترتيب معيّن، يتم تحسين send_realtime_input
لزيادة وقت الاستجابة على حساب
الترتيب الحتمي.
ضبط ميزة "تقسيم الصوت والضوضاء" التلقائية
لمزيد من التحكّم في نشاط ميزة "إلغاء الضوضاء"، يمكنك ضبط المَعلمات التالية: اطّلِع على مرجع واجهة برمجة التطبيقات للحصول على مزيد من المعلومات.
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,
}
}
}
إيقاف ميزة "توقُّف الصوت والصورة تلقائيًا"
بدلاً من ذلك، يمكن إيقاف ميزة "توقُّف الصوت التلقائي" من خلال ضبط realtimeInputConfig.automaticActivityDetection.disabled
على true
في رسالة الإعداد. في هذه الإعدادات، يكون العميل مسؤولاً عن رصد
حديث المستخدم وإرسال
رسائل activityStart
وactivityEnd
في الأوقات المناسبة. لا يتم إرسال audioStreamEnd
في
هذه الإعدادات. بدلاً من ذلك، يتم وضع علامة على أي انقطاع في البث باستخدام
رسالة activityEnd
.
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())
# ...
عدد الرموز المميّزة
يمكنك العثور على إجمالي عدد الرموز المستهلكة في الحقل usageMetadata في رسالة الخادم المعروضة.
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}")
تمديد مدة الجلسة
يمكن تمديد الحد الأقصى لمدة الجلسة إلى غير محدود باستخدام آليتين:
بالإضافة إلى ذلك، ستتلقّى رسالة GoAway قبل انتهاء الجلسة، ما يتيح لك اتّخاذ المزيد من الإجراءات.
ضغط قدرة الاستيعاب
لتفعيل جلسات أطول وتجنُّب إنهاء الاتصال بشكل مفاجئ، يمكنك تفعيل ضغط نافذة السياق من خلال ضبط الحقل contextWindowCompression كجزء من إعدادات الجلسة.
في ContextWindowCompressionConfig، يمكنك ضبط آلية النافذة المتحركة وعدد الرموز المميّزة التي تؤدي إلى بدء الضغط.
from google.genai import types
config = types.LiveConnectConfig(
response_modalities=["AUDIO"],
context_window_compression=(
# Configures compression with default parameters.
types.ContextWindowCompressionConfig(
sliding_window=types.SlidingWindow(),
)
),
)
استئناف الجلسة
لمنع إنهاء الجلسة عندما يعيد الخادم ضبط اتصال WebSocket بشكل دوري، عليك ضبط الحقل sessionResumption ضمن إعدادات الإعداد.
يؤدي ضبط هذا الإعداد إلى إرسال
الرسائل SessionResumptionUpdate
من الخادم، والتي يمكن استخدامها لاستئناف الجلسة من خلال تمرير رمز التمكين
لاستئناف الجلسة الأخير على أنّه SessionResumptionConfig.handle
للاتصال اللاحق.
import asyncio
from google import genai
from google.genai import types
client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"
async def main():
print(f"Connecting to the service with handle {previous_session_handle}...")
async with client.aio.live.connect(
model=model,
config=types.LiveConnectConfig(
response_modalities=["AUDIO"],
session_resumption=types.SessionResumptionConfig(
# The handle of the session to resume is passed here,
# or else None to start a new session.
handle=previous_session_handle
),
),
) as session:
while True:
await session.send_client_content(
turns=types.Content(
role="user", parts=[types.Part(text="Hello world!")]
)
)
async for message in session.receive():
# Periodically, the server will send update messages that may
# contain a handle for the current state of the session.
if message.session_resumption_update:
update = message.session_resumption_update
if update.resumable and update.new_handle:
# The handle should be retained and linked to the session.
return update.new_handle
# For the purposes of this example, placeholder input is continually fed
# to the model. In non-sample code, the model inputs would come from
# the user.
if message.server_content and message.server_content.turn_complete:
break
if __name__ == "__main__":
asyncio.run(main())
تلقّي رسالة قبل انقطاع الاتصال بالجلسة
يُرسِل الخادم رسالة GoAway التي تشير إلى أنّه سيتم قريبًا إنهاء الربط الحالي. تتضمّن هذه الرسالة timeLeft، التي تشير إلى الوقت المتبقّي وتتيح لك اتّخاذ إجراء آخر قبل إنهاء الاتصال على أنّه تم إلغاؤه.
async for response in session.receive():
if response.go_away is not None:
# The connection will soon be terminated
print(response.go_away.time_left)
تلقّي رسالة عند اكتمال عملية الإنشاء
يُرسِل الخادم رسالة generationComplete تشير إلى أنّ النموذج قد انتهى من إنشاء الاستجابة.
async for response in session.receive():
if response.server_content.generation_complete is True:
# The generation is complete
درجة دقة الوسائط
يمكنك تحديد درجة دقة الوسائط لوسائط الإدخال من خلال ضبط الحقل
mediaResolution
كجزء من إعدادات الجلسة:
from google.genai import types
config = types.LiveConnectConfig(
response_modalities=["AUDIO"],
media_resolution=types.MediaResolution.MEDIA_RESOLUTION_LOW,
)
القيود
ضَع في الاعتبار القيود التالية لواجهة برمجة التطبيقات Live API عند التخطيط لمشروعك.
طرق الردّ
يمكنك ضبط طريقة استجابة واحدة فقط (TEXT
أو AUDIO
) لكل جلسة في
إعدادات الجلسة. يؤدي ضبط كليهما إلى ظهور رسالة خطأ في الإعداد. ويعني ذلك
أنّه يمكنك ضبط النموذج للردّ إما بالنص أو بالصوت،
ولكن ليس كليهما في الجلسة نفسها.
مصادقة العميل
لا توفّر Live API سوى مصادقة بين الخوادم ولا يُنصح باستخدامها مباشرةً من قِبل العميل. يجب توجيه إدخال العميل من خلال خادم تطبيق وسيط للمصادقة الآمنة باستخدام واجهة برمجة التطبيقات Live API.
مدة الجلسة
يمكن تمديد مدة الجلسة إلى أجل غير مسمى من خلال تفعيل ضغط الجلسة. بدون الضغط، تقتصر جلسات الصوت فقط على 15 دقيقة، وتقتصر جلسات الصوت والفيديو على دقيقتين. سيؤدي تجاوز هذه الحدود بدون ضغط إلى إنهاء الاتصال.
بالإضافة إلى ذلك، يمكنك ضبط استئناف الجلسة لسماح العميل باستئناف جلسة تم إنهاؤها.
قدرة الاستيعاب
تبلغ قدرة استيعاب الجلسة 32 ألف رمز مميّز.
اللغات المتاحة
تتوفّر Live API باللغات التالية.
اللغة | رمز 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 |
المالايالامية (الهند) | ml-IN |
الماراثية (الهند) | mr-IN |
التاميلية (الهند) | ta-IN |
التيلوغوية (الهند) | te-IN |
الهولندية (هولندا) | nl-NL |
الكورية (كوريا الجنوبية) | ko-KR |
الماندرين الصينية (الصين) | cmn-CN |
البولندية (بولندا) | pl-PL |
الروسية (روسيا) | ru-RU |
التايلاندية (تايلاند) | th-TH |
عمليات الدمج مع منتجات تابعة لجهات خارجية
بالنسبة إلى عمليات نشر تطبيقات الويب والتطبيقات المتوافقة مع الأجهزة الجوّالة، يمكنك استكشاف الخيارات من:
الخطوات التالية
- تنفيذ عملية التواصل بين العميل والخادم باستخدام الرموز المميّزة المؤقتة
- جرِّب Live API في Google AI Studio.
- لمزيد من المعلومات حول نموذج Gemini 2.0 Flash Live، يُرجى الاطّلاع على صفحة النموذج.
- يمكنك تجربة المزيد من الأمثلة في كتاب Live API cookbook، وكتاب Live API Tools cookbook، والنص البرمجي Live API Get Started script.