Prompt Engineer — очень перспективная профессия. На рынке труда, в том числе российском, появляется всё больше вакансий с солидной зарплатой. Удивительно, но к специалистам в этой области, как правило, нет конкретных требований. Иногда кажется, что некоторые компании ищут промпт-инженеров, просто чтобы соответствовать тренду. Недавно я видел в одном из объявлений такой пассаж: «...Будет преимуществом опыт работы на смежной позиции (продактом, дата-сайентистом, разработчиком) и знание Python…».  Если всё перечисленное — только преимущество, то что тогда считать требованиями? Ручное написание промптов и проверка качества на глаз? Для личного использования это работает, но речь идёт о том, что спроектированный промпт будет внедрён в сервис компании, и значит, он будет использоваться потенциально тысячи раз. Что если с какой-то вероятностью он выдает недопустимые ответы?  Мы должны задаться вопросом: «Как часто и насколько хорошо промпт справляется с задачей?». Чтобы дать на это ответ, потребуется отправлять много запросов к LLM с нашей инструкцией и смотреть на результаты. То есть, собирать и анализировать данные. К счастью, сегодня уже можно найти библиотеки, которые предлагают инструменты для автоматизации тестирования промптов. Одна из них — с подробной документацией и большим количеством полезных методов — называется promptfoo. Именно её мы и будем использовать. На мой взгляд, алгоритм проектирования промпта должен выглядеть примерно так: 1. Определение целей и ограничений. 2. Написание чернового варианта промпта.3. Написание тестов для этого промпта.4. Итерации обратная связь/изменение промпта.5. Финальная проверка на статистически значимом количестве экспериментов. Чтобы работа была более наглядной, мы будем следовать этому пайплайну, реализуя чат-бота для онлайн-магазина одежды. 1. Определение целей и ограничений. Нам нужно, чтобы чат-бот давал пользователям всю вложенную в него информацию без каких-либо галлюцинаций. Он должен правильно передавать заявленные в ассортименте названия вещей, цены и размеры, помогать решать стандартные ситуации и не поддерживать общение на сторонние темы. 2. Написание чернового варианта промпта. Первый вариант промпта (далее жирным шрифтом выделены непосредственно инструкции, остальное — модули вложенной информации): «Ты являешься диспетчером техподдержки магазина одежды N3VERZzz. Чтобы валидно ответить на следующий вопрос: "{{input}}", используйследующую информацию:[Ассортимент Магазина] [Информация о Доставке] [Политика Возврата] [Скидки и Акции] [Способы Обратной Связи] [Контактная Информация] [Инструкция для Ответов] — Отвечай на вопросы прямо и кратко. Не повторяй вопрос в ответе.[Инструкции для Запросов не по теме] — Если интенция запроса НЕ попадает ни в одну из перечисленных категорий, задавай уточняющие вопросы и напоминай, что ты являешься диспетчером техподдержки магазина одежды N3VERZzz.[Инструкции по сложным запросам] — Для сложных вопросов, требующих комбинации информации из разных категорий, старайся агрегировать данные так, чтобы ответ был полным и точным. Использу доступную информацию из всех соответствующих разделов для формирования краткого и информативного ответа.[Примеры Ответов] » 3. Написание тестов. Теперь нам нужно протестировать этот промпт с помощью библиотеки promptfoo. Чаще всего я пользуюсь следующими методами: — Метод "contains" проверяет ответ LLM на наличие определенного значения. Поскольку этот метод учитывает регистр букв, его удобно использовать для проверки ожидаемых в ответе числительных. — Метод "regex" предназначен для проверки соответствия выходных данных заданному регулярному выражению. Регулярные выражения позволяют задавать сложные правила поиска и обработки текста. Например, можно проверить, упоминается ли в тексте Санкт-Петербург в разных падежах. — Метод "llm-rubric" проверяет выходные данные, используя встроенную LLM. Этот метод анализирует текст и оценивает его на предмет соответствия заявленным указаниям. Почти все проверки можно реализовать, используя только метод "llm-rubric". Но здесь есть нюансы. Например, проверка на «человекоподобное поведение» может пройти успешно, хотя в ответе прямым текстом будет написано «поскольку я являюсь искусственным интеллектом». Похоже, что основная цель такой проверки - убедиться в релевантности ответа, а не в том, как искусственный интеллект определяет свою идентичность. Давайте напишем первые тесты: Так выглядит наш файл. В providers выбираем модель для тестирования, в prompts передаем файл, в котором находится промпт. Отобразить результаты тестов можно в удобном формате: 4. Итерации обратная связь/изменение промпта. Пока я работал с этим промптом, было очень много итераций 'тест-правка-тест'. Расскажу про самые интересные ошибки и решения.  Периодически ответ LLM начинался с повторения вопроса. Это было топорно и слегка комично — модель будто размышляла вслух. Кажется, я полностью избавился от этого, добавив в инструкцию для ответов input и дополнительное описание ситуации. Изначально было так:[Инструкция для Ответов] — Отвечай на вопросы прямо и кратко. Не повторяй вопрос в ответе. Такое изменение убрало корявости в ответе:[Инструкция для Ответов] — Отвечай на вопросы прямо и кратко. Не повторяй вопрос: «{{input}}» в ответе. Еще один интересный случай произошел с запросом о WhatsApp. Хотя в инструкции единственной указанной социальной сетью был YouTube, LLM подтвердила, что с нашим брендом можно связаться через мессенджер. Дело в том, что в инструкции был дан номер горячей линии, и LLM проявила инициативу, соединив номер телефона с мессенджером.  Конечно, такая дезинформация как минимум разозлила бы пользователя. Эту проблему очень просто решить: нужно прописать, что нет никаких других социальных сетей и мессенджеров, кроме указанных. Но кажется, что понятия, лежащие в концептуальном поле близко друг к другу, будут неизбежно срастаться, и заблаговременно понять, где это произойдет, невозможно. Полностью обезопасить себя от этого не получится, и лучший совет здесь — делать больше тестов и внимательно смотреть на ответы. 5. Финальная проверка. Поскольку этот промпт не является коммерческим проектом, я решил не реализовывать полноценную проверку на статистически значимом количестве экспериментов. Я остановился на тестировании базового функционала, написав в общей сложности 59 тестов. К сожалению, у меня так и не получилось полностью ограничить LLM в ответах на темы, не касающиеся магазина. Как бы я ни запрещал это делать, лояльный GPT хочет поделиться советом. Это достаточно сложная задача (может быть, для GPT-3.5).  При работе с LLM можно установить «температуру» креативности. Если мы выставим её на ноль, то в генерации всегда будет отдаваться предпочтение следующему токену с наибольшим процентом вероятности выхода. Таким образом, на одинаковые вопросы будут одинаковые ответы. Поскольку LLM, имплементированные в сервисы, должны работать с вложенной информацией, в большинстве кейсов предпочтение будет отдаваться повторяемости ответов, а не их креативности. Это значит, что температуру будут выкручивать на ноль, и запускать один и тот же тест два раза будет бессмысленно. Придется писать очень большое количество разнообразных тестов.  Здесь может помочь генерация текста: предоставить LLM текст промпта и уже написанные тесты с указанием сделать нечто похожее. Потом добавить эти тесты, проверить их и повторить операцию еще раз. Во время написания этой статьи я постоянно ловил себя на том, что говорю очевидные вещи. Я продолжал работу только потому, что не нашел никого, кто бы высказал эту точку зрения. Мы наблюдаем зачаток новой профессии, поэтому сейчас в этой области нет стандартов. Впереди много исследований и открытий, которые через время сформируют эту область. Кажется, если промпт-инженер станет промпт-аналитиком, это не только многократно увеличит его вклад, но и даст возможность говорить с отделом разработки на одном языке. Значит, улучшится координация команды. Все это станет возможным и даже закономерным, если к промптам начнут относиться как к абстрактным программам. Промпт — это абстрактная программа. Поскольку промпт — программа, мы должны его тестировать. Нужно понимать, решает ли он поставленную задачу. Если решает, не вызывают ли они попутно какие-то другие косвенные проблемы. Поскольку это абстрактная программа, мы должны тестировать его более тщательно, чем код. Ключевой аспект тестирования промптов — это учет субъективности естественного языка. Важно понимать, что промпт является определенного рода линзой, надетой на LLM. Мы тестируем возможный реестр ответов, а не один ответ. _______________________________Ссылка на документацию promptfoo: https://promptfoo.dev/docs/introПо всем вопросам пишите мне в телеграм.