Вызов функций позволяет подключать модели к внешним инструментам и API. Вместо генерации текстовых ответов модель понимает, когда следует вызывать определенные функции, и предоставляет необходимые параметры для выполнения реальных действий. Это позволяет модели выступать в качестве моста между естественным языком и реальными действиями и данными. Вызов функции имеет три основных варианта использования:
- Расширение знаний: доступ к информации из внешних источников, таких как базы данных, API и базы знаний.
- Расширение возможностей: используйте внешние инструменты для выполнения вычислений и расширения ограничений модели, например использование калькулятора или создание диаграмм.
- Принимайте меры: взаимодействуйте с внешними системами с помощью API-интерфейсов, например, планируя встречи, создавая счета, отправляя электронные письма или управляя устройствами умного дома.
Как работает вызов функций
Вызов функций предполагает структурированное взаимодействие между вашим приложением, моделью и внешними функциями. Вот описание процесса:
- Определить объявление функции: Определите объявление функции в коде вашего приложения. Объявления функций описывают имя функции, параметры и назначение модели.
- Вызов LLM с объявлениями функций: отправьте приглашение пользователя вместе с объявлениями функций в модель. Он анализирует запрос и определяет, будет ли полезен вызов функции. Если да, он отвечает структурированным объектом JSON.
- Выполнение кода функции (ваша ответственность): Модель не выполняет функцию сама. Ваше приложение несет ответственность за обработку ответа и проверку вызова функции, если
- Да : извлеките имя и аргументы функции и выполните соответствующую функцию в своем приложении.
- Нет: модель предоставила прямой текстовый ответ на запрос (этот поток в примере менее подчеркнут, но является возможным результатом).
- Создайте удобный для пользователя ответ: если функция была выполнена, зафиксируйте результат и отправьте его обратно в модель на следующем этапе разговора. Он будет использовать результат для создания окончательного, удобного для пользователя ответа, включающего информацию из вызова функции.
Этот процесс можно повторять в течение нескольких ходов, что позволяет создавать сложные взаимодействия и рабочие процессы. Модель также поддерживает вызов нескольких функций за один ход ( параллельный вызов функций ) и последовательно ( композиционный вызов функций ).
Шаг 1. Определите объявление функции
Определите функцию и ее объявление в коде вашего приложения, которые позволят пользователям устанавливать значения освещения и делать запросы к API. Эта функция может вызывать внешние службы или API.
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}
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. Вызов модели с объявлениями функций
После того как вы определили объявления функций, вы можете предложить модели использовать эту функцию. Он анализирует приглашение и объявления функций и решает ответить напрямую или вызвать функцию. Если вызывается функция, объект ответа будет содержать предложение вызова функции.
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)
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, определяющей, как вызвать одну или несколько объявленных функций, чтобы ответить на вопрос пользователя.
id=None args={'color_temp': 'warm', 'brightness': 25} name='set_light_values'
{
name: 'set_light_values',
args: { brightness: 25, color_temp: 'warm' }
}
Шаг 3. Выполните код функции set_light_values
Извлеките детали вызова функции из ответа модели, проанализируйте аргументы и выполните функцию set_light_values
в нашем коде.
# Extract tool call details
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}")
// 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. Создайте удобный для пользователя ответ с результатом функции и снова вызовите модель.
Наконец, отправьте результат выполнения функции обратно в модель, чтобы она могла включить эту информацию в свой окончательный ответ пользователю.
# 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(types.Content(role="model", parts=[types.Part(function_call=tool_call)])) # Append the model's function call message
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)
// 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({ role: 'model', parts: [{ functionCall: tool_call }] });
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
). Используйте описательные имена без пробелов и специальных символов (используйте символы подчеркивания или верблюжий регистр). -
description
(строка): четкое и подробное объяснение назначения и возможностей функции. Это очень важно для того, чтобы модель понимала, когда использовать функцию. Будьте конкретны и приведите примеры, если они полезны («Находит кинотеатры по местоположению и, возможно, по названию фильма, который в настоящее время идет в кинотеатрах»). -
parameters
(объект): определяет входные параметры, которые ожидает функция.-
type
(строка): указывает общий тип данных, напримерobject
. -
properties
(объект): список отдельных параметров, каждый из которых имеет:-
type
(строка): тип данных параметра, напримерstring
,integer
,boolean, array
. -
description
(строка): описание назначения и формата параметра. Приведите примеры и ограничения («Город и штат, например, «Сан-Франциско, Калифорния», или почтовый индекс, например, «95616»). -
enum
(массив, необязательно): если значения параметров взяты из фиксированного набора, используйте «enum», чтобы перечислить разрешенные значения, а не просто описывать их в описании. Это повышает точность ("enum": ["дневной свет", "прохладный", "теплый"]).
-
-
required
(массив): массив строк, в котором перечислены имена параметров, которые являются обязательными для работы функции.
-
Параллельный вызов функций
Помимо вызова функции одного поворота, вы также можете вызывать несколько функций одновременно. Параллельный вызов функций позволяет выполнять несколько функций одновременно и используется, когда функции не зависят друг от друга. Это полезно в таких сценариях, как сбор данных из нескольких независимых источников, например получение сведений о клиентах из разных баз данных или проверка уровня запасов на различных складах или выполнение нескольких действий, таких как превращение вашей квартиры в дискотеку.
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"],
},
}
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
. Чтобы узнать больше, вы можете прочитать о настройке вызова функций .
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})")
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})`);
}
Каждый из напечатанных результатов отражает один вызов функции, запрошенный моделью. Чтобы отправить результаты обратно, включите ответы в том же порядке, в котором они были запрошены.
Python SDK поддерживает функцию, называемую автоматическим вызовом функций , которая преобразует функцию 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 2.0 поддерживает композиционный вызов функций, то есть модель может объединять несколько вызовов функций. Например, чтобы ответить «Получить температуру в моем текущем местоположении», API Gemini может вызвать как функцию get_current_location()
, так и функцию get_weather()
, которая принимает местоположение в качестве параметра.
# 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")
// 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")
Режимы вызова функций
API Gemini позволяет вам контролировать, как модель использует предоставленные инструменты (объявления функций). В частности, вы можете установить режим в function_calling_config
.
-
AUTO (Default)
: модель решает, генерировать ли ответ на естественном языке или предлагать вызов функции на основе подсказки и контекста. Это наиболее гибкий режим, рекомендуемый для большинства сценариев. -
ANY
: модель ограничена тем, что всегда прогнозирует вызов функции и гарантирует соблюдение схемы функции. Еслиallowed_function_names
не указаны, модель может выбирать любое из предоставленных объявлений функций. Еслиallowed_function_names
указаны в виде списка, модель может выбирать только функции из этого списка. Используйте этот режим, если вам требуется вызов функции в ответ на каждый запрос (если применимо). NONE
: модели запрещено вызывать функции. Это эквивалентно отправке запроса без каких-либо объявлений функций. Используйте это, чтобы временно отключить вызов функций, не удаляя определения инструментов.
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,
)
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)
При использовании Python SDK вы можете предоставлять функции Python непосредственно в качестве инструментов. SDK автоматически преобразует функцию Python в объявления, обрабатывает выполнение вызова функции и цикл ответа. Затем Python SDK автоматически:
- Обнаруживает ответы на вызовы функций из модели.
- Вызовите соответствующую функцию Python в своем коде.
- Отправляет ответ функции обратно в модель.
- Возвращает окончательный текстовый ответ модели.
Чтобы использовать это, определите свою функцию с помощью подсказок типа и строки документации, а затем передайте саму функцию (а не объявление JSON) в качестве инструмента:
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 London?",
config=config,
)
print(response.text) # The SDK handles the function call and returns the final text
Вы можете отключить автоматический вызов функций с помощью:
# To disable automatic function calling:
config = types.GenerateContentConfig(
tools=[get_current_temperature],
automatic_function_calling=types.AutomaticFunctionCallingConfig(disable=True)
)
Автоматическое объявление схемы функции
Автоматическое извлечение схемы из функций Python работает не во всех случаях. Например: он не обрабатывает случаи, когда вы описываете поля вложенного объекта-словаря. API способен описывать любой из следующих типов:
AllowedType = (int | float | bool | str | list['AllowedType'] | dict[str, AllowedType])
Чтобы увидеть, как выглядит выведенная схема, вы можете преобразовать ее с помощью from_callable
:
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 .
# 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")
// 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 .
Поддерживаемые модели
Экспериментальные модели не включены. С их возможностями вы можете ознакомиться на странице обзора модели .
Модель | Вызов функции | Параллельный вызов функций | Композиционный вызов функций (Только Live API) |
---|---|---|---|
Близнецы 2.0 Флэш | ✔️ | ✔️ | ✔️ |
Близнецы 2.0 Флэш-Лайт | Х | Х | Х |
Близнецы 1.5 Флэш | ✔️ | ✔️ | ✔️ |
Близнецы 1.5 Про | ✔️ | ✔️ | ✔️ |
Лучшие практики
- Описания функций и параметров. Будьте предельно ясны и конкретны в своих описаниях. Модель полагается на них, чтобы выбрать правильную функцию и предоставить соответствующие аргументы.
- Именование: используйте описательные имена функций (без пробелов, точек и тире).
- Строгая типизация: используйте определенные типы (целое число, строка, перечисление) для параметров, чтобы уменьшить количество ошибок. Если параметр имеет ограниченный набор допустимых значений, используйте перечисление.
- Оперативное проектирование:
- Предоставьте контекст: расскажите модели о ее роли (например, «Вы полезный помощник погоды»).
- Дайте инструкции: укажите, как и когда использовать функции (например, «Не угадывайте даты; всегда используйте будущую дату для прогнозов»).
- Поощряйте разъяснения: попросите модель задавать уточняющие вопросы, если это необходимо.
- Температура: используйте низкую температуру (например, 0) для более детерминированных и надежных вызовов функций.
- Проверка: если вызов функции имеет серьезные последствия (например, размещение заказа), подтвердите вызов вместе с пользователем перед его выполнением.
- Обработка ошибок . Внедрите надежную обработку ошибок в свои функции, чтобы корректно обрабатывать неожиданные входные данные или сбои API. Возвращайте информативные сообщения об ошибках, которые модель может использовать для генерации полезных ответов пользователю.
- Безопасность. Помните о безопасности при вызове внешних API. Используйте соответствующие механизмы аутентификации и авторизации. Избегайте раскрытия конфиденциальных данных при вызовах функций.
- Ограничения токенов: описания функций и параметры учитываются при расчете лимита входных токенов. Если вы достигаете предела токенов, рассмотрите возможность ограничения количества функций или длины описаний, разбейте сложные задачи на более мелкие и более целенаправленные наборы функций.
Примечания и ограничения
- Поддерживается только часть схемы OpenAPI .
- Поддерживаемые типы параметров в Python ограничены.
- Автоматический вызов функций — это только функция Python SDK.