Вызов функции OpenAI для обеспечения format/schema
Привет, читатели блога dev-gang! В июле 2023 года OpenAI представила вызов функций — функцию, лежащую в основе экосистемы плагинов ChatGPT.
Что мне показалось особенно полезным, так это не возможность запуска внешних API и встраивания ответов в диалоги... А обещание того, что новые модели настроены на возврат структурированных данных:
Эти модели были точно настроены, чтобы как определять, когда необходимо вызвать функцию (в зависимости от ввода пользователя), так и реагировать с помощью JSON, который соответствует сигнатуре функции. Вызов функций позволяет разработчикам более надежно получать структурированные данные из модели.
Раньше нужно было попросить модель ответить в формате JSON/XML/что-то еще и предоставить определение схемы где-нибудь в подсказке или диалоге. И, вероятно, кто-то сталкивался с проблемами, когда многие ответы не соответствовали ожиданиям. Теперь для этого в вызове API есть отдельное поле, и OpenAI гарантирует, что модель не будет отвечать в других форматах (пока она определяет необходимость вызова функции).
Умная проверка
Один из вариантов использования, который я видел на практике, — это семантическая проверка больших форм. Вместо обычных валидаторов (проверка пустых полей, минимальной длины или регулярного выражения для электронных писем) LLM теперь могут понимать значение данных.
Подготовив хорошую подсказку с достаточным количеством объяснений и четкими критериями, вы можете поручить ИИ-клерку выполнять тяжелую работу: просматривать онлайн-заявки. В нашем случае это был процесс признания, когда людей номинировали на награду (вспомним внутреннюю компанию «Оскар» с сотнями заявок).
Код и подсказка
const body = JSON.stringify({
"messages": [
{
"role": "system",
"content": priming
},
{
"role": "user",
"content": descriptions
},
{
"role": "user",
"content": nominee
}
],
"functions": [
{
"name": functionName,
"description": "Sends validation results of nominee's submission and determines\
if the submission requries rework or can be marked as OK and sent for further processing",
"parameters": {
"type": "object",
"properties": {
"status": {
"type": "string",
"description": "Determines if validation is OK or not",
"enum": ["OK", "NOT-OK"]
},
"recommendations": {
"type": "string",
"description": "Empty if there're no objections and the submission has passed validation. \
Otherwise explains why validation was not passed. The result is a slightly styled text formatted \
as HTML (using paragraphs, lists, bold fonts where necessary)",
}
},
"required": ["status", "recommendations"]
}
}
],
"temperature": 0.0,
"frequency_penalty": 0,
"presence_penalty": 0,
"n": 1,
"max_tokens": 400,
"top_p": 0.95
});
Это типичное тело запроса OpenAI для завершения чата с одним новым полем: functions
.
Идея состоит в том, чтобы притвориться, что необходимо выполнить вызов функции, и использовать только параметры, возвращаемые LLM:
obj = JSON.parse(data.choices[0].message.function_call.arguments);
Чтобы заставить GPT возвращать вызов функции (помимо описаний функций и параметров, как показано выше), я усилил требование, добавив эту часть в системное приглашение:
Ваш вывод должен быть вызовом функции с двумя полями:
• статус – возможные значения: «ОК» (претензий нет, кандидатура может перейти к следующему шагу) и «НЕ ОК» (вы выявили недостатки и имеете рекомендации)
• рекомендации – если у вас есть сомнения по поводу представленного материала (как указано выше) и вы хотите отправить его обратно на доработку, предоставьте результаты проверки и перечислите свои аргументы здесь.
Также обратите внимание, что при выполнении вызова вам необходимо использовать более позднюю версию API (убедитесь, что в URL-адресе указано. ?api-version=2023-07-01-preview
).
Полный пример на TypeScript находится здесь.
Полученные результаты
С контекстом gpt3.5 и 16k
это работало как шарм. OpenAI всегда возвращал действительный JSON (по крайней мере, во время отладки не проверял телеметрию продукта).
Я попробовал и вызов функции, и старые подсказки «Пожалуйста, ответьте с помощью JSON...». Последний использовался для предоставления аномалий. Иногда поле recommendations
содержало список элементов JSON вместо произвольного текста.
Привязка к поставщику
Если позже вы решите сменить поставщика LLM, вы можете обнаружить, что в их модели нет возможности вызова функций. Или соответствующие поля API отличаются. Свободные текстовые разговоры по-прежнему более портативны.
P.S.: Некоторое время назад я наткнулся на этот репозиторий, который намекает на один из методов реализации (помимо тонкой настройки) таких функций, как вызов функций, обеспечивающих структурированные ответы. Regex можно использовать в качестве промежуточного фильтра во время генерации токенов и повысить вероятность того, что токены будут следовать требуемому шаблону.