Промпт для кода — это техническое задание. Не заклинание, не «магические
слова», не вежливая просьба. Обычное ТЗ, которое отличается от человеческого
только тем, что исполнитель не переспросит, если что-то непонятно: он просто
решит за вас и пойдёт дальше.
Отсюда всё остальное. Хороший промпт — тот, по которому нельзя сделать не то.
Почти любая рабочая формулировка раскладывается на четыре куска. Не обязательно
писать их подряд и подписывать заголовками, но если какого-то нет — результат
будет случайным именно в этом месте.
Контекст. Где мы, что за проект, какие файлы трогаем, что уже есть.
«В src/lib/api.ts есть клиент, который ходит в наш бэкенд» — одна строка,
а модель перестаёт изобретать свой.
Задача. Что должно получиться. Одно изменение, а не список из шести.
Ограничения. Чего делать нельзя. Это самая недооценённая часть: без неё
появляются новые зависимости, переписанные соседние функции и «заодно
отрефакторил».
Критерии приёмки. Как понять, что готово. Проверяемо: команда, которая
должна отработать, поведение, которое должно появиться.
Плохо:
сделай нормальную обработку ошибок в апи-клиенте
Здесь непонятно всё: что считать ошибкой, что делать при ней, где границы
изменений и что такое «нормальную». Модель что-нибудь выберет, и это будет
её выбор, а не ваш.
Хорошо:
В src/lib/api.ts запросы падают с необработанным исключением,
когда бэкенд недоступен.
Нужно: при сетевой ошибке и при 5xx возвращать последний
успешный ответ из кэша (он уже есть в lib/cache.ts) и ставить
флаг stale: true. При 4xx поведение не меняем — пробрасываем.
Не трогай сигнатуры экспортируемых функций и не добавляй
зависимостей.
Проверка: npm run check проходит, страница /feed/ при
выключенном API открывается с плашкой, а не с пятисоткой.
Разница не в длине — во втором варианте нет мест, где надо угадывать.
Показать пример вместо описания. «Сделай как в Attachment.astro» точнее
любого описания стиля. Модель отлично копирует шаблон и плохо угадывает
неписаные соглашения.
Формулировать проверяемо. «Красиво» и «чисто» — это ничто. «Не больше
одного уровня вложенности», «без глобальных переменных», «время ответа не
зависит от числа записей» — это требования.
Дробить. Задача на десять шагов даёт десять шансов промахнуться, и промах
на третьем испортит остальные семь. Один шаг — один коммит — одна проверка.
Сначала план, потом код. Для чего-то крупного: «опиши, что собираешься
менять и в каких файлах, код пока не пиши». Плохой план видно за десять
секунд, плохой код — за полчаса ревью.
Отдавать ошибку целиком. Не пересказ, а вывод: полный трейсбек, команда,
которая его вызвала, версии. Пересказ теряет ровно ту деталь, которая была
важной.
Говорить, что уже пробовали. «Кэш-заголовки я проверил, дело не в них» —
экономит целый круг.
«Исправь всё, что не так» — модель найдёт двадцать поводов и перепишет
половину файла. Просите одно исправление за раз.
«Ты ошибся» без деталей. Модель не знает, в чём именно, и начнёт менять
наугад — часто ломая то, что работало. Скажите, что произошло вместо
ожидаемого.
Спор на третий круг. Два уточнения не сошлись — проблема в постановке,
а не в понимании. Откатитесь и переформулируйте с нуля.
Гигантский дамп кода. Полкодовой базы в промпте не помогает, а мешает:
существенное тонет. Дайте нужные файлы и скажите, где искать остальное.
Вежливость вместо конкретики. «Пожалуйста, постарайся сделать хорошо» не
несёт информации. Тон вообще ни на что не влияет — влияют требования.
Повтор одного и того же в каждом чате. Стек, соглашения, чего не делать —
это не промпт, это постоянный контекст проекта. Опишите
один раз файлом в репозитории.
Первый ответ редко финальный, и это нормально. Важно, как двигаться дальше.
git checkout ., а не полдня.Хороший признак того, что промпт получился: вы можете отдать его человеку,
который проект не знает, и он сделает примерно то же самое.