تتيح لك طلبات البيانات ربط النماذج بالأدوات وواجهات برمجة التطبيقات الخارجية. بدلاً من إنشاء ردود نصية، يفهم النموذج الحالات التي يجب فيها استدعاء وظائف معيّنة ويقدّم المَعلمات اللازمة لتنفيذ الإجراءات في الواقع. ويسمح ذلك للنموذج بالعمل كجسر بين اللغة الطبيعية والواقع المتمثل في الإجراءات والبيانات. هناك 3 حالات استخدام أساسية لاستدعاء الدوالّ:
- تعزيز المعرفة: يمكنك الوصول إلى المعلومات من مصادر خارجية، مثل قواعد البيانات وواجهات برمجة التطبيقات وقواعد المعلومات.
- توسيع الإمكانات: يمكنك استخدام أدوات خارجية لإجراء العمليات الحسابية وتوسيع حدود النموذج، مثل استخدام آلة حاسبة أو إنشاء الرسوم البيانية.
- اتّخاذ الإجراءات: التفاعل مع الأنظمة الخارجية باستخدام واجهات برمجة التطبيقات، مثل تحديد المواعيد أو إنشاء الفواتير أو إرسال الرسائل الإلكترونية أو التحكّم في الأجهزة المنزلية الذكية
آلية عمل "استدعاء الدوالّ البرمجية"
يتضمن استدعاء الدوالّ تفاعلاً منظَّمًا بين تطبيقك وال نموذج والدوالّ الخارجية. في ما يلي تفاصيل العملية:
- تحديد بيان الدالة: حدِّد بيان الدالة في رمز تطبيقك. تصف تعريفات الدوالّ اسم الدالة ومعلماتها والغرض منها للنموذج.
- استدعاء نموذج اللغة المحوسبة الطويلة باستخدام تعريفات الدوالّ: أرسِل طلب المستخدم مع تعريفات الدوالّ إلى النموذج. ويحلل الطلب ويحدّد ما إذا كان من المفيد استدعاء دالة. إذا كان الأمر كذلك، يتم الردّ باستخدام عنصر JSON منظَّم.
- رمز تنفيذ الدالة (مسؤوليتك): لا
ينفّذ النموذج الدالة نفسها. تقع على عاتق تطبيقك مهمة
معالجة الردّ والتحقّق من طلب الوظيفة، إذا كان
- نعم: استخرِج اسم الدالة ومَعلماتها ونفِّذ الدالة المقابلة في تطبيقك.
- لا: قدّم النموذج ردًا نصيًا مباشرًا على الطلب (لا يتم التركيز على هذه العملية كثيرًا في المثال، ولكنّها نتيجة محتملة).
- إنشاء ردّ سهل على المستخدم: في حال تنفيذ وظيفة، سجِّل النتيجة وأرسِلها مرة أخرى إلى النموذج في جولة لاحقة من المحادثة. سيستخدم النتيجة لإنشاء ردّ نهائي سهل الاستخدام يتضمّن المعلومات الواردة من طلب الدالة.
يمكن تكرار هذه العملية على مدار عدة دورات، ما يتيح استخدام عمليات تفاعُل وسير عمل معقّدة. يتيح النموذج أيضًا استدعاء دوال متعددة في خطوة واحدة (استدعاء الدوال المشترَكة) وبترتيب (استدعاء الدوال التركيبية).
الخطوة 1: تحديد بيان الدالة
حدِّد دالة وبيانًا لها في رمز تطبيقك يتيح للمستخدمين ضبط قيم الإضاءة وتقديم طلب لواجهة برمجة التطبيقات. يمكن أن تستدعي هذه الدالة خدمات خارجية أو واجهات برمجة تطبيقات.
Python
from google.genai import types
# Define a function that the model can call to control smart lights
set_light_values_declaration = {
"name": "set_light_values",
"description": "Sets the brightness and color temperature of a light.",
"parameters": {
"type": "object",
"properties": {
"brightness": {
"type": "integer",
"description": "Light level from 0 to 100. Zero is off and 100 is full brightness",
},
"color_temp": {
"type": "string",
"enum": ["daylight", "cool", "warm"],
"description": "Color temperature of the light fixture, which can be `daylight`, `cool` or `warm`.",
},
},
"required": ["brightness", "color_temp"],
},
}
# This is the actual function that would be called based on the model's suggestion
def set_light_values(brightness: int, color_temp: str) -> dict[str, int | str]:
"""Set the brightness and color temperature of a room light. (mock API).
Args:
brightness: Light level from 0 to 100. Zero is off and 100 is full brightness
color_temp: Color temperature of the light fixture, which can be `daylight`, `cool` or `warm`.
Returns:
A dictionary containing the set brightness and color temperature.
"""
return {"brightness": brightness, "colorTemperature": color_temp}
JavaScript
import { Type } from '@google/genai';
// Define a function that the model can call to control smart lights
const setLightValuesFunctionDeclaration = {
name: 'set_light_values',
description: 'Sets the brightness and color temperature of a light.',
parameters: {
type: Type.OBJECT,
properties: {
brightness: {
type: Type.NUMBER,
description: 'Light level from 0 to 100. Zero is off and 100 is full brightness',
},
color_temp: {
type: Type.STRING,
enum: ['daylight', 'cool', 'warm'],
description: 'Color temperature of the light fixture, which can be `daylight`, `cool` or `warm`.',
},
},
required: ['brightness', 'color_temp'],
},
};
/**
* Set the brightness and color temperature of a room light. (mock API)
* @param {number} brightness - Light level from 0 to 100. Zero is off and 100 is full brightness
* @param {string} color_temp - Color temperature of the light fixture, which can be `daylight`, `cool` or `warm`.
* @return {Object} A dictionary containing the set brightness and color temperature.
*/
function setLightValues(brightness, color_temp) {
return {
brightness: brightness,
colorTemperature: color_temp
};
}
الخطوة 2: استدعاء النموذج باستخدام تعريفات الدوالّ
بعد تعريف تعريفات الدوالّ، يمكنك توجيه النموذج إلى استخدام الدالة. ويحلل الطلب وإعلانات الدوال ويقرر الردّ مباشرةً أو استدعاء دالة. في حال استدعاء دالة، سيحتوي عنصر الردّ على اقتراح لاستدعاء الدالة.
Python
from google import genai
# Generation Config with Function Declaration
tools = types.Tool(function_declarations=[set_light_values_declaration])
config = types.GenerateContentConfig(tools=[tools])
# Configure the client
client = genai.Client(api_key=os.getenv("GEMINI_API_KEY"))
# Define user prompt
contents = [
types.Content(
role="user", parts=[types.Part(text="Turn the lights down to a romantic level")]
)
]
# Send request with function declarations
response = client.models.generate_content(
model="gemini-2.0-flash", config=config, contents=contents
)
print(response.candidates[0].content.parts[0].function_call)
JavaScript
import { GoogleGenAI } from '@google/genai';
// Generation Config with Function Declaration
const config = {
tools: [{
functionDeclarations: [setLightValuesFunctionDeclaration]
}]
};
// Configure the client
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
// Define user prompt
const contents = [
{
role: 'user',
parts: [{ text: 'Turn the lights down to a romantic level' }]
}
];
// Send request with function declarations
const response = await ai.models.generateContent({
model: 'gemini-2.0-flash',
contents: contents,
config: config
});
console.log(response.functionCalls[0]);
بعد ذلك، يعرض النموذج عنصر functionCall
في مخطّط متوافق مع OpenAPI
يحدّد كيفية استدعاء دالة واحدة أو أكثر من الدوالّ المعلَن عنها للردّ
على سؤال المستخدم.
Python
id=None args={'color_temp': 'warm', 'brightness': 25} name='set_light_values'
JavaScript
{
name: 'set_light_values',
args: { brightness: 25, color_temp: 'warm' }
}
الخطوة 3: تنفيذ رمز الدالة set_light_values
استخرِج تفاصيل طلب استدعاء الدالة من ردّ النموذج، وحلِّل المَعلمات
، ونفِّذ دالة set_light_values
في الرمز البرمجي.
Python
# Extract tool call details, it may not be in the first part.
tool_call = response.candidates[0].content.parts[0].function_call
if tool_call.name == "set_light_values":
result = set_light_values(**tool_call.args)
print(f"Function execution result: {result}")
JavaScript
// Extract tool call details
const tool_call = response.functionCalls[0]
let result;
if (tool_call.name === 'set_light_values') {
result = setLightValues(tool_call.args.brightness, tool_call.args.color_temp);
console.log(`Function execution result: ${JSON.stringify(result)}`);
}
الخطوة 4: إنشاء ردّ سهل على المستخدم مع نتيجة الدالة واستدعاء النموذج مرة أخرى
أخيرًا، أرسِل نتيجة تنفيذ الدالة إلى النموذج لكي يتمكّن من دمج هذه المعلومات في ردّه النهائي على المستخدم.
Python
# Create a function response part
function_response_part = types.Part.from_function_response(
name=tool_call.name,
response={"result": result},
)
# Append function call and result of the function execution to contents
contents.append(response.candidates[0].content) # Append the content from the model's response.
contents.append(types.Content(role="user", parts=[function_response_part])) # Append the function response
final_response = client.models.generate_content(
model="gemini-2.0-flash",
config=config,
contents=contents,
)
print(final_response.text)
JavaScript
// Create a function response part
const function_response_part = {
name: tool_call.name,
response: { result }
}
// Append function call and result of the function execution to contents
contents.push(response.candidates[0].content);
contents.push({ role: 'user', parts: [{ functionResponse: function_response_part }] });
// Get the final response from the model
const final_response = await ai.models.generateContent({
model: 'gemini-2.0-flash',
contents: contents,
config: config
});
console.log(final_response.text);
وبذلك، تكتمل عملية استدعاء الدالة. استخدم النموذج الدالة
set_light_values
بنجاح لتنفيذ إجراء الطلب الذي قدّمه المستخدم.
تعريفات الدوالّ
عند تنفيذ طلب استدعاء دالة في طلب، يتم إنشاء عنصر tools
،
الذي يحتوي على function declarations
واحدة أو أكثر. يمكنك تحديد الدوالّ باستخدام ملف برمجي بتنسيق JSON، وتحديدًا باستخدام مجموعة ملف برمجي محدودة من تنسيق مخطّط
OpenAPI. يمكن أن يتضمّن بيان دالة واحدة
المَعلمات التالية:
-
name
(سلسلة): اسم فريد للدالة (get_weather_forecast
،send_email
). استخدِم أسماء وصفية بدون مسافات أو أحرف خاصة (استخدِم الخطوط السفلية أو أسلوب camelCase). -
description
(سلسلة): شرح واضح ومفصّل لهدف الدالة وإمكاناتها وهذا أمر مهم لكي يفهم النموذج متى يجب استخدام الدالة. يجب أن تكون دقيقًا وأن تقدّم أمثلة إذا كان ذلك مفيدًا ("يبحث عن دور السينما استنادًا إلى الموقع الجغرافي وعنوان الفيلم الذي يتم عرضه حاليًا في دور السينما، إن أمكن"). parameters
(كائن): يحدِّد مَعلمات الإدخال التي تتوقّعها الدالة.-
type
(سلسلة): لتحديد نوع البيانات العام، مثلobject
-
properties
(عنصر): يسرد المَعلمات الفردية، وكل منها يتضمّن ما يلي:-
type
(سلسلة): نوع بيانات المَعلمة، مثلstring
integer
boolean, array
-
description
(سلسلة): وصف لغرض المَعلمة و تنسيقها تقديم أمثلة والقيود ("المدينة والولاية، على سبيل المثال، "القاهرة، مصر" أو رمز بريدي، مثلاً '95616'."). -
enum
(مصفوفة، اختيارية): إذا كانت قيم المَعلمة من مجموعة ثابتة، استخدِم "enum" لسرد القيم المسموح بها بدلاً من وصفها في الوصف فقط. ويؤدي ذلك إلى تحسين الدقة ("enum": ["daylight", "cool", "warm"]).
-
required
(مصفوفة): مصفوفة من السلاسل التي تسرد أسماء المَعلمات التي تكون إلزامية لكي تعمل الدالة
-
استدعاء الدوالّ بشكل موازٍ
بالإضافة إلى استدعاء دالة واحدة في كل مرة، يمكنك أيضًا استدعاء عدة وظائف في آنٍ واحد. يتيح لك استدعاء الدوالّ بشكل موازٍ تنفيذ دوالّ متعددة في آنٍ واحد، ويتم استخدامه عندما لا تكون الدوالّ تعتمد على بعضها. يكون ذلك مفعّلاً في سيناريوهات مثل جمع البيانات من مصادر مستقلة متعددة، مثل استرداد تفاصيل العملاء من قواعد بيانات مختلفة أو التحقّق من مستويات المستودع في مستودعات مختلفة أو تنفيذ إجراءات متعددة مثل تحويل شقتك إلى ديسكو.
Python
power_disco_ball = {
"name": "power_disco_ball",
"description": "Powers the spinning disco ball.",
"parameters": {
"type": "object",
"properties": {
"power": {
"type": "boolean",
"description": "Whether to turn the disco ball on or off.",
}
},
"required": ["power"],
},
}
start_music = {
"name": "start_music",
"description": "Play some music matching the specified parameters.",
"parameters": {
"type": "object",
"properties": {
"energetic": {
"type": "boolean",
"description": "Whether the music is energetic or not.",
},
"loud": {
"type": "boolean",
"description": "Whether the music is loud or not.",
},
},
"required": ["energetic", "loud"],
},
}
dim_lights = {
"name": "dim_lights",
"description": "Dim the lights.",
"parameters": {
"type": "object",
"properties": {
"brightness": {
"type": "number",
"description": "The brightness of the lights, 0.0 is off, 1.0 is full.",
}
},
"required": ["brightness"],
},
}
JavaScript
import { Type } from '@google/genai';
const powerDiscoBall = {
name: 'power_disco_ball',
description: 'Powers the spinning disco ball.',
parameters: {
type: Type.OBJECT,
properties: {
power: {
type: Type.BOOLEAN,
description: 'Whether to turn the disco ball on or off.'
}
},
required: ['power']
}
};
const startMusic = {
name: 'start_music',
description: 'Play some music matching the specified parameters.',
parameters: {
type: Type.OBJECT,
properties: {
energetic: {
type: Type.BOOLEAN,
description: 'Whether the music is energetic or not.'
},
loud: {
type: Type.BOOLEAN,
description: 'Whether the music is loud or not.'
}
},
required: ['energetic', 'loud']
}
};
const dimLights = {
name: 'dim_lights',
description: 'Dim the lights.',
parameters: {
type: Type.OBJECT,
properties: {
brightness: {
type: Type.NUMBER,
description: 'The brightness of the lights, 0.0 is off, 1.0 is full.'
}
},
required: ['brightness']
}
};
استدعاء النموذج باستخدام تعليمات يمكنها استخدام جميع الأدوات المحدّدة
يستخدم هذا المثال tool_config
. لمزيد من المعلومات، يمكنك الاطّلاع على مقالة ضبط
طلبات استدعاء الدوال.
Python
from google import genai
from google.genai import types
# Set up function declarations
house_tools = [
types.Tool(function_declarations=[power_disco_ball, start_music, dim_lights])
]
config = {
"tools": house_tools,
"automatic_function_calling": {"disable": True},
# Force the model to call 'any' function, instead of chatting.
"tool_config": {"function_calling_config": {"mode": "any"}},
}
# Configure the client
client = genai.Client(api_key=os.getenv("GEMINI_API_KEY"))
chat = client.chats.create(model="gemini-2.0-flash", config=config)
response = chat.send_message("Turn this place into a party!")
# Print out each of the function calls requested from this single call
print("Example 1: Forced function calling")
for fn in response.function_calls:
args = ", ".join(f"{key}={val}" for key, val in fn.args.items())
print(f"{fn.name}({args})")
JavaScript
import { GoogleGenAI } from '@google/genai';
// Set up function declarations
const houseFns = [powerDiscoBall, startMusic, dimLights];
const config = {
tools: [{
functionDeclarations: houseFns
}],
// Force the model to call 'any' function, instead of chatting.
toolConfig: {
functionCallingConfig: {
mode: 'any'
}
}
};
// Configure the client
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
// Create a chat session
const chat = ai.chats.create({
model: 'gemini-2.0-flash',
config: config
});
const response = await chat.sendMessage({message: 'Turn this place into a party!'});
// Print out each of the function calls requested from this single call
console.log("Example 1: Forced function calling");
for (const fn of response.functionCalls) {
const args = Object.entries(fn.args)
.map(([key, val]) => `${key}=${val}`)
.join(', ');
console.log(`${fn.name}(${args})`);
}
تعكس كل نتيجة من النتائج المطبوعة طلبًا واحدًا للدالة قد طلبة النموذج. لإرسال النتائج مرة أخرى، يجب تضمين الردود بالترتيب نفسه الذي تم طلبه.
تتيح حزمة تطوير البرامج (SDK) لـ Python ميزة تُعرف باسم استدعاء الدوال تلقائيًا التي تحوّل دالة Python إلى بيانات تعريف، وتتعامل مع تنفيذ استدعاء الدالة ودورة الاستجابة نيابةً عنك. في ما يلي مثال على حالة استخدام ميزة "عدم الظهور".
Python
from google import genai
from google.genai import types
# Actual implementation functions
def power_disco_ball_impl(power: bool) -> dict:
"""Powers the spinning disco ball.
Args:
power: Whether to turn the disco ball on or off.
Returns:
A status dictionary indicating the current state.
"""
return {"status": f"Disco ball powered {'on' if power else 'off'}"}
def start_music_impl(energetic: bool, loud: bool) -> dict:
"""Play some music matching the specified parameters.
Args:
energetic: Whether the music is energetic or not.
loud: Whether the music is loud or not.
Returns:
A dictionary containing the music settings.
"""
music_type = "energetic" if energetic else "chill"
volume = "loud" if loud else "quiet"
return {"music_type": music_type, "volume": volume}
def dim_lights_impl(brightness: float) -> dict:
"""Dim the lights.
Args:
brightness: The brightness of the lights, 0.0 is off, 1.0 is full.
Returns:
A dictionary containing the new brightness setting.
"""
return {"brightness": brightness}
config = {
"tools": [power_disco_ball_impl, start_music_impl, dim_lights_impl],
}
chat = client.chats.create(model="gemini-2.0-flash", config=config)
response = chat.send_message("Do everything you need to this place into party!")
print("\nExample 2: Automatic function calling")
print(response.text)
# I've turned on the disco ball, started playing loud and energetic music, and dimmed the lights to 50% brightness. Let's get this party started!
استدعاء الدوالّ التركيبية
يتيح استدعاء الدوالّ التركيبية أو التسلسلية لتطبيق Gemini تسلسل عدة
طلبات للدوالّ معًا من أجل تنفيذ طلب معقّد. على سبيل المثال، للإجابة عن سؤال "معرفة درجة الحرارة في موقعي الجغرافي الحالي"، قد تستدعي Gemini API أولاً دالة get_current_location()
متبوعة دالّة get_weather()
تأخذ الموقع الجغرافي كمَعلمة.
يوضّح المثال التالي كيفية تنفيذ اتّباع الدوال المركبة باستخدام حزمة تطوير البرامج (SDK) لـ Python واتّباع الدوال التلقائية.
Python
يستخدم هذا المثال ميزة استدعاء الدوالّ التلقائية في
google-genai
حزمة تطوير البرامج (SDK) لـ Python. تحوِّل حزمة تطوير البرامج (SDK) تلقائيًا دوالّ Python
إلى المخطّط المطلوب، وتنفِّذ طلبات استدعاء الدوالّ عند طلبها
من النموذج، وتُرسِل النتائج مرة أخرى إلى النموذج لإكمال المهمة.
import os
from google import genai
from google.genai import types
# Example Functions
def get_weather_forecast(location: str) -> dict:
"""Gets the current weather temperature for a given location."""
print(f"Tool Call: get_weather_forecast(location={location})")
# TODO: Make API call
print("Tool Response: {'temperature': 25, 'unit': 'celsius'}")
return {"temperature": 25, "unit": "celsius"} # Dummy response
def set_thermostat_temperature(temperature: int) -> dict:
"""Sets the thermostat to a desired temperature."""
print(f"Tool Call: set_thermostat_temperature(temperature={temperature})")
# TODO: Interact with a thermostat API
print("Tool Response: {'status': 'success'}")
return {"status": "success"}
# Configure the client and model
client = genai.Client(
api_key=os.getenv("GEMINI_API_KEY")
) # Replace with your actual API key setup
config = types.GenerateContentConfig(
tools=[get_weather_forecast, set_thermostat_temperature]
)
# Make the request
response = client.models.generate_content(
model="gemini-2.0-flash",
contents="If it's warmer than 20°C in London, set the thermostat to 20°C, otherwise set it to 18°C.",
config=config,
)
# Print the final, user-facing response
print(response.text)
النتيجة المتوقّعة
عند تشغيل الرمز، سترى حزمة تطوير البرامج (SDK) تنظّم طلبات معالجة الدوالّ. يتصل النموذج أولاً بـ get_weather_forecast
ويتلقّى درجة
الحرارة، ثم يتصل بـ set_thermostat_temperature
باستخدام قيمة
الصحيحة استنادًا إلى المنطق الوارد في الطلب.
Tool Call: get_weather_forecast(location=London)
Tool Response: {'temperature': 25, 'unit': 'celsius'}
Tool Call: set_thermostat_temperature(temperature=20)
Tool Response: {'status': 'success'}
OK. I've set the thermostat to 20°C.
JavaScript
يوضّح هذا المثال كيفية استخدام حزمة تطوير البرامج (SDK) لـ JavaScript/TypeScript لإجراء اتّصال دالة تركيبية باستخدام حلقة تنفيذ يدوية.
import { GoogleGenAI, Type } from "@google/genai";
// Configure the client
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
// Example Functions
function get_weather_forecast({ location }) {
console.log(`Tool Call: get_weather_forecast(location=${location})`);
// TODO: Make API call
console.log("Tool Response: {'temperature': 25, 'unit': 'celsius'}");
return { temperature: 25, unit: "celsius" };
}
function set_thermostat_temperature({ temperature }) {
console.log(
`Tool Call: set_thermostat_temperature(temperature=${temperature})`,
);
// TODO: Make API call
console.log("Tool Response: {'status': 'success'}");
return { status: "success" };
}
const toolFunctions = {
get_weather_forecast,
set_thermostat_temperature,
};
const tools = [
{
functionDeclarations: [
{
name: "get_weather_forecast",
description:
"Gets the current weather temperature for a given location.",
parameters: {
type: Type.OBJECT,
properties: {
location: {
type: Type.STRING,
},
},
required: ["location"],
},
},
{
name: "set_thermostat_temperature",
description: "Sets the thermostat to a desired temperature.",
parameters: {
type: Type.OBJECT,
properties: {
temperature: {
type: Type.NUMBER,
},
},
required: ["temperature"],
},
},
],
},
];
// Prompt for the model
let contents = [
{
role: "user",
parts: [
{
text: "If it's warmer than 20°C in London, set the thermostat to 20°C, otherwise set it to 18°C.",
},
],
},
];
// Loop until the model has no more function calls to make
while (true) {
const result = await ai.models.generateContent({
model: "gemini-2.0-flash",
contents,
config: { tools },
});
if (result.functionCalls && result.functionCalls.length > 0) {
const functionCall = result.functionCalls[0];
const { name, args } = functionCall;
if (!toolFunctions[name]) {
throw new Error(`Unknown function call: ${name}`);
}
// Call the function and get the response.
const toolResponse = toolFunctions[name](args);
const functionResponsePart = {
name: functionCall.name,
response: {
result: toolResponse,
},
};
// Send the function response back to the model.
contents.push({
role: "model",
parts: [
{
functionCall: functionCall,
},
],
});
contents.push({
role: "user",
parts: [
{
functionResponse: functionResponsePart,
},
],
});
} else {
// No more function calls, break the loop.
console.log(result.text);
break;
}
}
النتيجة المتوقّعة
عند تشغيل الرمز، سترى حزمة تطوير البرامج (SDK) تنظّم طلبات معالجة الدوالّ. يتصل النموذج أولاً بـ get_weather_forecast
، ويتلقّى درجة
الحرارة، ثم يتصل بـ set_thermostat_temperature
بالقيمة
الصحيحة استنادًا إلى المنطق في الطلب.
Tool Call: get_weather_forecast(location=London)
Tool Response: {'temperature': 25, 'unit': 'celsius'}
Tool Call: set_thermostat_temperature(temperature=20)
Tool Response: {'status': 'success'}
OK. It's 25°C in London, so I've set the thermostat to 20°C.
إنّ استدعاء الدوال التركيبية هي ميزة أساسية في Live API. وهذا يعني أنّ واجهة برمجة التطبيقات Live API يمكنها معالجة استدعاء الدالة على غرار حزمة تطوير البرامج (SDK) لـ Python.
Python
# Light control schemas
turn_on_the_lights_schema = {'name': 'turn_on_the_lights'}
turn_off_the_lights_schema = {'name': 'turn_off_the_lights'}
prompt = """
Hey, can you write run some python code to turn on the lights, wait 10s and then turn off the lights?
"""
tools = [
{'code_execution': {}},
{'function_declarations': [turn_on_the_lights_schema, turn_off_the_lights_schema]}
]
await run(prompt, tools=tools, modality="AUDIO")
JavaScript
// Light control schemas
const turnOnTheLightsSchema = { name: 'turn_on_the_lights' };
const turnOffTheLightsSchema = { name: 'turn_off_the_lights' };
const prompt = `
Hey, can you write run some python code to turn on the lights, wait 10s and then turn off the lights?
`;
const tools = [
{ codeExecution: {} },
{ functionDeclarations: [turnOnTheLightsSchema, turnOffTheLightsSchema] }
];
await run(prompt, tools=tools, modality="AUDIO")
أوضاع استدعاء الدوالّ
تتيح لك Gemini API التحكّم في كيفية استخدام النموذج للأدوات المقدَّمة (وظيفة
التعريفات). ويمكنك تحديد الوضع على وجه التحديد ضمن
function_calling_config
.
AUTO (Default)
: يقرّر النموذج ما إذا كان سينشئ ردًا باللغة الطبيعية أو يقترح طلبًا لتشغيل دالة استنادًا إلى الطلب والسياق. هذا هو الوضع الأكثر مرونة ويُنصح به لمعظم السيناريوهات.ANY
: يتم تقييد النموذج لتوقّع استدعاء دالة دائمًا وضمان الالتزام بمخطّط الدالة. إذا لم يتم تحديدallowed_function_names
، يمكن للنموذج الاختيار من بين أيّ من نماذج تعريف الدوالّ المقدّمة. إذا تم تقديمallowed_function_names
كقائمة، لن يتمكّن النموذج من الاختيار إلا من بين الدوالّ الواردة في تلك القائمة. استخدِم هذا الوضع عندما تحتاج إلى طلب استدعاء دالة استجابةً لكل طلب (إن أمكن).NONE
: محظور على النموذج إجراء استدعاءات للوظائف. ويعادل ذلك إرسال طلب بدون أيّ تعريفات وظائف. استخدِم هذا الإجراء لتوقيف استدعاء الدوال مؤقتًا بدون إزالة تعريفات أداة الربط.
Python
from google.genai import types
# Configure function calling mode
tool_config = types.ToolConfig(
function_calling_config=types.FunctionCallingConfig(
mode="ANY", allowed_function_names=["get_current_temperature"]
)
)
# Create the generation config
config = types.GenerateContentConfig(
temperature=0,
tools=[tools], # not defined here.
tool_config=tool_config,
)
JavaScript
import { FunctionCallingConfigMode } from '@google/genai';
// Configure function calling mode
const toolConfig = {
functionCallingConfig: {
mode: FunctionCallingConfigMode.ANY,
allowedFunctionNames: ['get_current_temperature']
}
};
// Create the generation config
const config = {
temperature: 0,
tools: tools, // not defined here.
toolConfig: toolConfig,
};
استدعاء الدالة التلقائي (Python فقط)
عند استخدام حزمة تطوير البرامج (SDK) لـ Python، يمكنك توفير دوال Python مباشرةً كأدوات. تحوّل حزمة SDK دالة Python تلقائيًا إلى بيانات تعريف، وتتعامل مع تنفيذ استدعاء الدالة ودورة الاستجابة نيابةً عنك. بعد ذلك، تُجري حزمة تطوير البرامج (SDK) لـ Python ما يلي تلقائيًا:
- يرصد استجابات استدعاء الدوال من النموذج.
- استخدِم دالة Python المقابلة في الرمز البرمجي.
- تُرسِل استجابة الدالة مرة أخرى إلى النموذج.
- تعرِض هذه السمة الردّ النصي النهائي للنموذج.
لاستخدام هذه الميزة، حدِّد الدالة باستخدام تلميحات النوع ونص وصفي، ثم مرِّر الدالة نفسها (وليس بيان JSON) كأداة:
Python
from google import genai
from google.genai import types
# Define the function with type hints and docstring
def get_current_temperature(location: str) -> dict:
"""Gets the current temperature for a given location.
Args:
location: The city and state, e.g. San Francisco, CA
Returns:
A dictionary containing the temperature and unit.
"""
# ... (implementation) ...
return {"temperature": 25, "unit": "Celsius"}
# Configure the client and model
client = genai.Client(api_key=os.getenv("GEMINI_API_KEY")) # Replace with your actual API key setup
config = types.GenerateContentConfig(
tools=[get_current_temperature]
) # Pass the function itself
# Make the request
response = client.models.generate_content(
model="gemini-2.0-flash",
contents="What's the temperature in Boston?",
config=config,
)
print(response.text) # The SDK handles the function call and returns the final text
يمكنك إيقاف استدعاء الدوالّ البرمجية التلقائي باستخدام:
Python
# To disable automatic function calling:
config = types.GenerateContentConfig(
tools=[get_current_temperature],
automatic_function_calling=types.AutomaticFunctionCallingConfig(disable=True)
)
بيان مخطّط الدالة التلقائية
لا تعمل عملية استخراج المخطّط التلقائية من وظائف Python في جميع الحالات. على سبيل المثال: لا يعالج هذا الإجراء الحالات التي تصف فيها حقول عنصر قاموس مُدمَج. يمكن لواجهة برمجة التطبيقات وصف أيٍّ من الأنواع التالية:
Python
AllowedType = (int | float | bool | str | list['AllowedType'] | dict[str, AllowedType])
للاطّلاع على شكل المخطّط المستنِد، يمكنك تحويله باستخدام
from_callable
:
Python
def multiply(a: float, b: float):
"""Returns a * b."""
return a * b
fn_decl = types.FunctionDeclaration.from_callable(callable=multiply, client=client)
# to_json_dict() provides a clean JSON representation.
print(fn_decl.to_json_dict())
استخدام أدوات متعددة: دمج الأدوات الأصلية مع استدعاء الدوالّ
باستخدام Gemini 2.0، يمكنك تفعيل أدوات متعددة تجمع بين الأدوات الأصلية و طلبات الدالة في الوقت نفسه. في ما يلي مثال يتيح أداتين، الربط بخدمة "بحث Google" وتنفيذ الترميز، في طلب باستخدام Live API.
Python
# Multiple tasks example - combining lights, code execution, and search
prompt = """
Hey, I need you to do three things for me.
1. Turn on the lights.
2. Then compute the largest prime palindrome under 100000.
3. Then use Google Search to look up information about the largest earthquake in California the week of Dec 5 2024.
Thanks!
"""
tools = [
{'google_search': {}},
{'code_execution': {}},
{'function_declarations': [turn_on_the_lights_schema, turn_off_the_lights_schema]} # not defined here.
]
# Execute the prompt with specified tools in audio modality
await run(prompt, tools=tools, modality="AUDIO")
JavaScript
// Multiple tasks example - combining lights, code execution, and search
const prompt = `
Hey, I need you to do three things for me.
1. Turn on the lights.
2. Then compute the largest prime palindrome under 100000.
3. Then use Google Search to look up information about the largest earthquake in California the week of Dec 5 2024.
Thanks!
`;
const tools = [
{ googleSearch: {} },
{ codeExecution: {} },
{ functionDeclarations: [turnOnTheLightsSchema, turnOffTheLightsSchema] } // not defined here.
];
// Execute the prompt with specified tools in audio modality
await run(prompt, {tools: tools, modality: "AUDIO"});
يمكن لمطوّري Python تجربة ذلك في دفتر ملاحظات استخدام أداة واجهة برمجة التطبيقات المباشرة.
بروتوكول سياق النماذج (MCP)
بروتوكول سياق النماذج (MCP) هو معيار مفتوح لربط تطبيقات الذكاء الاصطناعي بالأدوات والبيانات الخارجية. يوفّر MCP بروتوكولًا شائعًا للنمذجة للوصول إلى السياق، مثل الدوال (الأدوات) أو مصادر البيانات (الموارد) أو الطلبات المحدّدة مسبقًا.
تتضمّن حِزم تطوير البرامج (SDK) في Gemini ميزات مدمجة متوافقة مع MCP، ما يقلل من الرموز البرمجية المتكررة ويقدّم استدعاء الأدوات تلقائيًا لأدوات MCP. عندما يُنشئ النموذج طلبًا لاستخدام أداة MCP، يمكن لحِزم تطوير البرامج (SDK) لعملاء Python و JavaScript تنفيذ أداة MCP تلقائيًا وإرسال الردّ مرة أخرى إلى النموذج في طلب لاحق، مع مواصلة هذه الحلقة إلى أن يتوقف النموذج عن إرسال طلبات لاستخدام الأداة.
يمكنك هنا العثور على مثال على كيفية استخدام خادم MCP محلي مع Gemini وحزمة SDK الخاصة بـ
mcp
.
Python
تأكَّد من تثبيت أحدث إصدار من mcp
حزمة تطوير البرامج (SDK) على منصّة التطوير المفضّلة لديك.
pip install mcp
import os
import asyncio
from datetime import datetime
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from google import genai
client = genai.Client(api_key=os.getenv("GEMINI_API_KEY"))
# Create server parameters for stdio connection
server_params = StdioServerParameters(
command="npx", # Executable
args=["-y", "@philschmid/weather-mcp"], # MCP Server
env=None, # Optional environment variables
)
async def run():
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
# Prompt to get the weather for the current day in London.
prompt = f"What is the weather in London in {datetime.now().strftime('%Y-%m-%d')}?"
# Initialize the connection between client and server
await session.initialize()
# Send request to the model with MCP function declarations
response = await client.aio.models.generate_content(
model="gemini-2.0-flash",
contents=prompt,
config=genai.types.GenerateContentConfig(
temperature=0,
tools=[session], # uses the session, will automatically call the tool
# Uncomment if you **don't** want the sdk to automatically call the tool
# automatic_function_calling=genai.types.AutomaticFunctionCallingConfig(
# disable=True
# ),
),
)
print(response.text)
# Start the asyncio event loop and run the main function
asyncio.run(run())
JavaScript
تأكَّد من تثبيت أحدث إصدار من حزمة SDK لنظام التشغيل mcp
على منصتك المفضّلة.
npm install @modelcontextprotocol/sdk
import { GoogleGenAI, FunctionCallingConfigMode , mcpToTool} from '@google/genai';
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
// Create server parameters for stdio connection
const serverParams = new StdioClientTransport({
command: "npx", // Executable
args: ["-y", "@philschmid/weather-mcp"] // MCP Server
});
const client = new Client(
{
name: "example-client",
version: "1.0.0"
}
);
// Configure the client
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
// Initialize the connection between client and server
await client.connect(serverParams);
// Send request to the model with MCP tools
const response = await ai.models.generateContent({
model: "gemini-2.0-flash",
contents: `What is the weather in London in ${new Date().toLocaleDateString()}?`,
config: {
tools: [mcpToTool(client)], // uses the session, will automatically call the tool
// Uncomment if you **don't** want the sdk to automatically call the tool
// automaticFunctionCalling: {
// disable: true,
// },
},
});
console.log(response.text)
// Close the connection
await client.close();
القيود المفروضة على ميزة "إدارة العملاء المتعددين" المضمّنة
إنّ ميزة "إدارة العملاء المتعددين" المضمّنة هي ميزة تجريبية في حِزم SDK لدينا، وهي تخضع للقيود التالية:
- تتوفّر الأدوات فقط، وليس الموارد أو الطلبات.
- وهي متاحة لحِزم SDK Python وJavaScript/TypeScript.
- قد تحدث تغييرات جذرية في الإصدارات المستقبلية.
يمكنك دائمًا دمج خوادم MCP يدويًا إذا كانت هذه الخوادم تحدّ من ما تريد بنائه.
النماذج المتوافقة
ولا يتم تضمين النماذج التجريبية. يمكنك الاطّلاع على ميزاتها في صفحة نظرة عامة على الطراز.
الطراز | استدعاء الدوالّ | استدعاء الدوالّ بشكل موازٍ | استدعاء الدوالّ التركيبية |
---|---|---|---|
Gemini 2.0 Flash | ✔️ | ✔️ | ✔️ |
Gemini 2.0 Flash-Lite | X | X | X |
Gemini 1.5 Flash | ✔️ | ✔️ | ✔️ |
Gemini 1.5 Pro | ✔️ | ✔️ | ✔️ |
أفضل الممارسات
- أوصاف الدوال والمَعلمات: يجب أن تكون أوصافك واضحة ومفصّلة للغاية. يعتمد النموذج على هذه العناصر لاختيار الدالة الصحيحة وتقديم الوسيطات المناسبة.
- التسمية: استخدِم أسماء دوال وصفية (بدون مسافات أو نقاط أو شرطة).
- الكتابة القوية: استخدِم أنواعًا محدّدة (عدد صحيح أو سلسلة أو قائمة) للمَعلمات للحدّ من الأخطاء. إذا كانت المَعلمة تحتوي على مجموعة محدودة من القيم الصالحة، استخدِم ملف تعريف برمجيًا للقائمة المحدودة.
- اختيار الأداة: على الرغم من أنّ النموذج يمكنه استخدام عدد عشوائي من الأدوات، فإنّ تقديم عدد كبير جدًا منها يمكن أن يزيد من خطر اختيار أداة غير صحيحة أو غير مثالية. للحصول على أفضل النتائج، احرص على تقديم الأدوات ذات الصلة فقط بالسياق أو المهمة، مع إبقاء المجموعة النشطة في حدود 10 إلى 20 أداة كحد أقصى. ننصحك باختيار الأدوات الديناميكية استنادًا إلى سياق المحادثة إذا كان لديك إجمالي عدد كبير من الأدوات.
- هندسة الطلبات:
- تقديم سياق: أخبِر النموذج بدوره (مثل "أنت مساعد متعاون في ما يتعلّق بالطقس").
- تقديم تعليمات: حدِّد كيفية استخدام الدوالّ وحالات استخدامها (مثل "لا تخمن تواريخ التوقعات، بل استخدِم دائمًا تاريخًا مستقبليًا.").
- تشجيع التوضيح: يمكنك توجيه النموذج لطرح أسئلة توضيحية إذا لزم الأمر.
- درجة الحرارة: استخدِم درجة حرارة منخفضة (مثل 0) لطلبات الدوالّ التي تتسم بالتحديد والموثوقية.
- التحقّق من الصحة: إذا كانت هناك عواقب مهمة لاستدعاء دالة (مثل تقديم طلب)، عليك التحقّق من صحته مع المستخدم قبل تنفيذه.
- معالجة الأخطاء: نفِّذ معالجة أخطاء فعّالة في وظائفك لمعالجة الإدخالات غير المتوقّعة أو حالات تعذُّر الاتصال بواجهة برمجة التطبيقات بشكلٍ سلس. عرض رسائل خطأ مفيدة يمكن للنموذج استخدامها لإنشاء ردود مفيدة للمستخدم
- الأمان: يجب الانتباه إلى الأمان عند استدعاء واجهات برمجة التطبيقات الخارجية. استخدِم آليات المصادقة والتفويض المناسبة. تجنَّب عرض البيانات الحسّاسة في طلبات الدالة.
- الحدّ الأقصى لعدد الرموز المميّزة: يتم احتساب أوصاف الدوالّ والمَعلمات ضمن الحدّ الأقصى المسموح به لعدد الرموز المميّزة التي يمكنك إدخالها. إذا كنت تتجاوز حدود الرموز المميّزة، ننصحك بالحدّ من عدد الدوالّ أو طول الأوصاف، وتقسيم المهام المعقدة إلى مجموعات دوالّ أصغر حجمًا وأكثر تركيزًا.
الملاحظات والقيود
- لا يتوافق سوى مجموعة فرعية من OpenAPI schema.
- أنواع المَعلمات المتوافقة في لغة بايثون محدودة.
- إنّ استدعاء الدوالّ تلقائيًا هو ميزة حزمة تطوير البرامج (SDK) لـ Python فقط.