В последнее время мне довольно часто приходится отвечать на вопросы, как я добиваюсь такой эффективности работы с ИИ-ассистентом, хотя коллеги гораздо тщательнее относятся к промптам, пишут километровые преамбулы на каждый чих и увещевают своих помощников мантрами наподобие «ты аналитик-архитектор с трехсотлетним стажем».
Записал вот и даже перевел на русский свои рецепты, чтобы каждый раз не вставать.
Типографика
ИИ-ассистенты, судя по всему, питают нежность к ярко-выраженным маркерам. Я использую маркеры ⓪ –⑳ для нумерации, ▸/▹ для списков, типографически корректные кавычки (‘’/«»/“”/) и длинные тире. Compose key облегчает набор всей этой живности, а альтернативная раскладка превращает его в сплошное удовольствие. Советов для бедолаг на MacOS/Win у меня нет, уж простите.
Рабочие процессы
У меня есть системные рабочие процессы (workflows) для ассистента. Все они выглядят одинаково: «СТАРТОВОЕ_СЛОВО → ПРАВИЛА_ПРОЦЕССА → СТОП_СЛОВО».
Вот пример:
Определим процесс, которому ты обязан следовать каждый раз, когда мы работаем над новой задачей. Имя процесса — NEW_TASK. Правила:
① Сообщение «New task <TASK_NAME>!», набранное мной, запускает новый процесс NEW_TASK
② При запуске нового процесса ты должен подтянуть главную ветку с github и создать новую ветку с именем «<TASK_NAME>»
③ В этот момент ты ждёшь, пока я введу постановку задачи
④ Ты должен проанализировать постановку задачи и немедленно задать все вопросы, где у тебя есть хоть малейшая неопределённость или недостаток ясности
⑤ После устранения всех неопределённостей ты должен предложить план реализации и запросить правки и/или одобрение
⑥ По факту одобрения ты приступаешь к реализации, задавая все возникающие по ходу вопросы
⑦ По завершении ты обязан создать исчерпывающие тесты для новой функциональности, документацию (и в исходном коде, и отдельно в markdown), запись в changelog и краткую сводку проделанного в markdown
⑧ После того как я всё приму, сказав «Task done!», ты коммитишь всё с исчерпывающим сообщением, пушишь в remote и создаёшь pull request в github.
Я никогда не разговариваю с ассистентом по-русски, это, согласно моему опыту, сильно влияет на качество результата, поэтому вот тот же текст на английском:
Let’s define the workflow you must follow every time we work on a new task, named NEW_TASK. The rules are following:
① The statement “New task <TASK_NAME>!” typed by me starts new NEW_TASK workflow
② Upon starting new workflow you must pull the main branch from github and create a new branch named “<TASK_NAME>”
③ At this point you have to wait for me to enter the problem statement
④ You have to analyze the problem statement and immediately ask all the questions regarding it where you might have had any uncertancy and/or lack of clarity
⑤ After everythig is clarified, you must come up with the plan of implementation and ask for its amendment and/or approval
⑥ Upon approval, you should start implementing it, asking all the questions you might have appeared
⑦ Once done, you must create a comprehensive tests for the new functionality, documentation in both the source code as standalone (markdown), changelog entry, and a brief what-has-been-done note in markdown
⑧ After I accept everything by saying “Task done!”, you should commit everything with a descriptive comprehensive commit message, push it to remote, and create a pull request in github.
Ключевой момент тут — стоп-слова. Без них ассистент радостно прогалопирует через все восемь шагов на одном дыхании, закоммитит непротестированный код в main и откроет pull request с заголовком «feat: everything». Стоп-слова — это поводок. Полюбите поводок, поводок — это полезно, особенно, если мы находимся с правильной стороны.
Контекст — царь и бог (а у вашего ассистента — амнезия)
Каждая новая сессия — это свежевылупившийся утёнок. Новая жизнь с чистого листа. Скормите ему конвенции вашей кодовой базы, ваши стилистические предпочтения, вашу философию тестирования — и делайте это постоянно, через правила и системные промпты, а не через исполненное надежды повторение одного и того же в каждом чате.
Разница между правилом «всегда используй :json вместо :jason» и ручным исправлением одной и той же зависимости в каждом сгенерированном mix.exs — это разница между инженерией и епитимьёй.
Персистентные правила — не опция. Они — тот цивилизационный слой, который отделяет вас от первозданного хаоса контекстного окна, никогда не слышавшего о вашем проекте. У каждого рабочего процесса (см. выше) может быть свой набор таких правил.
Атомарные задачи, или хватит писать романы
Результат удовлетворенного соблазна сказать «реализуй всю систему аутентификации» примерно столь же продуктивен, как просьба к стажёру «сделай так, чтобы приложение работало». Разбейте задачу. Потом разбейте ещё раз. Если описание задачи превышает десять строк — вы написали роман, а не задачу. Если внутри задачи возможны развилки — ассистент неизбежно выберет не тот путь.
Ассистент с радостью возьмётся за ваш роман и будет наугад выбирать направление на каждой развилке. Он произведёт нечто, что компилируется, не проходит ни одного теста и неизбежно заставлит вас усомниться в выборе профессии. Тогда как «добавь функцию verify_token/2, которая делает pattern-match на {:ok, claims} и {:error, reason}» — это он может сделать во сне. Если бы модели спали.
Правило артифицияльного буравчика: если к решению ведёт более одного корректного архитектурного пути — задача слишком велика. Занимайтесь архитектурой решение сами, а право набирать код — делегируйте. Даже самая лучшая машинистка не напишет «Войну и мир».
Покажи хороший код — получи хороший код
Это не мистика, это сопоставление с образцом, в прямом смысле. Если вы скармливаете ассистенту примеры чистого, идиоматичного кода — он будет производить чистый, идиоматичный код. Если вы скармливаете ему своё легаси-спагетти, написанное в 3 часа ночи во время продакшен-инцидента, — вы получите ещё больше спагетти, но с ИИ-сгенерированным пармезаном сверху.
Я храню курированный набор «эталонных» модулей, прикреплённых в качестве контекста с незапамятных времён. Ассистенту не нужно говорить «ты — ведущий архитектор на эликсире с 300-летним опытом». Ему нужно увидеть, как выглядит хороший эликсир. Покажите, а не мотивируйте.
Доверяй, но проверяй (особенно тесты)
Жесточайшая ирония ИИ-разработки: ассистент генерирует тесты, которые проходят. «Зелёные, как бананы в Советском Союзе!» — восклицаете вы и деплоите. Три часа спустя вы обнаруживаете: тесты проверяли, что функция возвращает хоть что-нибудь, а не что она возвращает правильное что-нибудь.
Читайте сгенерированные тесты внимательнее, чем имплементацию. Имплементация хотя бы выглядит подозрительно, когда она неправильная. Плохой тест выглядит в точности как хороший, только ничего полезного он не проверяет. Делайте pattern-match на конкретных значениях; assert result — это не тест, это молитва.
Искусство говорить «нет, давай заново»
Ваш ассистент — не ваш психотерапевт. Ему не нужна поддержка. «Это неправильно», — сказанное в тишину, — ничему его не учит. «Это неправильно, потому что рекурсивный вызов не обрабатывает базовый случай пустого списка, ожидаемый паттерн — смотри List.foldl/3» — вот теперь мы куда-то движемся. Держите пальцы прямо над комбинацией Ctrl+C и давите каждый раз, когда видите, что мыслительный процесс ассистента несёт куда-то в бурелом.
Вы всегда любили перебивать людей при личном общении — не стесняйтесь перебивать и своего заместителя.
Когда пора убивать сессию
Если вы уже три раза^W^W второй раз идёте по кругу, споря об одной и той же функции — закройте сессию. Начните заново. Контекстное окно отравлено неудачными попытками, поправками и взаимным разочарованием — пора начинать с белого листа.
Новая сессия с чистым описанием того, чего вы на самом деле хотите, превзойдёт седьмой раунд «нет, я имел в виду другое» — всегда. Азарт казино распространяется и на бюджеты токенов.
Имейте в виду: сама необходимость закрыть сессию красноречиво свидетельствует о том, что ваш исходный промпт был никуда не годным. Перепишите его с нуля. Убедитесь, что у ассистента нет свободы выбора путей. По прямым дорогам они умеют ходить превосходно.
Чек-лист
Вот, вкратце, список для тех, кто убежден, будто этот текст написан моделькой:
▸ Используйте сохранённые правила, а не сообщения типа: «Привет, как дела?» на каждую сессию
▸ Определяйте рабочие процессы с явными стартовыми и стоп-словами
▸ Не более одного архитектурного решения на задачу
▸ Прикрепляйте хороший код в качестве примеров, а мотивационную преамбулу — отправьте навсегда на свалку
▸ Запускайте полный валидационный конвейер (format, credo, dialyzer, test) после каждого шага, а не в конце
▸ Читайте сгенерированные тесты так, будто их написал кто-то, кто хочет вас обмануть (и знает, где вы живёте)
▸ Две-три неудачные итерации = убить сессию, переосмыслить задачу
▸ Никогда не позволяйте ассистенту коммитить без вашего явного на то указания
▸ Если вы не можете решить задачу сами — ассистент не решит её за вас, он может лишь печатать быстрее
Последний пункт заслуживает того, чтобы вытатуировать его на ягодице (или, хотя бы, отлить в бронзе). ИИ-ассистент — это умножи́тель силы, но не сила. Умножайте ноль на что угодно.
Удачного промптинга.
Автор: amcured


