Начать пользоваться на www.aijora.ru
AijoraДокументация
Функции

Вызов функций

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();
}