Паттерны промптинга
Промптинг — это не магия и не интуиция. Это набор устоявшихся паттернов с предсказуемым эффектом: правильно сформулированная задача даёт стабильный, управляемый результат. Для разработчика, который работает через агентов, промптинг — это язык требований: как превратить задачу в инструкцию, которую модель выполнит надёжно. Эта статья — о паттернах формулирования: анатомия промпта, few-shot, chain-of-thought, prompt chaining, антипаттерны и критерии выбора паттерна под задачу. Всё это — то, из чего вы каждый день собираете спецификации для агентов.
Содержание
- Анатомия промпта: system / user / assistant
- Zero-shot, one-shot, few-shot
- Chain-of-thought
- Prompt chaining
- Как выбрать паттерн под задачу
- Антипаттерны и типичные ошибки
- Case study: от «сделай хорошо» до стабильного вывода
- Ключевые тезисы для интервью
- Заключение
- Полезные ссылки
Анатомия промпта: system / user / assistant
Три роли в разговоре
System prompt — инструкции, которые задают поведение модели на уровне сессии: роль, ограничения, формат вывода. Это привилегированный слот: модель обучена следовать системным инструкциям строже, чем пользовательским.
User — сообщения от пользователя или от приложения: конкретная задача, данные, уточнения.
Assistant — сообщения модели. В истории хранятся прошлые ответы.
Что куда класть
// Системный промпт: неизменное поведение для всей сессии
const system = `Ты — ассистент по code review.
Пиши замечания кратко, по одному на пункт.
Всегда указывай номер строки.
Не предлагай изменений за пределами переданного кода.`;
// User message: конкретная задача с данными
const userMessage = `Проверь этот компонент:
\`\`\`tsx
${componentCode}
\`\`\``;
Для работы с агентами это правило применимо напрямую: постоянные инструкции — в AGENTS.md / system prompt, конкретная задача — в текущем сообщении.
Таблица: что класть в system, что в user
| Слой | Содержимое | Частота изменения |
|---|---|---|
| System prompt | Роль, ограничения, формат вывода, стиль | Редко, на уровне сессии |
| AGENTS.md | Стек, команды, соглашения, запреты проекта | Постоянно, в репозитории |
| User | Конкретная задача, данные, код, критерии | Каждый вызов |
Порядок сообщений имеет значение
Из статьи о ментальной модели: модели лучше обрабатывают начало и конец контекста. Практическое следствие: критические ограничения — в начало (system prompt), конкретное задание — в конец (текущее сообщение). История в середине прочитывается, но с меньшим вниманием.
Zero-shot, one-shot, few-shot
Zero-shot: задача без примеров
Работает хорошо для распространённых задач, которые модель «видела» в обучении. Проблема: модель сама интерпретирует формат вывода — результат может быть «нейтральная», «Нейтральная», «Тональность: нейтральная», «Это смешанный отзыв…». Всё это требует разного парсинга.
One-shot: один пример
Один пример резко сужает пространство интерпретаций и задаёт формат:
Определи тональность. Отвечай одним словом: positive / negative / neutral.
Отзыв: "Отличный товар, рекомендую!"
Тональность: positive
Отзыв: "Быстрая доставка, но упаковка помята"
Тональность:
Модель почти наверняка ответит neutral — формат задан примером.
Few-shot: несколько примеров
Few-shot работает лучше в задачах с неочевидной логикой классификации или специфичным доменом — когда нужно показать модели граничные случаи.
Правило качества примеров: плохой пример вреднее, чем его отсутствие. Если примеры противоречат друг другу или содержат исключения без объяснения — модель обучается на противоречии.
Таблица: zero-shot vs one-shot vs few-shot
| Аспект | Zero-shot | One-shot | Few-shot |
|---|---|---|---|
| Формат вывода | Модель решает сама | Задан примером | Задан несколькими примерами |
| Стоимость (токены) | Минимальная | +1 пример | +N примеров |
| Где работает | Типовые задачи | Сужение интерпретаций | Сложная классификация, домен |
| Граничные случаи | Не заданы | Один случай | Могут быть закодированы в примерах |
| Риск | Формат «плавает» | Пример может быть нерепрезентативным | Плохие примеры обучают на противоречии |
Когда few-shot реально помогает
- Нестандартный формат вывода — нужна специфическая структура
- Доменная специфика — внутренние категории, которых нет в общем обучении
- Граничные случаи — примеры именно для неоднозначных входных данных
Когда few-shot НЕ нужен
- Задача типичная, модель справляется zero-shot (извлечение дат, перевод, форматирование)
- Формат можно задать одной строкой инструкции («отвечай только JSON»)
- Каждый пример — это токены; для длинных данных few-shot раздувает стоимость
Chain-of-thought
Проблема: сложные рассуждения без промежуточных шагов
Если спросить модель напрямую «Если куплю 3 яблока по 7 рублей и 5 груш по 11, сколько сдачи со 100?» — она нередко ошибается. Если попросить «рассуждай пошагово» — точность резко возрастает. Причина: модель генерирует токены последовательно; при прямом ответе у неё нет «места» для промежуточных вычислений — они должны появиться в тексте.
Применение
// Без CoT: модель даёт ответ напрямую
Определи, есть ли в этом коде утечка памяти: <код>
// С CoT: инструкция думать вслух
Определи, есть ли в этом коде утечка памяти.
Рассуждай пошагово:
1. Определи все подписки, таймеры и слушатели событий
2. Проверь, есть ли cleanup для каждого из них
3. Сделай вывод
Код: <код>
Для работы с агентами CoT полезен в задачах анализа и отладки: «проанализируй, затем реши» даёт лучший результат, чем «реши сразу».
Когда CoT помогает, а когда нет
| Задача | CoT помогает? | Почему |
|---|---|---|
| Многошаговые рассуждения | ✅ | Промежуточные шаги «записываются» в текст |
| Отладка, поиск причины | ✅ | Модель проверяет каждую ветку по очереди |
| Простые факты | ❌ | Рассуждение только тратит токены |
| Творческие задачи | ❌ | CoT ограничивает свободу |
| Очевидный ответ | ❌ | Избыточное рассуждение может снизить точность |
| Извлечение данных из текста | ⚠️ | Часто помогает, но не обязательно |
Prompt chaining
Когда одного промпта недостаточно
Сложные задачи плохо решаются одним запросом: слишком много требований одновременно, конкурирующие цели, задача слишком длинная для одного вывода. Prompt chaining — разбиение на последовательность более простых шагов, где вывод одного становится входом следующего.
// Одним запросом: перегружен, плохой результат
Проанализируй код, найди баги, исправь их, задокументируй,
напиши тесты и обнови README
// Цепочка: каждый шаг фокусирован
Шаг 1: Проанализируй код и опиши проблемы
Шаг 2: Исправь баги на основе анализа
Шаг 3: Напиши тесты на основе исправленного кода
Паттерн: генерация + проверка
Второй распространённый случай: генерируем результат первым вызовом, проверяем корректность вторым («генерация + проверка»).
Шаг 1: Реализуй функцию по спецификации: <спецификация>
Шаг 2: Проверь, соответствует ли этот код спецификации.
Спецификация: <спецификация>
Код: <код>
Ответь: "ok" если соответствует, иначе — список несоответствий.
Это ключевой паттерн для работы с агентами: не принимать результат агента без проверки. Независимая проверка — второй вызов с другим фокусом — ловит то, что первый пропустил.
Когда цепочки нужны, а когда нет
| Случай | Цепочка? | Почему |
|---|---|---|
| Анализ → исправление → тесты | ✅ | Каждый шаг фокусирован, результат проверяем |
| «Сгенерируй и проверь» | ✅ | Второй вызов ловит ошибки первого |
| Типовая задача | ❌ | Цепочка добавляет latency и стоимость |
| Короткий ответ | ❌ | Один промпт быстрее и дешевле |
| Современные модели | ⚠️ | Справляются с многошаговыми задачами лучше, чем год назад |
Как выбрать паттерн под задачу
Соберём все паттерны в единую таблицу выбора:
| Задача | Паттерн | Почему |
|---|---|---|
| Типовое форматирование, перевод, извлечение | Zero-shot | Модель знает задачу, примеры — лишние токены |
| Нужен строгий формат вывода (JSON, одно слово) | One-shot | Пример задаёт формат без неоднозначности |
| Классификация с доменной спецификой | Few-shot | Примеры кодируют категории и границы |
| Многошаговое рассуждение, отладка | Chain-of-thought | Промежуточные шаги «в тексте» повышают точность |
| Сложная задача с несколькими фазами | Prompt chaining | Фокус на одном шаге, результат проверяем |
| Критичный результат | Генерация + проверка | Второй вызов ловит ошибки первого |
Правило-резюме: начните с минимально достаточного паттерна. Zero-shot, если формат не важен. One-shot, если важен формат. Few-shot — только когда нужны доменные категории. CoT — для рассуждений. Цепочку — когда один промпт не справляется. Каждый следующий паттерн — это больше токенов и latency, поэтому его нужно оправдать.
Антипаттерны и типичные ошибки
Избыточная вежливость
// Плохо: токены на вежливость — это деньги и latency
Пожалуйста, не могли бы вы любезно помочь мне, если вас не затруднит,
проанализировать этот код?
// Хорошо: директивный тон
Проанализируй код. Укажи проблемы и улучшения.
Модели не обижаются. Вежливые обороты занимают токены и размывают инструкции.
Противоречивые инструкции
Если инструкции конфликтуют, приоритет зависит от модели и контекста — результат непредсказуем. Решение: согласованные инструкции или явный приоритет в system prompt.
Негативные инструкции без позитивной альтернативы
// Хуже: только запрет
Не используй markdown. Не пиши заголовки. Не делай списки.
// Лучше: явно желаемый формат
Отвечай простым текстом, сплошными абзацами, без форматирования.
«Не делай X» менее эффективно, чем «делай Y» — модель должна знать, что делать, а не только чего избегать.
Перегрузка одного промпта
// Плохо: слишком много задач одновременно
1. Найди все баги
2. Перепиши на TypeScript
3. Добавь тесты
4. Оптимизируй производительность
// Хорошо: одна чёткая задача
Найди все баги в этом коде. Для каждого: строка, описание, уровень критичности.
Неясный критерий качества
// Плохо: «хорошо» — субъективно и неизмеримо
Напиши хороший компонент для формы входа.
// Хорошо: конкретные критерии
Напиши React-компонент формы входа:
- Поля: email, password
- Валидация на submit: email format, password min 8 символов
- Сообщения об ошибках под каждым полем
- Disabled-состояние кнопки во время запроса
- TypeScript, без сторонних библиотек для форм
Таблица: антипаттерн → симптом → фикс
| Антипаттерн | Симптом | Фикс |
|---|---|---|
| Избыточная вежливость | Токены на «пожалуйста», размытые инструкции | Директивный тон |
| Противоречивые инструкции | Непредсказуемый результат | Явный приоритет в system prompt |
| Только запреты | Модель «не знает», что делать | Позитивная формулировка «делай Y» |
| Перегрузка промпта | Среднее качество по всем задачам | Одна задача на вызов / цепочка |
| Неясный критерий | «Хорошо», «красиво», «быстро» | Измеримые критерии и формат |
Case study: от «сделай хорошо» до стабильного вывода
Покажем, как выбор паттерна меняет результат, на одной задаче: «извлечь дату из текста».
Шаг 1. Zero-shot — формат плавает.
// Промпт
Извлеки дату из: "Заказ отправлен 15.01.2024, доставка в течение 3 дней"
// Возможные ответы модели:
// 15.01.2024
// Дата: 15.01.2024
// Заказ отправлен 15.01.2024
Ответы разные по формату — парсить такой вывод нельзя.
Шаг 2. One-shot — формат задан.
// Промпт
Извлеки дату. Отвечай только датой в формате YYYY-MM-DD.
Пример: "Заказ отправлен 15.01.2024" → 2024-01-15
"Курс обновился 01.03.2024, следующий 01.06.2024"
Ответ: 2024-03-01 — формат стабилен. Ключевое: в примере дата в другом формате (дд.мм.гггг), а ответ — в целевом (гггг-мм-дд). Пример показывает переход, а не просто копирование.
Шаг 3. Few-shot — граничные случаи.
// Два примера кодируют границы:
// - первая дата в тексте, а не «самая похожая»
// - дата в нестандартном формате
"Встреча 10.12.2024, продлена до 20.12" → 2024-12-10
"Срок 01.02.2024 (старый), новый 15.02" → 2024-02-15
Модель теперь выбирает первую дату в тексте, а не угадывает по контексту.
Шаг 4. Что произошло.
| Метрика | Zero-shot | One-shot | Few-shot |
|---|---|---|---|
| Формат стабилен | ❌ | ✅ | ✅ |
| Граничные случаи учтены | ❌ | ⚠️ | ✅ |
| Стоимость (токены) | Минимальная | +1 пример | +2 примера |
Вывод: для типовой задачи хватило one-shot — он дал стабильный формат без лишних токенов. Few-shot понадобился только потому, что задача содержала неоднозначность (какую из нескольких дат брать). Это и есть правило: начните с минимально достаточного паттерна, добавляйте следующий только когда текущий не справляется.
Ключевые тезисы для интервью
- Промпт состоит из трёх ролей: system (поведение сессии), user (конкретная задача), assistant (история ответов); постоянное — в system/AGENTS.md, одноразовое — в текущее сообщение.
- Few-shot — примеры в промпте для калибровки формата и логики; качество примеров важнее их количества, плохой пример вреднее отсутствия.
- Chain-of-Thought вынуждает модель генерировать промежуточные шаги рассуждения в тексте — повышает точность на сложных многошаговых задачах и отладке, но бесполезен для простых фактов и творчества.
- Prompt chaining — декомпозиция сложной задачи на последовательные вызовы; паттерн «генерация + проверка» — независимая проверка результата вторым вызовом.
- Выбор паттерна — от минимально достаточного: zero-shot → one-shot (формат) → few-shot (домен) → CoT (рассуждения) → chaining (сложность); каждый следующий дороже в токенах и latency.
- Негативные инструкции («не делай X») менее эффективны, чем позитивные («делай Y»); противоречивые инструкции дают непредсказуемый результат.
- Один промпт — одна задача; конкретные измеримые критерии качества лучше абстрактного «напиши хорошо».
Заключение
Промптинг — это инженерная дисциплина, а не интуиция. Несколько принципов, которые работают всегда:
- Чёткие инструкции побеждают длинные. Конкретный формат лучше общего «напиши хорошо».
- Примеры эффективнее объяснений. One-shot часто даёт лучший результат, чем развёрнутая инструкция без примера.
- Промежуточные шаги — это токены в тексте. CoT работает потому, что рассуждение буквально записывается в ответе.
- Один промпт — одна задача. Сложное разбивается на цепочку.
- Результат агента проверяется. Паттерн «генерация + проверка» — второй вызов с независимым фокусом.
- Начинайте с минимально достаточного паттерна — каждый следующий должен быть оправдан стоимостью.
Для разработчика, работающего через агентов, эти паттерны — не теория, а повседневный язык: как превратить задачу в спецификацию, которую агент выполнит без догадок.
Полезные ссылки
- Anthropic Prompt Library — библиотека готовых промптов для типовых задач
- Anthropic Prompt Engineering Guide — официальный гайд по промптингу
- Brex Prompt Engineering Guide — практический гайд от Brex с примерами
- Prompt Engineering Guide (DAIR.AI) — обзор паттернов: few-shot, CoT, self-consistency