Петля «генерация — оценка — починка»: когда один промпт разбивать на три

Тема 1/4: Промптинг как инженерная дисциплина Урок 3/3

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

Задача: недельное расписание смен

Рассмотрим сценарий, когда агент строится с нуля. Задача такая: составить недельное расписание смен для восьми сотрудников розничного магазина. У каждого сотрудника своя доступность, у магазина — требования к числу людей на смене, и есть набор жёстких ограничений, которые должны выполняться в каждом сценарии. Это задача с проверяемыми правилами: расписание либо нарушает ограничение, либо нет, промежуточных состояний не бывает.

Когда агент создаётся с нуля, на результат влияют сразу три вещи: сам промпт, выбранная модель и код вокруг модели — то, как устроен вызов и что происходит с ответом. Поэтому и сравнивать подходы стоит по всем трём направлениям, а не только правки текста промпта.

Почему оценивает Python-функция, а не LLM-судья

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

Пять экспериментов: от простого промпта к петле

Отправная точка — простой промпт, к которому уже применена базовая гигиена из прошлого урока: структура через XML-теги и заданный формат вывода (JSON, чтобы дальше по конвейеру не ловить ошибки разбора). Оценочный набор — пять тест-кейсов, для каждого считается число нарушений.

  1. Простой промпт + более лёгкая модель. Все пять тест-кейсов провалены. Модель делает неплохую попытку рассуждать, но тратит много токенов и не перепроверяет свою работу.
  2. Тот же промпт + более мощная модель. Тест-кейсы по-прежнему падают, но число нарушений заметно меньше. Более сильные рассуждения помогают, хотя для выпуска этого недостаточно.
  3. Более мощная модель с адаптивным мышлением. Промпт не меняется — меняется только вызов: модель сама решает, сколько рассуждений ей нужно. Задача решается, но расход токенов и задержка вырастают примерно втрое — около 100 секунд на прогон.
  4. Более лёгкая модель + улучшенный промпт. В промпт добавлено, как рассуждать над задачей, и указание перепроверять работу перед выводом. Проходят два тест-кейса из пяти. Причём оставшиеся провалы — уже не нарушения правил расписания: модель упирается в лимит вывода и не успевает довести ответ. Поднять лимит токенов можно, но это ещё больше токенов и ещё выше задержка — не тот путь.
  5. Петля «генерация — оценка — починка». Задача разбита на три отдельных промпта, которые работают по кругу. Такой подход решает все пять тест-кейсов — при заметно меньшем расходе токенов и меньшей задержке, чем у более лёгкой модели с улучшенным промптом.

Как устроена петля

Три роли — три простых промпта:

  • Генератор составляет первый черновик расписания.
  • Оценщик проходит по каждому правилу и находит конкретные нарушения, приводя доказательства: какое правило нарушено, где именно и чем это подтверждается.
  • Ремонтник получает список нарушений и вносит точечные исправления — не переписывает расписание целиком, а чинит найденные места.

Ключевое свойство — независимость. Каждый промпт решает одну узкую задачу и ничего не знает об остальных. Вместо одной модели, которая должна одновременно составить расписание, проверить его и исправить ошибки, работают три простых шага, и каждый по отдельности даётся модели легко.

Обратите внимание: Python-функция из оценочного набора никуда не делась — она по-прежнему измеряет итоговый результат. А оценщик внутри петли — это уже модель: она ищет нарушения по правилам и объясняет их словами, чтобы ремонтнику было что чинить.

Мягкие требования на лету

У петли есть преимущество, которого нет у одного большого промпта: мягкие требования можно задавать прямо во время выполнения, в промпте-оценщике. Примеры: «Гарри не любит работать с Салли — по возможности не ставьте их вместе» или «в среду нужна третья смена». Такие пожелания зависят от конкретной недели и конкретного магазина. С петлёй их достаточно дописать в промпт оценщика — Python-функцию оценки в коде править не нужно. Жёсткие правила остаются в коде, мягкие живут в тексте, и эти два слоя не мешают друг другу.

Что из этого забрать

Вывод: для этой задачи пригодны два варианта — более мощная модель с адаптивным мышлением либо агентная петля. Первый проще в устройстве, но примерно втрое дороже по токенам и задержке. Вторая требует спроектировать три промпта, зато работает быстрее и дешевле и даёт слой мягких требований.

Общее правило: разбиение одного большого промпта на несколько отдельных систем помогает там, где шаги повторяемы и легко изолируются. Если в задаче можно выделить операции, которые модель выполняет каждый раз — сгенерировать, проверить, исправить, — каждой операции лучше дать собственный простой промпт, чем требовать всего сразу от одного большого.