تتيح لك ميزة "استدعاء الدوال" ربط النماذج بالأدوات وواجهات برمجة التطبيقات الخارجية. وبدلاً من إنشاء ردود نصية، يحدّد النموذج الوقت المناسب لاستدعاء دوال معيّنة ويقدّم المَعلمات اللازمة لتنفيذ إجراءات واقعية. يتيح ذلك للنموذج أن يكون بمثابة جسر يربط بين اللغة الطبيعية والإجراءات والبيانات في العالم الحقيقي. تتضمّن ميزة "استدعاء الدالة" 3 حالات استخدام أساسية:
- تعزيز المعرفة: الوصول إلى المعلومات من مصادر خارجية، مثل قواعد البيانات وواجهات برمجة التطبيقات وقواعد المعرفة
- توسيع الإمكانات: يمكنك استخدام أدوات خارجية لإجراء العمليات الحسابية وتوسيع حدود النموذج، مثل استخدام آلة حاسبة أو إنشاء رسومات بيانية.
- اتّخاذ الإجراءات: التفاعل مع الأنظمة الخارجية باستخدام واجهات برمجة التطبيقات، مثل تحديد المواعيد أو إنشاء الفواتير أو إرسال الرسائل الإلكترونية أو التحكّم في الأجهزة المنزلية الذكية
Python
from google import genai
from google.genai import types
# Define the function declaration for the model
schedule_meeting_function = {
"name": "schedule_meeting",
"description": "Schedules a meeting with specified attendees at a given time and date.",
"parameters": {
"type": "object",
"properties": {
"attendees": {
"type": "array",
"items": {"type": "string"},
"description": "List of people attending the meeting.",
},
"date": {
"type": "string",
"description": "Date of the meeting (e.g., '2024-07-29')",
},
"time": {
"type": "string",
"description": "Time of the meeting (e.g., '15:00')",
},
"topic": {
"type": "string",
"description": "The subject or topic of the meeting.",
},
},
"required": ["attendees", "date", "time", "topic"],
},
}
# Configure the client and tools
client = genai.Client()
tools = types.Tool(function_declarations=[schedule_meeting_function])
config = types.GenerateContentConfig(tools=[tools])
# Send request with function declarations
response = client.models.generate_content(
model="gemini-2.5-flash",
contents="Schedule a meeting with Bob and Alice for 03/14/2025 at 10:00 AM about the Q3 planning.",
config=config,
)
# Check for a function call
if response.candidates[0].content.parts[0].function_call:
function_call = response.candidates[0].content.parts[0].function_call
print(f"Function to call: {function_call.name}")
print(f"Arguments: {function_call.args}")
# In a real app, you would call your function here:
# result = schedule_meeting(**function_call.args)
else:
print("No function call found in the response.")
print(response.text)
JavaScript
import { GoogleGenAI, Type } from '@google/genai';
// Configure the client
const ai = new GoogleGenAI({});
// Define the function declaration for the model
const scheduleMeetingFunctionDeclaration = {
name: 'schedule_meeting',
description: 'Schedules a meeting with specified attendees at a given time and date.',
parameters: {
type: Type.OBJECT,
properties: {
attendees: {
type: Type.ARRAY,
items: { type: Type.STRING },
description: 'List of people attending the meeting.',
},
date: {
type: Type.STRING,
description: 'Date of the meeting (e.g., "2024-07-29")',
},
time: {
type: Type.STRING,
description: 'Time of the meeting (e.g., "15:00")',
},
topic: {
type: Type.STRING,
description: 'The subject or topic of the meeting.',
},
},
required: ['attendees', 'date', 'time', 'topic'],
},
};
// Send request with function declarations
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: 'Schedule a meeting with Bob and Alice for 03/27/2025 at 10:00 AM about the Q3 planning.',
config: {
tools: [{
functionDeclarations: [scheduleMeetingFunctionDeclaration]
}],
},
});
// Check for function calls in the response
if (response.functionCalls && response.functionCalls.length > 0) {
const functionCall = response.functionCalls[0]; // Assuming one function call
console.log(`Function to call: ${functionCall.name}`);
console.log(`Arguments: ${JSON.stringify(functionCall.args)}`);
// In a real app, you would call your actual function here:
// const result = await scheduleMeeting(functionCall.args);
} else {
console.log("No function call found in the response.");
console.log(response.text);
}
REST
curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H 'Content-Type: application/json' \
-X POST \
-d '{
"contents": [
{
"role": "user",
"parts": [
{
"text": "Schedule a meeting with Bob and Alice for 03/27/2025 at 10:00 AM about the Q3 planning."
}
]
}
],
"tools": [
{
"functionDeclarations": [
{
"name": "schedule_meeting",
"description": "Schedules a meeting with specified attendees at a given time and date.",
"parameters": {
"type": "object",
"properties": {
"attendees": {
"type": "array",
"items": {"type": "string"},
"description": "List of people attending the meeting."
},
"date": {
"type": "string",
"description": "Date of the meeting (e.g., '2024-07-29')"
},
"time": {
"type": "string",
"description": "Time of the meeting (e.g., '15:00')"
},
"topic": {
"type": "string",
"description": "The subject or topic of the meeting."
}
},
"required": ["attendees", "date", "time", "topic"]
}
}
]
}
]
}'
طريقة عمل ميزة "استخدام الدوال"

تتضمّن ميزة "استدعاء الدوال" تفاعلاً منظَّمًا بين تطبيقك والنموذج والدوال الخارجية. في ما يلي تفاصيل العملية:
- تحديد تعريف الدالة: حدِّد تعريف الدالة في الرمز البرمجي لتطبيقك. تصف "تعريفات الدوال" اسم الدالة ومعلماتها والغرض منها للنموذج.
- استدعاء النموذج اللغوي الكبير باستخدام تعريفات الدوال: أرسِل طلب المستخدم مع تعريفات الدوال إلى النموذج. ويحلّل الطلب ويحدّد ما إذا كان استدعاء دالة سيكون مفيدًا. وفي حال توفّرها، سيردّ عليك بكائن JSON منظَّم.
- تنفيذ رمز الدالة (مسؤوليتك): لا ينفّذ النموذج الدالة بنفسه. يقع على عاتق تطبيقك مسؤولية معالجة الرد والتحقّق من Function Call، إذا كان
- نعم: استخرِج اسم الدالة ووسيطاتها ونفِّذ الدالة المقابلة في تطبيقك.
- لا: قدّم النموذج ردًا نصيًا مباشرًا على الطلب (لا يتم التركيز على هذا المسار في المثال، ولكنّه نتيجة محتملة).
- إنشاء ردّ سهل الاستخدام: إذا تم تنفيذ دالة، يجب تسجيل النتيجة وإرسالها مرة أخرى إلى النموذج في دورة لاحقة من المحادثة. سيستخدم النتيجة لإنشاء رد نهائي سهل الاستخدام يتضمّن المعلومات من استدعاء الدالة.
يمكن تكرار هذه العملية عدة مرات، ما يتيح إجراء تفاعلات وعمليات سير عمل معقّدة. يتيح النموذج أيضًا استدعاء دوال متعددة في دورة واحدة (استدعاء الدوال المتوازية) وبشكل متسلسل (استدعاء الدوال التركيبية).
الخطوة 1: تحديد تعريف دالة
حدِّد دالة وبيانها ضمن رمز تطبيقك يسمح للمستخدمين بضبط قيم الإضاءة وإجراء طلب إلى واجهة برمجة التطبيقات. يمكن أن تستدعي هذه الدالة خدمات أو واجهات برمجة تطبيقات خارجية.
Python
# 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.genai import types
# Configure the client and tools
client = genai.Client()
tools = types.Tool(function_declarations=[set_light_values_declaration])
config = types.GenerateContentConfig(tools=[tools])
# 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.5-flash",
contents=contents
config=config,
)
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({});
// 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.5-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
from google import genai
from google.genai import types
# 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
client = genai.Client()
final_response = client.models.generate_content(
model="gemini-2.5-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.5-flash',
contents: contents,
config: config
});
console.log(final_response.text);
بهذا تنتهي عملية استدعاء الدوال. استخدم النموذج الدالة
set_light_values بنجاح لتنفيذ الإجراء المطلوب من المستخدم.
تعريفات الدوال
عند تنفيذ ميزة "استدعاء الدوال" في طلب، يمكنك إنشاء كائن tools يحتوي على دالة واحدة أو أكثر function declarations. يمكنك تحديد الدوال باستخدام JSON، وتحديدًا باستخدام مجموعة فرعية من عبارات الاختيار من تنسيق مخطط OpenAPI. يمكن أن يتضمّن تعريف الدالة الواحدة المَعلمات التالية:
-
name(string): اسم فريد للدالة (get_weather_forecast،send_email). استخدِم أسماء وصفية بدون مسافات أو أحرف خاصة (استخدِم الشرطات السفلية أو camelCase). description(سلسلة): شرح واضح ومفصّل للغرض من الدالة وإمكاناتها. وهذا أمر بالغ الأهمية لكي يفهم النموذج متى يجب استخدام الدالة. كن دقيقًا وقدِّم أمثلة إذا كان ذلك مفيدًا ("تعثر على دور السينما استنادًا إلى الموقع الجغرافي وعنوان الفيلم اختياريًا، والذي يتم عرضه حاليًا في دور السينما").parameters(object): تحدّد هذه السمة مَعلمات الإدخال التي تتوقّعها الدالة.type(سلسلة): تحدّد نوع البيانات العام، مثلobject.properties(عنصر): تعرض هذه السمة قائمة بالمعلمات الفردية، ويتضمّن كل منها ما يلي:type(سلسلة): نوع بيانات المَعلمة، مثلstringأوintegerأوboolean, array-
description(سلسلة): وصف لغرض المَعلمة وتنسيقها. قدِّم أمثلة وقيودًا ("المدينة والولاية، مثل "سان فرانسيسكو، كاليفورنيا" أو رمز بريدي، مثل '95616'."). -
enum(مصفوفة، اختياري): إذا كانت قيم المَعلمات من مجموعة ثابتة، استخدِم "enum" لإدراج القيم المسموح بها بدلاً من مجرد وصفها في الوصف. يؤدي ذلك إلى تحسين الدقة ("enum": ["daylight", "cool", "warm"]).
required(مصفوفة): مصفوفة من السلاسل تسرد أسماء المَعلمات التي يجب توفّرها لكي تعمل الدالة.
يمكنك أيضًا إنشاء FunctionDeclarations من دوال Python مباشرةً باستخدام
types.FunctionDeclaration.from_callable(client=client, callable=your_function).
استدعاء الدوال باستخدام نماذج التفكير
تستخدم نماذج Gemini 3 و2.5 سلسلة عملية "تفكير" داخلية للاستدلال على الطلبات. يؤدي ذلك إلى تحسين أداء استدعاء الدوال بشكل كبير، ما يسمح للنموذج بتحديد الوقت المناسب لاستدعاء دالة والمعلَمات التي يجب استخدامها بشكل أفضل. بما أنّ Gemini API لا يحتفظ بأي بيانات، تستخدم النماذج توقيعات الأفكار للحفاظ على السياق في المحادثات المتعددة الأدوار.
يتناول هذا القسم الإدارة المتقدّمة لتوقيعات الأفكار، ولا يكون ضروريًا إلا إذا كنت تنشئ طلبات واجهة برمجة التطبيقات يدويًا (مثل REST) أو تتلاعب بسجلّ المحادثات.
إذا كنت تستخدم حِزم تطوير البرامج (SDK) من Google للذكاء الاصطناعي التوليدي (مكتباتنا الرسمية)، لن تحتاج إلى إدارة هذه العملية. تتولّى حِزم SDK تلقائيًا تنفيذ الخطوات اللازمة، كما هو موضّح في المثال السابق.
إدارة سجلّ المحادثات يدويًا
إذا عدّلت سجلّ المحادثات يدويًا، بدلاً من إرسال الردّ السابق الكامل، عليك التعامل بشكل صحيح مع thought_signature المضمّن في ردّ النموذج.
اتّبِع هذه القواعد لضمان الحفاظ على سياق النموذج:
- يجب دائمًا إعادة
thought_signatureإلى النموذج داخلPartالأصلي. - لا تدمج
Partتحتوي على توقيع معPartلا تحتوي على توقيع. يؤدي ذلك إلى إزالة السياق الموضعي للفكرة. - لا تدمج بين ملفَي
Partsيحتويان على تواقيع، لأنّه لا يمكن دمج سلاسل التواقيع.
توقيعات أفكار Gemini 3
في Gemini 3، قد يحتوي أي Part من ردّ النموذج
على توقيع فكري.
على الرغم من أنّنا ننصح بشكل عام بعرض التوقيعات من جميع أنواع Part، إلا أنّ عرض توقيعات الأفكار هو أمر إلزامي عند استخدام ميزة "استدعاء الدوال". ما لم يتم التلاعب بسجلّ المحادثات يدويًا، ستتعامل حزمة تطوير البرامج (SDK) من Google للذكاء الاصطناعي التوليدي مع توقيعات الأفكار تلقائيًا.
إذا كنت تتلاعب بسجلّ المحادثات يدويًا، يُرجى الرجوع إلى صفحة توقيعات الأفكار للحصول على إرشادات وتفاصيل كاملة حول كيفية التعامل مع توقيعات الأفكار في Gemini 3.
فحص توقيعات الأفكار
مع أنّ ذلك ليس ضروريًا للتنفيذ، يمكنك فحص الردّ للاطّلاع على
thought_signature لأغراض تصحيح الأخطاء أو تعليمية.
Python
import base64
# After receiving a response from a model with thinking enabled
# response = client.models.generate_content(...)
# The signature is attached to the response part containing the function call
part = response.candidates[0].content.parts[0]
if part.thought_signature:
print(base64.b64encode(part.thought_signature).decode("utf-8"))
JavaScript
// After receiving a response from a model with thinking enabled
// const response = await ai.models.generateContent(...)
// The signature is attached to the response part containing the function call
const part = response.candidates[0].content.parts[0];
if (part.thoughtSignature) {
console.log(part.thoughtSignature);
}
يمكنك الاطّلاع على مزيد من المعلومات حول القيود والاستخدامات المتعلقة بالتوقيعات الفكرية ونماذج التفكير بشكل عام في صفحة التفكير.
استدعاء الدوال بشكلٍ متوازٍ
بالإضافة إلى استدعاء الدوال في جولة واحدة، يمكنك أيضًا استدعاء دوال متعددة في الوقت نفسه. تتيح لك ميزة "تنفيذ الدوال بالتوازي" تنفيذ دوال متعددة في الوقت نفسه، ويتم استخدامها عندما لا تكون الدوال معتمدة على بعضها البعض. ويكون ذلك مفيدًا في حالات مثل جمع البيانات من مصادر مستقلة متعددة، مثل استرداد تفاصيل العملاء من قواعد بيانات مختلفة أو التحقّق من مستويات المخزون في مستودعات مختلفة أو تنفيذ إجراءات متعددة مثل تحويل شقتك إلى ديسكو.
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']
}
};
اضبط وضع استدعاء الدوال للسماح باستخدام جميع الأدوات المحدّدة. لمزيد من المعلومات، يمكنك الاطّلاع على مقالة ضبط ميزة "استدعاء الدوال".
Python
from google import genai
from google.genai import types
# Configure the client and tools
client = genai.Client()
house_tools = [
types.Tool(function_declarations=[power_disco_ball, start_music, dim_lights])
]
config = types.GenerateContentConfig(
tools=house_tools,
automatic_function_calling=types.AutomaticFunctionCallingConfig(
disable=True
),
# Force the model to call 'any' function, instead of chatting.
tool_config=types.ToolConfig(
function_calling_config=types.FunctionCallingConfig(mode='ANY')
),
)
chat = client.chats.create(model="gemini-2.5-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({});
// Create a chat session
const chat = ai.chats.create({
model: 'gemini-2.5-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 function implementations
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}
# Configure the client
client = genai.Client()
config = types.GenerateContentConfig(
tools=[power_disco_ball_impl, start_music_impl, dim_lights_impl]
)
# Make the request
response = client.models.generate_content(
model="gemini-2.5-flash",
contents="Do everything you need to this place into party!",
config=config,
)
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()
config = types.GenerateContentConfig(
tools=[get_weather_forecast, set_thermostat_temperature]
)
# Make the request
response = client.models.generate_content(
model="gemini-2.5-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
يوضّح هذا المثال كيفية استخدام JavaScript/TypeScript SDK لتنفيذ استدعاءات الدوال التركيبية باستخدام حلقة تنفيذ يدوية.
import { GoogleGenAI, Type } from "@google/genai";
// Configure the client
const ai = new GoogleGenAI({});
// 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.5-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: محظور على النموذج إجراء استدعاءات الدوال. وهذا الإجراء يعادل إرسال طلب بدون أي تعريفات للدوال. يمكنك استخدام هذه السمة لإيقاف ميزة "استدعاء الدوال" مؤقتًا بدون إزالة تعريفات الأدوات. VALIDATED(معاينة): يقتصر النموذج على توقّع إما طلبات الدوال أو اللغة الطبيعية، ويضمن الالتزام بمخطط الدوال. في حال عدم توفيرallowed_function_names، يختار النموذج من جميع تعريفات الدوال المتاحة. في حال توفيرallowed_function_names، يختار النموذج من مجموعة الدوال المسموح بها.
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(
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 = {
tools: tools, // not defined here.
toolConfig: toolConfig,
};
استدعاء الدالة تلقائيًا (في Python فقط)
عند استخدام حزمة تطوير البرامج (SDK) الخاصة بلغة Python، يمكنك تقديم دوال Python مباشرةً كأدوات. تحوّل حزمة SDK هذه الدوال إلى تعريفات، وتدير عملية تنفيذ استدعاء الدالة، وتتعامل مع دورة الاستجابة نيابةً عنك. عرِّف الدالة باستخدام تلميحات الأنواع وسلسلة التوثيق. للحصول على أفضل النتائج، ننصحك باستخدام سلاسل مستندات بتنسيق Google. سيقوم حِزمة تطوير البرامج (SDK) بعد ذلك تلقائيًا بما يلي:
- رصد الردود على طلبات تنفيذ الدوال من النموذج
- استدعِ دالة Python المناسبة في الرمز البرمجي.
- إرسال ردّ الدالة إلى النموذج
- عرض الرد النصي النهائي للنموذج
لا تحلّل حزمة تطوير البرامج (SDK) حاليًا أوصاف الوسيطات إلى خانات وصف السمة في تعريف الدالة الذي تم إنشاؤه. بدلاً من ذلك، يرسل السلسلة بأكملها كوصف للدالة ذات المستوى الأعلى.
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
client = genai.Client()
config = types.GenerateContentConfig(
tools=[get_current_temperature]
) # Pass the function itself
# Make the request
response = client.models.generate_content(
model="gemini-2.5-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
config = types.GenerateContentConfig(
tools=[get_current_temperature],
automatic_function_calling=types.AutomaticFunctionCallingConfig(disable=True)
)
بيان مخطط الدالة التلقائي
يمكن لواجهة برمجة التطبيقات وصف أي من الأنواع التالية. يُسمح باستخدام أنواع Pydantic، طالما أنّ الحقول المحدّدة فيها تتألف أيضًا من أنواع مسموح بها. لا تتوافق أنواع القواميس (مثل dict[str: int]) مع هذه الميزة، لذا لا تستخدمها.
Python
AllowedType = (
int | float | bool | str | list['AllowedType'] | pydantic.BaseModel)
للاطّلاع على شكل المخطط المستنتج، يمكنك تحويله باستخدام
from_callable:
Python
from google import genai
from google.genai import types
def multiply(a: float, b: float):
"""Returns a * b."""
return a * b
client = genai.Client()
fn_decl = types.FunctionDeclaration.from_callable(callable=multiply, client=client)
# to_json_dict() provides a clean JSON representation.
print(fn_decl.to_json_dict())
استخدام أدوات متعددة: الجمع بين الأدوات الأصلية واستدعاء الدوال
يمكنك تفعيل أدوات متعددة تجمع بين الأدوات الأصلية واستدعاء الدوال في الوقت نفسه. في ما يلي مثال يفعّل أداتَين، هما الاستناد إلى معلومات من "بحث 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 تجربة هذه الميزة في دفتر Live API Tool Use.
بروتوكول سياق النموذج (MCP)
بروتوكول سياق النموذج (MCP) هو معيار مفتوح المصدر لربط تطبيقات الذكاء الاصطناعي بأدوات وبيانات خارجية. يوفر MCP بروتوكولاً مشتركًا للنماذج للوصول إلى السياق، مثل الدوال (الأدوات) أو مصادر البيانات (الموارد) أو الطلبات المحدّدة مسبقًا.
تتضمّن حِزم تطوير البرامج (SDK) من Gemini إمكانية استخدام أدوات MCP بشكل مباشر، ما يقلّل من الرموز البرمجية المتكرّرة ويوفّر ميزة استدعاء الأدوات تلقائيًا لأدوات MCP. عندما ينشئ النموذج طلبًا لاستخدام أداة MCP، يمكن لحزمة تطوير البرامج (SDK) الخاصة بلغة Python وJavaScript تنفيذ أداة MCP تلقائيًا وإرسال الردّ إلى النموذج في طلب لاحق، مع مواصلة هذه العملية إلى أن يتوقف النموذج عن إرسال طلبات لاستخدام الأدوات.
يمكنك هنا الاطّلاع على مثال حول كيفية استخدام خادم MCP محلي مع Gemini وmcp SDK.
Python
تأكَّد من تثبيت أحدث إصدار من
حزمة تطوير البرامج mcp على
النظام الأساسي الذي تختاره.
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()
# 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.5-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({});
// 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.5-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();
القيود المفروضة على التوافق المضمّن مع منصّات إدارة الموافقة
تتوفّر ميزة دعم MCP المضمّنة تجريبيًا في حِزم SDK، وتخضع للقيود التالية:
- لا تتوفّر سوى الأدوات، وليس المراجع أو الطلبات
- وهي متاحة لحزمة تطوير البرامج (SDK) الخاصة بلغة Python وJavaScript/TypeScript.
- قد تحدث تغييرات غير متوافقة مع الإصدارات السابقة في الإصدارات المستقبلية.
يمكنك دائمًا دمج خوادم MCP يدويًا إذا كانت هذه الخوادم تفرض قيودًا على ما تنشئه.
النماذج المتوافقة
يسرد هذا القسم النماذج وإمكاناتها في استدعاء الدوال. لا يتم تضمين النماذج التجريبية. يمكنك الاطّلاع على نظرة عامة شاملة حول الإمكانات في صفحة النظرة العامة على النموذج.
| الطراز | استدعاء الدالة | استدعاء الدوال بشكل متوازٍ | استدعاء الدوال التركيبية |
|---|---|---|---|
| Gemini 2.5 Pro | ✔️ | ✔️ | ✔️ |
| Gemini 2.5 Flash | ✔️ | ✔️ | ✔️ |
| Gemini 2.5 Flash-Lite | ✔️ | ✔️ | ✔️ |
| Gemini 2.0 Flash | ✔️ | ✔️ | ✔️ |
| Gemini 2.0 Flash-Lite | X | X | X |
أفضل الممارسات
- أوصاف الوظائف والمَعلمات: يجب أن تكون أوصافك واضحة ومحدّدة للغاية. ويعتمد النموذج على هذه المعلومات لاختيار الوظيفة الصحيحة وتقديم الوسيطات المناسبة.
- التسمية: استخدِم أسماء دوال وصفية (بدون مسافات أو نقاط أو شرطات).
- الكتابة القوية: استخدِم أنواعًا محدّدة (عدد صحيح، سلسلة، تعداد) للمَعلمات للحدّ من الأخطاء. إذا كانت إحدى المَعلمات تتضمّن مجموعة محدودة من القيم الصالحة، استخدِم enum.
- اختيار الأدوات: على الرغم من أنّ النموذج يمكنه استخدام عدد غير محدود من الأدوات، إلا أنّ توفير عدد كبير جدًا منها قد يزيد من خطر اختيار أداة غير صحيحة أو غير مثالية. للحصول على أفضل النتائج، احرص على توفير الأدوات ذات الصلة فقط بالسياق أو المهمة، مع الحفاظ على المجموعة النشطة عند 10 إلى 20 أداة كحد أقصى. ننصحك باختيار الأدوات بشكل ديناميكي استنادًا إلى سياق المحادثة إذا كان لديك عدد كبير من الأدوات.
- هندسة الطلبات:
- توفير سياق: أخبر النموذج بدوره (مثلاً "أنت مساعد مفيد بشأن الطقس").
- تقديم تعليمات: حدِّد كيفية استخدام الدوال ومتى (مثلاً لا تخمّن التواريخ، بل استخدِم دائمًا تاريخًا مستقبليًا للتوقّعات").
- تشجيع التوضيح: اطلب من النموذج طرح أسئلة توضيحية إذا لزم الأمر.
درجة الحرارة: استخدِم درجة حرارة منخفضة (مثل 0) لإجراء عمليات استدعاء للدوال أكثر تحديدًا وموثوقية.
التحقّق من الصحة: إذا كان لطلب تنفيذ دالة عواقب كبيرة (مثل تقديم طلب)، يجب التحقّق من صحة الطلب مع المستخدم قبل تنفيذه.
التحقّق من سبب الإنهاء: احرص دائمًا على التحقّق من
finishReasonفي ردّ النموذج للتعامل مع الحالات التي تعذّر فيها على النموذج إنشاء استدعاء دالة صالح.التعامل مع الأخطاء: نفِّذ عملية التعامل مع الأخطاء بشكل فعّال في الدوال للتعامل مع الإدخالات غير المتوقّعة أو حالات تعذُّر الوصول إلى واجهة برمجة التطبيقات. عرض رسائل خطأ مفيدة يمكن للنموذج استخدامها لإنشاء ردود مفيدة للمستخدم.
الأمان: يُرجى مراعاة الأمان عند استدعاء واجهات برمجة التطبيقات الخارجية. استخدام آليات المصادقة والتفويض المناسبة تجنَّب عرض البيانات الحسّاسة في استدعاءات الدوال.
حدود الرموز المميزة: يتم احتساب أوصاف الدوال ومعلَماتها ضمن الحد الأقصى لعدد الرموز المميزة التي يمكنك إدخالها. إذا كنت تواجه مشاكل بسبب الحد الأقصى لعدد الرموز المميزة، ننصحك بالحد من عدد الدوال أو طول الأوصاف، أو بتقسيم المهام المعقّدة إلى مجموعات أصغر وأكثر تركيزًا من الدوال.
الملاحظات والقيود
- لا يتوافق سوى جزء من مخطط OpenAPI.
- أنواع المَعلمات المتوافقة في Python محدودة.
- ميزة استدعاء الدوال التلقائي هي ميزة في حزمة تطوير البرامج (SDK) بلغة Python فقط.