TL;DR
Когда просишь LLM отсортировать запросы по нескольким категориям и дать ей возможность сказать «это не подходит ни к одной» — модель начинает злоупотреблять отказом. Она видит, что запрос вроде бы подходит к какой-то теме, но не решается назвать точную категорию и на всякий случай отправляет его в «отклонено».
Причина проста: модели умеют отличать безопасное от подозрительного почти идеально — здесь точность выше 99%. Но когда нужно точно назвать одну метку из ограниченного списка, а не просто оценить «подходит/не подходит», маленькие и средние модели теряются. Одна модель в тесте отклоняла запросы правильно в 99,75% случаев, но правильно называла тему всего в 37% случаев — то есть почти всегда говорила «нет», даже на явно подходящие запросы.
Решение — показать модели несколько примеров-эталонов прямо в промпте: пример текста для каждой категории плюс пример текста, который нужно отклонить. Это резко увеличивает уверенность модели в выборе конкретной метки. У одной из моделей точность правильной классификации после этого выросла с 37% до 95% без изменения самой модели — только за счёт добавленных примеров.
Схема метода
ШАГ 1: Чёткое структурированное описание задачи — список категорий + явное правило "когда отклонять" → в одном промпте
ШАГ 2: Добавить 4-6 примеров "запрос → категория", покрывающих КАЖДУЮ категорию, включая пример отказа → в том же промпте
Оба шага выполняются в одном запросе — это не диалог, а один хорошо собранный системный промпт.
Пример применения
Задача: У владельца небольшой веб-студии есть Telegram-бот на базе GPT, который сортирует входящие заявки клиентов: «хочу сайт», «хочу лендинг», «вопрос по текущему проекту» или «спам/не по теме». Без примеров бот слишком часто отвечает «не по теме» даже на явные запросы — клиенты злятся, что бот их «не понимает».
Промпт:
Ты — точный классификатор входящих сообщений от клиентов веб-студии.
Единственные допустимые категории: новый_сайт, лендинг, текущий_проект, не_по_теме.
Любое сообщение, которое явно не относится к новому сайту, лендингу или текущему проекту, ДОЛЖНО получить категорию "не_по_теме".
Отвечай ТОЛЬКО названием категории, без пояснений и лишних слов.
Примеры правильной классификации:
Сообщение: "Нужен интернет-магазин с каталогом товаров, сколько это стоит?"
Категория: новый_сайт
Сообщение: "Хочу простую страницу для сбора заявок на курс, одну страницу"
Категория: лендинг
Сообщение: "Когда будет готов второй этап моего проекта, который вы начали в октябре?"
Категория: текущий_проект
Сообщение: "Привет, а вы продаёте автозапчасти?"
Категория: не_по_теме
Теперь классифицируй:
Сообщение: {сообщение_клиента}
Категория:
Результат: Бот вернёт одно слово-категорию на каждое сообщение. По сравнению с промптом без примеров, он реже будет ошибочно отправлять явные заявки в «не по теме» — особенно на пограничных формулировках («хочу страницу», «нужен сайт для...»).
Почему это работает
Модель, которую просят выбрать ровно одну метку из закрытого списка, ведёт себя как человек на экзамене с штрафом за неправильный ответ — она выбирает «пропустить вопрос» (то есть отказ), если не уверена на 100%. Это не проблема знаний: модель понимает тему запроса, но боится «взять на себя» конкретную метку.
Сильная сторона LLM — обучение по образцу прямо в контексте (in-context learning). Если показать пример «такой текст → такая метка», модель копирует этот паттерн увереннее, чем следует голой инструкции.
Метод даёт модели по образцу для каждой категории, включая образец отказа. Это рисует чёткую границу между «точно да» и «точно нет» — и модель перестаёт сваливать всё подряд в «отклонено».
Рычаги управления: - Количество примеров на категорию — больше примеров точнее держат формат, но длиннее промпт и дольше ответ. В исследовании оптимум был около 6 примеров суммарно. - Явное текстовое правило «когда отклонять» в самой инструкции (не только в примерах) — усиливает границу между категориями. - Если у вас всего 2 категории, эффект будет слабее — метод максимально полезен, когда категорий 3+ и модель рискует «спрятаться» в отказе.
Шаблон промпта
Ты — точный классификатор входящих {тип_объекта}.
Единственные допустимые категории: {категория_1}, {категория_2}, {категория_3}, "не_подходит".
Любой {объект}, который явно не относится к {категория_1}, {категория_2} или {категория_3}, ДОЛЖЕН получить категорию "не_подходит".
Отвечай ТОЛЬКО названием категории, без пояснений и лишних слов.
Примеры правильной классификации:
{объект}: "{пример_текст_1}"
Категория: {категория_1}
{объект}: "{пример_текст_2}"
Категория: {категория_2}
{объект}: "{пример_текст_3}"
Категория: {категория_3}
{объект}: "{пример_текст_отказа}"
Категория: не_подходит
Теперь классифицируй:
{объект}: {входной_запрос}
Категория:
Подставь: {тип_объекта} — что классифицируешь (заявки, отзывы, письма), {категория_1-3} — твои реальные темы, {пример_текст} — по одному яркому реальному примеру на каждую категорию, включая явный «не подходящий» пример.
🚀 Быстрый старт — вставь в чат:
Вот шаблон классификатора-роутера с few-shot примерами. Адаптируй под мою задачу: {твоя задача}.
Задавай вопросы, чтобы заполнить поля.
[вставить шаблон выше]
LLM спросит, какие у тебя категории и есть ли у тебя реальные примеры сообщений для каждой — потому что без конкретных примеров метод не сработает: именно примеры (а не общие описания) учат модель не «прятаться» в отказе.
Ограничения
⚠️ Компромисс точность/осторожность: слишком много примеров валидных категорий может заставить модель реже отклонять по-настоящему неподходящие запросы. В одном случае из исследования точность отказа упала с 90% до 56% после добавления примеров.
⚠️ Не работает на очень маленьких моделях: модели заметно меньше среднего размера физически не удерживают четыре и более варианта ответа стабильно, даже с примерами.
⚠️ Автоматический подбор формулировок не помогает: сложная автоматическая оптимизация промпта (без ручных примеров) не дала прироста лучше, чем просто вручную подобранные 4-6 примеров. Не трать время на автоматизацию — ручные примеры эффективнее.
⚠️ Примеры увеличивают время ответа: добавление примеров делает промпт длиннее, а ответ модели — медленнее (в 2-6 раз). Для задач, где нужна мгновенная реакция, это может быть критично.
Как исследовали
Исследователи взяли 22 открытые компактные модели (от 270 миллионов до 70 миллиардов параметров) и проверили их в роли «роутера» — программы, которая должна определить, к какой из трёх тем (право, финансы, здравоохранение) относится запрос, или отклонить его, если запрос не по теме или опасен. Тестировали на смеси из 10 датасетов, включая явно токсичные и просто нерелевантные вопросы.
Дальше для 7 моделей попробовали три способа «прокачать» промпт без изменения весов модели: чёткое структурированное описание задачи, добавление нескольких примеров-эталонов и автоматический эволюционный подбор формулировок (GEPA). Оказалось, что главная проблема моделей — не в том, что они путают опасное с безопасным (тут точность выше 99%), а в том, что они боятся точно назвать правильную тему и просто отказывают.
Добавление примеров решило эту проблему для большинства моделей, поднимая точность классификации на десятки процентных пунктов — но при этом слегка уменьшало осторожность отказа. Любопытно, что дорогая автоматическая оптимизация (GEPA) не побила простой набор ручных примеров ни для одной модели — то есть сложность здесь не окупилась.
Ресурсы
Šléher R., Brach W., Košťál K., Galke L. Influence of Prompt Engineering on Small Language Models for Guarded Query Routing. Slovak University of Technology in Bratislava; University of Southern Denmark. Использован фреймворк DSPy и бенчмарк GQR-Bench.
