השימוש בכלים מאפשר ל-Live API להרחיב את היכולות שלו מעבר לשיחות, ולבצע פעולות בעולם האמיתי ולשלב הקשר חיצוני תוך שמירה על חיבור בזמן אמת. אפשר להגדיר כלים כמו קריאה לפונקציה, הרצת קוד וחיפוש Google באמצעות ה-API בזמן אמת.
סקירה כללית על הכלים הנתמכים
לפניכם סקירה כללית קצרה של הכלים הזמינים לכל מודל:
כלי | מודלים מדורגיםgemini-live-2.5-flash-preview gemini-2.0-flash-live-001 |
gemini-2.5-flash-preview-native-audio-dialog |
gemini-2.5-flash-exp-native-audio-thinking-dialog |
---|---|---|---|
חיפוש | כן | כן | כן |
קריאה לפונקציה | כן | כן | לא |
ביצוע קוד | כן | לא | לא |
הקשר של כתובת ה-URL | כן | לא | לא |
קריאה לפונקציה
Live API תומך בקריאות לפונקציות, בדיוק כמו בקשות רגילות ליצירת תוכן. קריאה לפונקציות מאפשרת ל-Live API לקיים אינטראקציה עם נתונים ותוכניות חיצוניים, וכך להרחיב את היכולות של האפליקציות.
אפשר להגדיר הצהרות על פונקציות כחלק מהגדרת הסשן.
אחרי קבלת קריאות לכלי, הלקוח צריך להשיב עם רשימה של אובייקטים מסוג FunctionResponse
באמצעות השיטה session.send_tool_response
.
למידע נוסף, קראו את המדריך בנושא קריאה לפונקציות.
Python
import asyncio
from google import genai
from google.genai import types
client = genai.Client()
model = "gemini-live-2.5-flash-preview"
# 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 chunk.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())
JavaScript
import { GoogleGenAI, Modality } from '@google/genai';
const ai = new GoogleGenAI({});
const model = 'gemini-live-2.5-flash-preview';
// Simple function definitions
const turn_on_the_lights = { name: "turn_on_the_lights" } // , description: '...', parameters: { ... }
const turn_off_the_lights = { name: "turn_off_the_lights" }
const tools = [{ functionDeclarations: [turn_on_the_lights, turn_off_the_lights] }]
const config = {
responseModalities: [Modality.TEXT],
tools: tools
}
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;
} else if (message.toolCall) {
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 = 'Turn on the lights please';
session.sendClientContent({ turns: inputTurns });
let turns = await handleTurn();
for (const turn of turns) {
if (turn.serverContent && turn.serverContent.modelTurn && turn.serverContent.modelTurn.parts) {
for (const part of turn.serverContent.modelTurn.parts) {
if (part.text) {
console.debug('Received text: %s\n', part.text);
}
}
}
else if (turn.toolCall) {
const functionResponses = [];
for (const fc of turn.toolCall.functionCalls) {
functionResponses.push({
id: fc.id,
name: fc.name,
response: { result: "ok" } // simple, hard-coded function response
});
}
console.debug('Sending tool response...\n');
session.sendToolResponse({ functionResponses: functionResponses });
}
}
// Check again for new messages
turns = await handleTurn();
for (const turn of turns) {
if (turn.serverContent && turn.serverContent.modelTurn && turn.serverContent.modelTurn.parts) {
for (const part of turn.serverContent.modelTurn.parts) {
if (part.text) {
console.debug('Received text: %s\n', part.text);
}
}
}
}
session.close();
}
async function main() {
await live().catch((e) => console.error('got error', e));
}
main();
מהנחיה אחת, המודל יכול ליצור כמה קריאות לפונקציות ואת הקוד הנדרש כדי לשרשר את הפלט שלהן. הקוד הזה מופעל בסביבת חול, ויוצר הודעות BidiGenerateContentToolCall.
קריאה אסינכרונית לפונקציות
קריאת פונקציות מתבצעת ברצף כברירת מחדל, כלומר הביצועים מושהים עד שהתוצאות של כל קריאת פונקציה יהיו זמינות. כך מובטח עיבוד רציף, כלומר לא תוכלו להמשיך את האינטראקציה עם המודל בזמן שהפונקציות פועלות.
אם אתם לא רוצים לחסום את השיחה, תוכלו להורות למודל להריץ את הפונקציות באופן אסינכרוני. כדי לעשות זאת, קודם צריך להוסיף behavior
להגדרות הפונקציות:
Python
# 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
JavaScript
import { GoogleGenAI, Modality, Behavior } from '@google/genai';
// Non-blocking function definitions
const turn_on_the_lights = {name: "turn_on_the_lights", behavior: Behavior.NON_BLOCKING}
// Blocking function definitions
const turn_off_the_lights = {name: "turn_off_the_lights"}
const tools = [{ functionDeclarations: [turn_on_the_lights, turn_off_the_lights] }]
NON-BLOCKING
מוודא שהפונקציה פועלת באופן אסינכרוני בזמן שאתם יכולים להמשיך לבצע פעולות במודל.
לאחר מכן, צריך להגדיר את התנהגות המודל כשהוא מקבל את הערך FunctionResponse
באמצעות הפרמטר scheduling
. יכול:
- להפריע למה שהוא עושה ולעדכן אתכם מיד בתגובה שהוא קיבל (
scheduling="INTERRUPT"
), - ממתינים עד שהפעולה הנוכחית תסתיים (
scheduling="WHEN_IDLE"
), או לא לעשות דבר ולהשתמש בידע הזה בהמשך הדיון (
scheduling="SILENT"
)
Python
# for a non-blocking function definition, apply scheduling in the function response:
function_response = types.FunctionResponse(
id=fc.id,
name=fc.name,
response={
"result": "ok",
"scheduling": "INTERRUPT" # Can also be WHEN_IDLE or SILENT
}
)
JavaScript
import { GoogleGenAI, Modality, Behavior, FunctionResponseScheduling } from '@google/genai';
// for a non-blocking function definition, apply scheduling in the function response:
const functionResponse = {
id: fc.id,
name: fc.name,
response: {
result: "ok",
scheduling: FunctionResponseScheduling.INTERRUPT // Can also be WHEN_IDLE or SILENT
}
}
ביצוע קוד
אפשר להגדיר את ביצוע הקוד כחלק מהגדרת הסשן. כך ה-Live API יכול ליצור ולבצע קוד Python ולבצע חישובים באופן דינמי כדי לשפר את התוצאות. מידע נוסף זמין במדריך לביצוע קוד.
Python
import asyncio
from google import genai
from google.genai import types
client = genai.Client()
model = "gemini-live-2.5-flash-preview"
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())
JavaScript
import { GoogleGenAI, Modality } from '@google/genai';
const ai = new GoogleGenAI({});
const model = 'gemini-live-2.5-flash-preview';
const tools = [{codeExecution: {}}]
const config = {
responseModalities: [Modality.TEXT],
tools: tools
}
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;
} else if (message.toolCall) {
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 = 'Compute the largest prime palindrome under 100000.';
session.sendClientContent({ turns: inputTurns });
const turns = await handleTurn();
for (const turn of turns) {
if (turn.serverContent && turn.serverContent.modelTurn && turn.serverContent.modelTurn.parts) {
for (const part of turn.serverContent.modelTurn.parts) {
if (part.text) {
console.debug('Received text: %s\n', part.text);
}
else if (part.executableCode) {
console.debug('executableCode: %s\n', part.executableCode.code);
}
else if (part.codeExecutionResult) {
console.debug('codeExecutionResult: %s\n', part.codeExecutionResult.output);
}
}
}
}
session.close();
}
async function main() {
await live().catch((e) => console.error('got error', e));
}
main();
חיפוש עם עיגון בנתונים
אפשר להפעיל את התכונה 'התמקדות' באמצעות חיפוש Google כחלק מהגדרת הסשן. כך אפשר לשפר את הדיוק של Live API ולמנוע הזיות. למידע נוסף, אפשר לעיין במדריך לגבי יצירת קשר עם האדמה.
Python
import asyncio
from google import genai
from google.genai import types
client = genai.Client()
model = "gemini-live-2.5-flash-preview"
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())
JavaScript
import { GoogleGenAI, Modality } from '@google/genai';
const ai = new GoogleGenAI({});
const model = 'gemini-live-2.5-flash-preview';
const tools = [{googleSearch: {}}]
const config = {
responseModalities: [Modality.TEXT],
tools: tools
}
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;
} else if (message.toolCall) {
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 = 'When did the last Brazil vs. Argentina soccer match happen?';
session.sendClientContent({ turns: inputTurns });
const turns = await handleTurn();
for (const turn of turns) {
if (turn.serverContent && turn.serverContent.modelTurn && turn.serverContent.modelTurn.parts) {
for (const part of turn.serverContent.modelTurn.parts) {
if (part.text) {
console.debug('Received text: %s\n', part.text);
}
else if (part.executableCode) {
console.debug('executableCode: %s\n', part.executableCode.code);
}
else if (part.codeExecutionResult) {
console.debug('codeExecutionResult: %s\n', part.codeExecutionResult.output);
}
}
}
}
session.close();
}
async function main() {
await live().catch((e) => console.error('got error', e));
}
main();
שילוב של כמה כלים
אתם יכולים לשלב כמה כלים ב-Live API כדי להרחיב עוד יותר את היכולות של האפליקציה:
Python
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}
# ... remaining model call
JavaScript
const 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!
`
const tools = [
{ googleSearch: {} },
{ codeExecution: {} },
{ functionDeclarations: [turn_on_the_lights, turn_off_the_lights] }
]
const config = {
responseModalities: [Modality.TEXT],
tools: tools
}
// ... remaining model call
המאמרים הבאים
- דוגמאות נוספות לשימוש בכלים עם Live API מפורטות בספר המתכונים לשימוש בכלים.
- במדריך ליכולות של Live API מוסבר בהרחבה על התכונות וההגדרות.