1. Введение в вызов функций

В модели GPT вызов функций означает предоставление описательных функций модели через API, позволяя ей интеллектуально выбирать и выводить объект JSON, содержащий параметры для вызова одной или нескольких функций. Важно отметить, что API для заполнения диалогов не выполняет функции напрямую, а генерирует JSON для выполнения функций в коде.

Проще говоря, функция вызова функций предполагает предоставление набора определений функций (включая описания функций и параметров) модели GPT. Затем модель решает, какую функцию вызвать на основе запроса пользователя. Поскольку модель не может выполнить внешние функции, она может только ответить запросом о том, какую функцию вызвать (включая параметры вызова функции). После получения результата запроса модели наша программа выполняет вызов функции локально. Результат вызова функции затем объединяется с запросом и отправляется обратно модели для дальнейшей обработки, прежде чем окончательный результат возвращается пользователю.

2. Сценарии применения вызова функций

Вот несколько примеров его практического применения:

  • Создание помощника для ответов на вопросы с помощью вызова внешних API, например, определение функций типа send_email(to: string, body: string) или get_current_weather(location: string, unit: 'celsius' | 'fahrenheit').
  • Преобразование естественного языка в вызовы API, например, перевод фразы "Кто мои лучшие клиенты?" в get_customers(min_revenue: int, created_before: string, limit: int) с последующим внутренним вызовом API.
  • Извлечение структурированных данных из текста, например, определение функций типа extract_data(name: string, birthday: string) или sql_query(query: string).

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

3. Модели, поддерживающие вызов функций

Не все версии модели обучены данным по вызову функций. В настоящее время поддержку вызова функций имеют модели: gpt-4, gpt-4-turbo-preview, gpt-4-0125-preview, gpt-4-1106-preview, gpt-4-0613, gpt-3.5-turbo, gpt-3.5-turbo-1106 и gpt-3.5-turbo-0613.

Кроме того, модели gpt-4-turbo-preview, gpt-4-0125-preview, gpt-4-1106-preview и gpt-3.5-turbo-1106 поддерживают параллельный вызов функций, позволяя выполнять несколько вызовов функций одновременно и обрабатывать их параллельно для достижения эффективных и эффективных результатов.

Примечание: потенциальный риск, связанный с функцией вызова, заключается в том, что она может привести к тому, что модель будет создавать ошибочные параметры (так называемые "фантомные параметры"). Поэтому перед принятием любых действий, влияющих на реальный мир (например, отправка электронных писем, онлайн-публикация, совершение покупок и т. д.), рекомендуется внедрить процесс подтверждения пользователя на уровне продукта, обеспечивая выполнение функций только после подтверждения пользователя.

4. Примеры вызова функций

4.1 Пример на Python

Внедрение вызова функций на платформе OpenAI обычно следует основным шагам, изложенным ниже. Ниже подробно описан весь процесс с использованием примера кода на Python, с фокусом на запрос погоды.

Шаг 1: Подготовьте вызываемые функции и определения функций для модели

Сначала нам нужно определить функцию, которую может вызвать модель GPT. Обычно это означает подготовку собственной функции, которая может выполнять определенные операции на основе входных параметров, например, взаимодействие с API стороннего разработчика.

import json

def get_current_weather(location, unit="fahrenheit"):
    return json.dumps({
        "location": location,
        "temperature": "18",
        "unit": unit
    })

Шаг 2: Вызов модели на основе параметра запроса и инструментов

Затем нам нужно вызвать модель GPT через API завершения чата и передать запрос пользователя (например, "Какая текущая погода") а также параметр tools, который включает описание функции get_current_weather, которую мы только что определили.

from openai import OpenAI

client = OpenAI()

tools = [{
    "type": "function",
    "function": {
        "name": "get_current_weather",
        "description": "Получить текущую погоду для указанного местоположения",
        "parameters": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "Название города, например: 'Сан-Франциско, Калифорния'"
                },
                "unit": {
                    "type": "string",
                    "enum": ["цельсий", "фаренгейт"]
                }
            },
            "required": ["location"]
        }
    }
}]

response = client.chat.completions.create(
    model="gpt-3.5-turbo",
    messages=[{"role": "user", "content": "Какая текущая погода в Сан-Франциско?"}],
    tools=tools
)

Шаг 3: Выполнение функции локально

Результат, возвращаемый моделью, будет содержать информацию о вызове функции, обычно содержащуюся в ответном параметре tool_calls. Затем мы можем выполнить соответствующий вызов функции локально на основе информации о вызове функции, описанной в параметре tool_calls.

tool_calls = response.choices[0].message.tool_calls

if tool_calls:
    arguments = json.loads(tool_calls[0].function.arguments)
    weather_info = get_current_weather(**arguments)
    print(weather_info) # Здесь мы можем увидеть информацию о погоде, запрошенную вызовом функции

Шаг 4: Повторный вызов модели с результатом вызова функции

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

follow_up_response = client.chat.completions.create(
    model="gpt-3.5-turbo",
    messages=[
        {"role": "user", "content": "Какая текущая погода в Сан-Франциско?"},
        {"role": "function", "name": "get_current_weather", "content": weather_info}
    ],
    tools=tools
)

Объяснение: В приведенном выше примере результат вызова функции отправляется в модель GPT через сообщение функции следующим образом:

{"role": "function", "name": "get_current_weather", "content": weather_info}

На практике вы также можете просто поместить результат вызова функции в качестве ссылочного содержимого в системное сообщение для того, чтобы ИИ мог использовать его при ответе на вопросы.

Шаг 5: Получение окончательного ответа от модели

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

final_output = follow_up_response.choices[0].message.content
print(final_output) # Этот вывод представляет информацию о погоде, которую мы хотим показать пользователю

Следуя вышеприведенным шагам, мы завершили полный пример запроса погоды с использованием модели GPT и вызовов функций.

4.2. Объяснение определения функции вызова функции

4.2.1 Значение полей параметра "Инструменты"

При вызове функции необходимо определить соответствующую информацию функции в параметре tools. Параметр tools является массивом, содержащим несколько определений функций, и каждое определение функции включает в себя следующие поля:

  1. type: Это поле представляет тип инструмента. При вызове функции это поле должно быть установлено на "function".
  2. function: Это поле содержит подробную информацию о функции и является объектом со следующими конкретными полями:
    • name: Название функции, которое является строкой.
    • description: Описание цели функции, которое может помочь модели генерировать параметры, соответствующие ожиданиям пользователя.
    • parameters: Описывает определения параметров функции и является объектом, содержащим следующие подполя:
      • type: Определяет тип параметра, который в большинстве случаев должен быть установлен на "object".
      • properties: Конкретные определения каждого параметра функции, где каждое определение параметра является объектом, обычно содержащим следующие подполя:
        • type: Тип данных параметра (например, "string", "integer", "boolean", и т.д.).
        • description: Описание параметра, чтобы модель понимала его цель.
        • enum (опционально): Когда type установлен на "string", поле enum может указать массив строк, представляющий набор допустимых значений.
      • required: Массив строк, содержащий имена обязательных параметров.

4.2.2 Примеры определений инструментов

Теперь давайте приведем несколько примеров определений tools, чтобы помочь понять, как используется каждое поле.

Пример 1: Получение информации о текущей погоде

{
    "type": "function",
    "function": {
        "name": "get_current_weather",
        "description": "Получить информацию о текущей погоде для указанного местоположения",
        "parameters": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "Город, для которого необходимо запросить погоду, например, 'Сан-Франциско, Калифорния'"
                },
                "unit": {
                    "type": "string",
                    "enum": ["цельсий", "фаренгейт"],
                    "description": "Единица температуры, 'цельсий' для Цельсия, 'фаренгейт' для Фаренгейта"
                }
            },
            "required": ["location", "unit"]
        }
    }
}

В приведенном выше примере мы определили функцию с именем get_current_weather для получения текущей погоды указанного местоположения. Параметры включают location и unit, где unit имеет два допустимых значения: "цельсий" (Цельсий) и "фаренгейт" (Фаренгейт).

Пример 2: Поиск альбомов для конкретного исполнителя

{
    "type": "function",
    "function": {
        "name": "find_artist_albums",
        "description": "Найти все альбомы для конкретного исполнителя",
        "parameters": {
            "type": "object",
            "properties": {
                "artist_name": {
                    "type": "string",
                    "description": "Имя исполнителя"
                }
            },
            "required": ["artist_name"]
        }
    }
}

В этом примере мы создали функцию под названием find_artist_albums для поиска всех альбомов конкретного исполнителя. Эта функция требует только один параметр: artist_name (имя исполнителя).

4.3. Пример вызова функции HTTP-запроса

OpenAI предоставляет API, доступный через протокол HTTP. Ниже мы объясним, как использовать функцию вызова через HTTP API. Разработчики других языков программирования могут обратиться к этому примеру.

4.3.1. Шаг 1: Вызов модели с запросом пользователя и объявлением функции

Сначала нам нужно отправить запрос пользователя и список поддерживаемых нами функций модели GPT, чтобы модель могла автоматически проанализировать, какую функцию вызвать для ответа на запрос пользователя на основе вопроса пользователя.

В следующем примере мы информируем GPT о том, что у нас есть функция get_current_weather, которую можно использовать для запроса информации о погоде для указанного города.

curl --location 'https://api.aiproxy.io/v1/chat/completions' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {OPENAI_KEY}' \
--data '{
    "model": "gpt-3.5-turbo",
    "messages": [
        {
            "role": "user",
            "content": "Какая погода в Шанхае сегодня?"
        }
    ],
    "tools": [
        {
            "type": "function",
            "function": {
                "name": "get_current_weather",
                "description": "Получить текущую информацию о погоде для указанного местоположения",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "location": {
                            "type": "string",
                            "description": "Город, для которого необходимо запросить погоду, например, 'Сан-Франциско, Калифорния'"
                        },
                        "unit": {
                            "type": "string",
                            "enum": [
                                "celsius",
                                "fahrenheit"
                            ],
                            "description": "Единица температуры, 'celsius' для Цельсия, 'fahrenheit' для Фаренгейта"
                        }
                    },
                    "required": [
                        "location",
                        "unit"
                    ]
                }
            }
        }
    ]
}'

Объяснение параметров запроса:

{
    "model": "gpt-3.5-turbo", // Вызываемая модель GPT
    "messages": [ // Это список сообщений для GPT, включая запрос пользователя
        {
            "role": "user",
            "content": "Какая погода в Шанхае сегодня?"
        }
    ],
    "tools": [
	  // Это определение вашей функции, информирующее GPT о доступных функциях
    ]
}

См. раздел 4.2.2 для определения параметра tools.

В нормальной обработке моделью GPT вы получите API-ответ, аналогичный следующему:

{
    "model": "gpt-3.5-turbo-0613",
    "object": "chat.completion",
    "usage": {
        "prompt_tokens": 122,
        "completion_tokens": 27,
        "total_tokens": 149
    },
    "id": "chatcmpl-8mL4hS4zNMocyR2ajKyAvSTcbNaao",
    "created": 1706531447,
    "choices": [
        {
            "index": 0,
            "delta": null,
            "message": {
                "role": "assistant",
                "tool_calls": [ // Параметр tool_calls представляет список функций, которые GPT хочет вызвать
                    {
                        "id": "call_1iF09ttX1R9ESR18Ul2nLe1R",
                        "type": "function",
                        "function": {
                            "name": "get_current_weather",  // Указывает, что GPT хочет ответить на запрос пользователя, вызвав функцию get_current_weather
                            "arguments": "{\n  \"location\": \"Шанхай, Китай\",\n  \"unit\": \"celsius\"\n}" // Это входной параметр для вызова функции get_current_weather
                        }
                    }
                ]
            },
            "finish_reason": "tool_calls"
        }
    ]
}

4.3.2. Шаг 2: Локальное выполнение вызова функции

Поскольку сама модель GPT не может выполнить определённые вызовы функций и только информирует нас, какую функцию она хочет вызвать, наша локальная программа должна выполнить конкретный вызов функции на основе параметра tool_calls, возвращаемого моделью. Способ выполнения локальных функций различается в разных языках программирования. Например, в Python вы можете обратиться к предыдущему разделу.

4.3.3. Шаг 3: Вызов модели снова с результатом выполнения функции

Поскольку вызов функции выполняется локально, нам нужно передать результат выполнения функции и вопрос пользователя обратно в модель GPT, чтобы получить окончательный ответ.

curl --location 'https://api.aiproxy.io/v1/chat/completions' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer sk-Roc5MX1zEuVxiuaMaETV6wZ2jXcCehjUCzwP9AcNErUiwppQ' \
--data '{
    "model": "gpt-3.5-turbo",
    "messages": [
        {
            "role": "user",
            "content": "Какая сегодня погода в Шанхае?"
        },
        {
            "role": "function",
            "name": "get_current_weather",
            "content": "{\"city\":\"Shanghai\", \"temperature\":\"25 градусов Цельсия\"}"
        }
    ],
    "tools": [
        {
            "type": "function",
            "function": {
                "name": "get_current_weather",
                "description": "Получить текущую информацию о погоде для указанного местоположения",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "location": {
                            "type": "string",
                            "description": "Город, для которого запрашивается погода, например, 'Сан-Франциско, Калифорния'"
                        },
                        "unit": {
                            "type": "string",
                            "enum": [
                                "celsius",
                                "fahrenheit"
                            ],
                            "description": "Единица температуры, 'celsius' для Цельсия, 'fahrenheit' для Фаренгейта"
                        }
                    },
                    "required": [
                        "location",
                        "unit"
                    ]
                }
            }
        }
    ]
}'

Примечание: В вышеуказанном запросе добавлено дополнительное функциональное сообщение для информирования модели GPT о возвращаемом значении функции. GPT непосредственно ответит на вопрос пользователя на основе информации о возвращаемом значении функции и не вызовет функцию снова.

Сообщение функции представляет собой возвращаемое значение функции и следует формату ниже:

{
    "role": "function", // Тип сообщения - функция, указывающий на возвращаемое значение функции
    "name": "get_current_weather", // Информирует GPT, что текущее сообщение - это возвращаемое значение функции get_current_weather
    "content": "{\"city\":\"Shanghai\", \"temperature\":\"25 градусов Цельсия\"}" // Содержимое возвращаемого значения функции, может быть в формате JSON или другом текстовом формате.
}

Ниже приведен окончательный ответ, сгенерированный GPT:

{
    "model": "gpt-3.5-turbo-0613",
    "object": "chat.completion",
    "usage": {
        "prompt_tokens": 144,
        "completion_tokens": 17,
        "total_tokens": 161
    },
    "id": "chatcmpl-8mLmvvKAjSql7rGF8fvQeddKhWYvr",
    "created": 1706534189,
    "choices": [
        {
            "index": 0,
            "delta": null,
            "message": {
                "role": "assistant",
                "content": "Сегодня в Шанхае температура составляет 25 градусов Цельсия."
            },
            "finish_reason": "stop"
        }
    ]
}