Функции
Вызов функций
Function Calling — вызов внешних функций через API
Function Calling (вызов функций) позволяет моделям вызывать внешние функции и API. Модель определяет, когда нужно вызвать функцию, какую функцию вызвать и с какими параметрами.
Как работает Function Calling
[Пользователь спрашивает]
↓
[Модель анализирует запрос]
↓
[Модель решает вызвать функцию]
↓
[Возвращает JSON с названием функции и параметрами]
↓
[Ваш код выполняет функцию]
↓
[Отправляете результат обратно модели]
↓
[Модель формулирует финальный ответ]
Проверка поддержки
Базовый пример
Создадим простую функцию получения погоды.
Шаг 1: Определяем функцию
// Реальная функция, которую будем вызывать
function getCurrentWeather(location, unit = "celsius") {
// В продакшене здесь был бы запрос к API погоды
if (location.toLowerCase().includes("москва")) {
return JSON.stringify({
location: "Москва",
temperature: -5,
unit: unit,
conditions: "Снег"
});
}
return JSON.stringify({
location: location,
temperature: "неизвестно"
});
}
import json
def get_current_weather(location, unit="celsius"):
"""Получить текущую погоду в указанном месте"""
# В продакшене здесь был бы запрос к API погоды
if "москва" in location.lower():
return json.dumps({
"location": "Москва",
"temperature": -5,
"unit": unit,
"conditions": "Снег"
})
return json.dumps({
"location": location,
"temperature": "неизвестно"
})
Шаг 2: Описываем функцию для модели
const tools = [
{
type: "function",
function: {
name: "getCurrentWeather",
description: "Получить текущую погоду в указанном городе",
parameters: {
type: "object",
properties: {
location: {
type: "string",
description: "Город и регион, например Москва, Россия"
},
unit: {
type: "string",
enum: ["celsius", "fahrenheit"],
description: "Единица измерения температуры"
}
},
required: ["location"]
}
}
}
];
Шаг 3: Первый запрос к API
const response = await fetch('https://api.aijora.com/api/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.AIJORA_API_KEY}`
},
body: JSON.stringify({
model: 'gpt-4o-mini',
messages: [
{ role: 'user', content: 'Какая сейчас погода в Москве?' }
],
tools: tools,
tool_choice: 'auto' // Модель сама решит, вызывать ли функцию
})
});
const data = await response.json();
const message = data.choices[0].message;
console.log('Ответ модели:', message);
import os
import requests
response = requests.post(
'https://api.aijora.com/api/v1/chat/completions',
headers={
'Authorization': f'Bearer {os.getenv("AIJORA_API_KEY")}'
},
json={
'model': 'gpt-4o-mini',
'messages': [
{'role': 'user', 'content': 'Какая сейчас погода в Москве?'}
],
'tools': tools,
'tool_choice': 'auto'
}
)
data = response.json()
message = data['choices'][0]['message']
print('Ответ модели:', message)
Ответ от модели
Модель вернёт что-то вроде:
{
"role": "assistant",
"content": null,
"tool_calls": [
{
"id": "call_abc123",
"type": "function",
"function": {
"name": "getCurrentWeather",
"arguments": "{\"location\": \"Москва, Россия\", \"unit\": \"celsius\"}"
}
}
]
}
Шаг 4: Выполняем функцию
// Проверяем, хочет ли модель вызвать функцию
if (message.tool_calls) {
// Доступные функции
const availableFunctions = {
getCurrentWeather: getCurrentWeather
};
// Добавляем ответ ассистента в историю
const messages = [
{ role: 'user', content: 'Какая сейчас погода в Москве?' },
message
];
// Обрабатываем каждый вызов функции
for (const toolCall of message.tool_calls) {
const functionName = toolCall.function.name;
const functionToCall = availableFunctions[functionName];
const functionArgs = JSON.parse(toolCall.function.arguments);
// Вызываем функцию
const functionResponse = functionToCall(
functionArgs.location,
functionArgs.unit
);
// Добавляем результат в сообщения
messages.push({
tool_call_id: toolCall.id,
role: 'tool',
name: functionName,
content: functionResponse
});
}
}
import json
# Проверяем, хочет ли модель вызвать функцию
if message.get('tool_calls'):
# Доступные функции
available_functions = {
"getCurrentWeather": get_current_weather
}
# Добавляем ответ ассистента в историю
messages = [
{'role': 'user', 'content': 'Какая сейчас погода в Москве?'},
message
]
# Обрабатываем каждый вызов функции
for tool_call in message['tool_calls']:
function_name = tool_call['function']['name']
function_to_call = available_functions[function_name]
function_args = json.loads(tool_call['function']['arguments'])
# Вызываем функцию
function_response = function_to_call(
location=function_args.get('location'),
unit=function_args.get('unit')
)
# Добавляем результат в сообщения
messages.append({
'tool_call_id': tool_call['id'],
'role': 'tool',
'name': function_name,
'content': function_response
})
Шаг 5: Второй запрос к модели
Теперь отправляем результат функции обратно модели:
const secondResponse = await fetch('https://api.aijora.com/api/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.AIJORA_API_KEY}`
},
body: JSON.stringify({
model: 'gpt-4o-mini',
messages: messages
})
});
const secondData = await secondResponse.json();
console.log('Финальный ответ:', secondData.choices[0].message.content);
// "В Москве сейчас -5°C и идёт снег."
second_response = requests.post(
'https://api.aijora.com/api/v1/chat/completions',
headers={
'Authorization': f'Bearer {os.getenv("AIJORA_API_KEY")}'
},
json={
'model': 'gpt-4o-mini',
'messages': messages
}
)
second_data = second_response.json()
print('Финальный ответ:', second_data['choices'][0]['message']['content'])
# "В Москве сейчас -5°C и идёт снег."
Полный пример
async function chatWithFunctions(userMessage) {
// Определяем функцию
function getCurrentWeather(location, unit = "celsius") {
if (location.toLowerCase().includes("москва")) {
return JSON.stringify({ location: "Москва", temperature: -5, unit, conditions: "Снег" });
}
return JSON.stringify({ location, temperature: "неизвестно" });
}
// Описываем функцию для модели
const tools = [{
type: "function",
function: {
name: "getCurrentWeather",
description: "Получить текущую погоду",
parameters: {
type: "object",
properties: {
location: { type: "string", description: "Город" },
unit: { type: "string", enum: ["celsius", "fahrenheit"] }
},
required: ["location"]
}
}
}];
const messages = [{ role: 'user', content: userMessage }];
// Первый запрос
const response = await fetch('https://api.aijora.com/api/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.AIJORA_API_KEY}`
},
body: JSON.stringify({
model: 'gpt-4o-mini',
messages,
tools,
tool_choice: 'auto'
})
});
const data = await response.json();
const message = data.choices[0].message;
messages.push(message);
// Если модель хочет вызвать функцию
if (message.tool_calls) {
const availableFunctions = { getCurrentWeather };
for (const toolCall of message.tool_calls) {
const fn = availableFunctions[toolCall.function.name];
const args = JSON.parse(toolCall.function.arguments);
const result = fn(args.location, args.unit);
messages.push({
tool_call_id: toolCall.id,
role: 'tool',
name: toolCall.function.name,
content: result
});
}
// Второй запрос с результатом функции
const secondResponse = await fetch('https://api.aijora.com/api/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.AIJORA_API_KEY}`
},
body: JSON.stringify({
model: 'gpt-4o-mini',
messages
})
});
const secondData = await secondResponse.json();
return secondData.choices[0].message.content;
}
return message.content;
}
// Использование
const answer = await chatWithFunctions('Какая погода в Москве?');
console.log(answer);
import os
import json
import requests
def chat_with_functions(user_message):
# Определяем функцию
def get_current_weather(location, unit="celsius"):
if "москва" in location.lower():
return json.dumps({"location": "Москва", "temperature": -5, "unit": unit, "conditions": "Снег"})
return json.dumps({"location": location, "temperature": "неизвестно"})
# Описываем функцию для модели
tools = [{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "Получить текущую погоду",
"parameters": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "Город"},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
},
"required": ["location"]
}
}
}]
messages = [{"role": "user", "content": user_message}]
# Первый запрос
response = requests.post(
'https://api.aijora.com/api/v1/chat/completions',
headers={'Authorization': f'Bearer {os.getenv("AIJORA_API_KEY")}'},
json={
'model': 'gpt-4o-mini',
'messages': messages,
'tools': tools,
'tool_choice': 'auto'
}
)
data = response.json()
message = data['choices'][0]['message']
messages.append(message)
# Если модель хочет вызвать функцию
if message.get('tool_calls'):
available_functions = {"get_current_weather": get_current_weather}
for tool_call in message['tool_calls']:
fn = available_functions[tool_call['function']['name']]
args = json.loads(tool_call['function']['arguments'])
result = fn(args.get('location'), args.get('unit'))
messages.append({
'tool_call_id': tool_call['id'],
'role': 'tool',
'name': tool_call['function']['name'],
'content': result
})
# Второй запрос с результатом функции
second_response = requests.post(
'https://api.aijora.com/api/v1/chat/completions',
headers={'Authorization': f'Bearer {os.getenv("AIJORA_API_KEY")}'},
json={'model': 'gpt-4o-mini', 'messages': messages}
)
second_data = second_response.json()
return second_data['choices'][0]['message']['content']
return message.get('content')
# Использование
answer = chat_with_functions('Какая погода в Москве?')
print(answer)
Параллельный вызов функций
Модель может вызвать несколько функций одновременно:
// Вопрос: "Какая погода в Москве, Лондоне и Токио?"
// Модель вернёт:
{
"tool_calls": [
{
"id": "call_1",
"function": { "name": "getCurrentWeather", "arguments": "{\"location\": \"Москва\"}" }
},
{
"id": "call_2",
"function": { "name": "getCurrentWeather", "arguments": "{\"location\": \"Лондон\"}" }
},
{
"id": "call_3",
"function": { "name": "getCurrentWeather", "arguments": "{\"location\": \"Токио\"}" }
}
]
}
Обработайте все вызовы в цикле, как показано выше.
Контроль вызова функций
Параметр tool_choice
контролирует, когда модель может вызывать функции:
{
tool_choice: "auto" // Модель сама решает (по умолчанию)
}
{
tool_choice: "none" // Модель НЕ будет вызывать функции
}
{
tool_choice: {
type: "function",
function: { name: "getCurrentWeather" }
} // Принудительно вызвать конкретную функцию
}
Примеры использования
1. Поиск в базе данных
const tools = [{
type: "function",
function: {
name: "searchProducts",
description: "Поиск товаров в базе данных",
parameters: {
type: "object",
properties: {
query: { type: "string", description: "Поисковый запрос" },
category: { type: "string", description: "Категория товаров" },
max_price: { type: "number", description: "Максимальная цена" }
},
required: ["query"]
}
}
}];
function searchProducts(query, category, max_price) {
// Запрос к вашей БД
return database.search({ query, category, max_price });
}
2. Отправка email
const tools = [{
type: "function",
function: {
name: "sendEmail",
description: "Отправить email пользователю",
parameters: {
type: "object",
properties: {
to: { type: "string", description: "Email получателя" },
subject: { type: "string", description: "Тема письма" },
body: { type: "string", description: "Текст письма" }
},
required: ["to", "subject", "body"]
}
}
}];
3. Работа с API
const tools = [{
type: "function",
function: {
name: "getStockPrice",
description: "Получить текущую цену акции",
parameters: {
type: "object",
properties: {
ticker: { type: "string", description: "Тикер акции (например, AAPL)" }
},
required: ["ticker"]
}
}
}];
async function getStockPrice(ticker) {
const response = await fetch(`https://api.stocks.com/price/${ticker}`);
return await response.json();
}