Articles

Function Calling в AI: Как LLM взаимодействуют с внешними инструментами

Function Calling в AI: Как LLM взаимодействуют с внешними инструментами
Mikhail
Автор
Mikhail
Опубликовано 21.08.2025
0,0
Views 8

Function Calling — это ключевой механизм, позволяющий искусственному интеллекту (AI) взаимодействовать с внешними системами, инструментами и базами данных. В эпоху, где большие языковые модели (LLM) становятся основными помощниками в бизнесе, науке и повседневных задачах, функциональный вызов становится стратегическим инструментом для расширения возможностей этих моделей. Он позволяет LLM не только генерировать текст, но и выполнять действия, выходящие за рамки их внутренних знаний.

Пример:
Представьте, что пользователь спрашивает: "Какая погода сегодня в Москве?"
Модель не может ответить без доступа к внешним данным, но с помощью функционального вызова она может вызвать API погоды и предоставить точный ответ.

Как это работает: 3 Этапа

1. Формирование структурированного запроса

Модель преобразует запрос пользователя в JSON с указанием:

  • Названия функции
  • Параметров вызова
  • Типов ожидаемых данных

2. Вызов внешней системы

Сервер обрабатывает запрос, вызывает API/базу данных и возвращает результат.

3. Формирование ответа

LLM интерпретирует результат и генерирует ответ на естественном языке.


Примеры function calling

🔧 Базовая структура (универсальный шаблон)

import requests

def call_external_api(function_name, parameters):
    """
    Универсальный обработчик внешних вызовов
    :param function_name: Название функции (соответствует endpoint'у API)
    :param parameters: Словарь параметров
    :return: Данные из API или ошибка
    """
    try:
        # Формирование запроса в едином формате
        payload = {
            "function": function_name,
            "parameters": parameters
        }

        # Отправка запроса с обработкой ошибок
        response = requests.post(
            "https://api.your-service.com/v1/functions",
            json=payload,
            timeout=10
        )
        response.raise_for_status()  # Проверка HTTP-статуса

        # Парсинг и валидация ответа
        result = response.json()
        if "error" in result:
            raise ValueError(f"API Error: {result['error']}")
        return result["data"]

    except requests.exceptions.RequestException as e:
        return {"error": f"Network error: {str(e)}"}
    except ValueError as e:
        return {"error": str(e)}

🌤️ Пример 1: Погода в реальном времени

# Шаг 1: Формирование запроса
user_query = "Какая погода сегодня в Париже?"
function_call = {
    "name": "get_weather",
    "arguments": {"city": "Paris", "units": "metric"}
}

# Шаг 2: Вызов API через обработчик
weather_data = call_external_api(
    function_call["name"],
    function_call["arguments"]
)

# Шаг 3: Обработка результата с проверкой
if "error" in weather_data:
    final_response = f"Не удалось получить данные: {weather_data['error']}"
else:
    # Использование ДАННЫХ ИЗ API, а не хардкода!
    temp = weather_data.get("temperature", "N/A")
    description = weather_data.get("description", "без описания")
    final_response = (
        f"Сейчас в Париже {temp}°C, {description}. "
        f"Влажность: {weather_data.get('humidity', '?')}%"
    )

print(final_response)

📈 Кейс 1: Финансовый анализ (реальный сценарий)

def analyze_sales():
    # Получение данных из базы
    sales_data = call_external_api("query_sales_db", {
        "period": "2023-Q4",
        "region": "EU"
    })

    if "error" in sales_data:
        return f"Ошибка базы данных: {sales_data['error']}"

    # Анализ с проверкой данных
    total = sum(sales_data["sales"])
    avg = total / len(sales_data["sales"]) if sales_data["sales"] else 0

    # Формирование отчета с контекстом
    return (
        f"Анализ продаж за 2023-Q4 (Европа):\n"
        f"- Общий объем: ${total:,.2f}\n"
        f"- Средний чек: ${avg:,.2f}\n"
        f"- Лучший день: {sales_data['best_day']}"
    )

print(analyze_sales())

💡 Интеграция с OpenAI API (настоящий Function Calling)

Вот как работает настоящий Function Calling в современных LLM (на примере OpenAI GPT-4):

Шаг 1: Определение функций

import openai

# Описание функции для OpenAI
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "Получить текущую погоду в указанном городе",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "Город и страна, например: Москва, Россия"
                    },
                    "unit": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"],
                        "default": "celsius"
                    }
                },
                "required": ["location"]
            },
            "returns": {
                "type": "object",
                "properties": {
                    "temperature": {"type": "number"},
                    "unit": {"type": "string"},
                    "description": {"type": "string"}
                }
            }
        }
    }
]

Шаг 2: Вызов модели с функциями

response = openai.chat.completions.create(
    model="gpt-4-turbo",
    messages=[
        {"role": "user", "content": "Какая погода в Токио?"}
    ],
    tools=tools,
    tool_choice="auto"  # Модель сама решает, когда вызывать функцию
)

Шаг 3: Обработка вызова функции

# Проверка, требуется ли вызов функции
if response.choices[0].message.tool_calls:
    tool_call = response.choices[0].message.tool_calls[0]

    # Извлечение параметров
    function_args = eval(tool_call.function.arguments)
    location = function_args["location"]

    # Реальный вызов API (ваш код!)
    weather_data = call_external_api(
        "get_current_weather", 
        {"location": location, "unit": "celsius"}
    )

    # Отправка результата обратно в модель
    second_response = openai.chat.completions.create(
        model="gpt-4-turbo",
        messages=[
            {"role": "user", "content": "Какая погода в Токио?"},
            response.choices[0].message,  # Первый ответ с tool_call
            {
                "role": "tool",
                "content": str(weather_data),
                "tool_call_id": tool_call.id
            }
        ]
    )

    print("Окончательный ответ:", second_response.choices[0].message.content)

🔍 Пошаговая инструкция для разработчика

1. Подготовка функций

# Шаблон описания функции для OpenAI
def define_tool(name, description, parameters, returns):
    return {
        "type": "function",
        "function": {
            "name": name,
            "description": description,
            "parameters": {
                "type": "object",
                "properties": parameters,
                "required": [k for k, v in parameters.items() if v.get("required", False)]
            },
            "returns": returns
        }
    }

# Пример использования
weather_tool = define_tool(
    name="get_current_weather",
    description="Получить текущую погоду",
    parameters={
        "location": {
            "type": "string",
            "description": "Город и страна",
            "required": True
        },
        "unit": {
            "type": "string",
            "enum": ["celsius", "fahrenheit"],
            "default": "celsius"
        }
    },
    returns={
        "type": "object",
        "properties": {
            "temperature": {"type": "number"},
            "unit": {"type": "string"},
            "conditions": {"type": "string"}
        }
    }
)

2. Обработка ошибок (лучшие практики)

def safe_api_call(function_name, params, max_retries=2):
    for attempt in range(max_retries + 1):
        try:
            # Ваш код вызова API
            return call_external_api(function_name, params)
        except Exception as e:
            if attempt == max_retries:
                log_error(f"API failed after {max_retries} attempts: {str(e)}")
                return {"error": "Сервис временно недоступен"}
            time.sleep(1 * (attempt + 1))  # Экспоненциальная задержка

3. Кэширование данных

from functools import lru_cache

@lru_cache(maxsize=100)
def cached_weather(city, units="metric"):
    """Кэширование погодных данных на 10 минут"""
    return call_external_api("get_weather", {"city": city, "units": units})

# Использование
print(cached_weather("London"))  # Первый вызов - реальный запрос
print(cached_weather("London"))  # Второй вызов - из кэша

⚖️ Сравнение Методов Реализации

Метод Когда использовать Пример кода
Прямой API-вызов Для кастомных интеграций requests.post(url, json=payload)
OpenAI Function Calling При работе с GPT-4 и аналогами tools=[{...}], tool_choice="auto"
Библиотеки-обертки Для популярных сервисов (Stripe, Twilio) stripe.Charge.create(...)
Локальные функции Для внутренней логики def calculate_tax(amount): ...

🔑 Best Practices

1. Валидация параметров

def validate_parameters(params, schema):
    """Проверка параметров перед вызовом API"""
    for field, rules in schema.items():
        if rules.get("required") and field not in params:
            raise ValueError(f"Missing required parameter: {field}")
        if "enum" in rules and params.get(field) not in rules["enum"]:
            raise ValueError(f"Invalid value for {field}")

2. Безопасность

# Никогда не храните ключи в коде!
import os
API_KEY = os.getenv("WEATHER_API_KEY")

# Используйте секрет-менеджеры в production
from google.cloud import secretmanager
def get_secret(secret_name):
    client = secretmanager.SecretManagerServiceClient()
    name = f"projects/my-project/secrets/{secret_name}/versions/latest"
    return client.access_secret_version(name=name).payload.data.decode("UTF-8")

3. Тестирование

# Пример unit-теста для обработчика API
def test_weather_api():
    mock_response = {"data": {"temperature": 22, "description": "ясно"}}
    with patch("requests.post", return_value=MockResponse(mock_response)):
        result = call_external_api("get_weather", {"city": "Test"})
        assert result["temperature"] == 22

В заключении о Function Calling

Function Calling — это стратегический инструмент, позволяющий AI преодолеть ограничения внутренних знаний и взаимодействовать с реальным миром. Он делает модели более универсальными, способными решать задачи, требующие доступа к данным, расчетам или внешним системам.

Чтобы эффективно использовать функциональный вызов, важно:
- Понимать, какие задачи требуют внешнего взаимодействия.
- Выбирать подходящие инструменты и API.
- Оптимизировать запросы и обрабатывать ошибки.
- Регулярно тестировать и улучшать систему.

С помощью function calling искусственный интеллект может стать не просто помощником, но и ключевым элементом цифровой трансформации бизнеса, науки и повседневной жизни.

Авторизуйтесь, чтобы оставить комментарий.

Комментариев: 0

Нет комментариев.