Диагностика Mock-интервью
Главная · LLM: обучение и инференс

Промпт-паттерны и structured outputs

Как формулировать инструкции, чтобы LLM отвечала предсказуемо: роль и критерии, few-shot примеры, декомпозиция, chain-of-thought — и как constrained decoding гарантирует валидный JSON на уровне сэмплирования, а не просьбы.

Интуиция

Контекст-инжиниринг отвечает на вопрос, что и в каком порядке модель видит на входе. Эта тема — про следующий слой: как формулировать сами инструкции и как получать выход, который можно парсить кодом, а не глазами. Промпт — это интерфейс к вероятностной машине: модель не «понимает задание», а продолжает текст самым правдоподобным способом. Хорошие паттерны работают не магией, а тем, что делают желаемое продолжение статистически самым вероятным.

Паттерны, которые работают (и почему)

Structured outputs: от просьбы к гарантии

Просьба «верни JSON» — это лестница надёжности. Уровень 1: просто попросить — модель иногда добавит «Конечно, вот ваш JSON:» или забудет кавычку. Уровень 2: few-shot с образцами — заметно лучше. Уровень 3: JSON mode — провайдер обучил модель и настроил инференс так, чтобы выход был валидным JSON. Уровень 4: schema-guided / constrained decoding — по JSON-схеме строится грамматика, и на каждом шаге генерации маскируются все токены, нарушающие её: невалидный токен физически не может быть выбран при сэмплировании. Валидность становится свойством декодера, а не воспитанности модели.

P(token | префикс) → 0 для всех токенов, ломающих грамматику; остальные перенормируются

Гарантируется только форма: JSON распарсится, поля и типы совпадут со схемой. Правильность значений полей — по-прежнему на совести модели: в поле amount может лежать не та сумма, и никакая грамматика этого не поймает.

💡 Ключевая мысль Constrained decoding ограничивает сэмплирование, а не «убеждает» модель: схема гарантирует форму ответа, но не смысл — точность значений полей всё равно проверяется eval-сетом.

Поиграй с порядком включения: первый few-shot пример даёт огромный скачок за умеренные токены, три примера — ещё точнее, но втрое дороже, а constrained decoding добивает валидность до 100% почти бесплатно — но не двигает точность ни на пункт. Это и есть главный вывод про structured outputs.

Анти-паттерны

Противоречивые инструкции. «Отвечай кратко» в начале и «объясни развёрнуто» в середине — модель не выберет «правильную», она будет метаться между обеими. Отрицания. «Не упоминай конкурентов» подсаживает конкурентов в контекст — токены «конкуренты» уже там и повышают вероятность соответствующего продолжения; надёжнее позитивная формулировка: «говори только о нашем продукте». Мегапромпт на десять задач. Инструкции конкурируют за внимание, отладка превращается в гадание — декомпозируй. Примеры расходятся с инструкцией. Если инструкция требует одного формата, а few-shot показывает другой, модель поверит примерам: показ сильнее рассказа работает и против тебя.

Промпт — это код

Промпт в проде меняет поведение системы так же, как код, — и заслуживает той же дисциплины: храни в репозитории и версионируй, а не правь в админке; на каждое изменение прогоняй eval-сет (см. оценку LLM) — «стало лучше на моих трёх примерах» регулярно означает «сломалось на тридцати чужих»; фиксируй, для какой модели промпт писался: смена модели — это смена рантайма.

⚠️ Подводный камень JSON mode и схема гарантируют, что ответ распарсится, — и создают ложное чувство безопасности: в валидном JSON может лежать неверная сумма, выдуманное имя или пустая строка вместо даты. Форму проверяет грамматика, смысл — только eval-сет.
🎤 На собеседовании
  • «Как добиться валидного JSON от LLM?» — лестница: просьба в промпте → few-shot с образцами → JSON mode провайдера → constrained decoding по схеме; только последний уровень даёт гарантию, потому что маскирует невалидные токены при сэмплировании.
  • «Почему few-shot сильнее словесной инструкции?» — модель продолжает паттерны: примеры задают формат в том же виде, в каком его нужно воспроизвести, без перевода «слова → поведение».
  • «Чем плох гигантский промпт на много задач?» — инструкции конкурируют и противоречат друг другу, ошибку нельзя локализовать, eval неинформативен; лечится декомпозицией на цепочку промптов.
  • «Гарантирует ли схема правильные данные?» — нет: она гарантирует форму (парсинг, типы полей), а правильность значений проверяется только оценкой на эталонном наборе.