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

Сетап

Перед нами сильный инженер. Из тех, кто открывает PR коллеги и через секунду чувствует code smells: не по саммари агента-ревьюера, носом чует. Навык, наработанный годами. И вот, этот инженер садится работать с агентом: формулирует требования — обстоятельно, с примерами, с критериями приёмки — нажимает энтер и ждёт. Как заказчик студии: озвучил хотелки, оставил контакты, приходите с результатом.

Я вижу такую ситуацию который год — у разных людей, в разных командах. С кодом — мастер. С агентом — неприхотливый заказчик.

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

Самое коварное, что снаружи это неотличимо от работы. Детальные промпты, знание моделей, свежие релизы — «я ИИ-адоптер». Поза заказчика отлично маскируется под компетентность: требования формулируются, токены жгутся, человек параллельно крутит 3-4 агента.

Но плевать, насколько умна модель. Ты не ту ручку крутишь: качество создаётся не там, где легче всего крутится, — и не только в коде; с текстом и ресёрчем то же самое. Об этом и поговорим.

«Инструмент»

Откуда вообще эта поза у компетентных людей? Не из глупости и не из лени. Из правильной — но крайне ранней — фазы отношения к ИИ-агентам, которую мы приняли за финальную.

Эта фаза называется «инструмент». Она у нас неспроста: «ИИ — это просто инструмент» — фраза, которой мы снимали страх того, что нас заменят. Пока ИИ — «штука, которая нас всех заменит», взять его в руки невозможно, оно жжётся; низведение его до «инструмента» этот страх снимает и позволяет начать работать. Терапия помогла. И на этом её функция исчерпана, но мы продолжаем искренне верить в это.

«Инструмент» — это не зрелая позиция, это лишь первый шаг. Молотком работают руками: сам ударил — сам увидел, куда попал. Агент так не работает: он исполняет задачу от начала до конца, пока ты пьёшь кофе. Это исполнитель, а не инструмент. А зрелая позиция рядом с исполнителем — руководство процессом: ценность руководителя в том, что он отвечает за процесс, который обеспечивает качество.

Застрявший на «инструменте» лупасит молотком там, где уже нужно управлять процессом.

А где вообще рождается качество

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

Хороший код. Хороший текст. Хороший… погоди — хороший для чего?

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

  • Одно и то же решение — находка в прототипе и мина в проде.
  • Одна и та же страница документации — полезный сигнал для одного вопроса и шум для другого.

Артефакт не меняется ни на байт — качество меняется на противоположное.

Вернёмся к нашей позе заказчика. «Озвучил требования и жди» — ставка без гарантии и с максимальной ценой ошибки: может и сработать, но проверяешь ты только результат, а владение процессом отдал на откуп бездушной машине. Исполнитель — без разницы, человек или модель — не пользуется артефактом так, как этого хочешь ты. В конце этой цепочки стоишь ты — со своей задачей, которую агент знает с твоих слов, и со вкусом, которого у него нет. Требовать от него «сделай хорошо» — ошибка в адресате: ты просишь его оценить момент, в котором его не будет: который случится не с ним.

Это тот же тезис, который я давал в курсе по тимлидству: делегировать что-то можно только в том случае, если вы способны обеспечить детальную, своевременную и непротиворечивую обратную связь. Или, если говорить проще: если вы знаете, чего хотите, и отвечаете на звонки.

Вкус — это потолок ремесла

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

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

Почему у меня всё идёт на low

Расскажу, как это выглядит у меня. Моя практика, похоже, сложилась обратной тому, что делают буксующие.

Когда агент проваливает задачу, естественный рефлекс — докинуть мозгов: модель классом повыше, эффорт поднять с low на high, промпт в три экрана с упоминанием 100+ файлов для контекста. «Пусть моделька думает, она железная». Я делаю наоборот. Почти всё у меня идёт на low. Иногда я ещё и понижаю класс модели: sonnet вместо opus, terra вместо sol. Эффорт у меня — не стартовая настройка. Это компенсация неустранимой сложности, и включается она после того, как первая попытка провалилась, — не до.

Почему так. Тяга докинуть эффорта — почти всегда сигнал не про задачу, а про тебя: ты не декомпозировал задачу и хочешь, чтобы её декомпозировали за тебя внутри чёрного ящика. Разница принципиальная. Твоя декомпозиция видна тебе: подзадачи, границы, что от чего зависит — и где ты видишь риски. «Эффорт» не виден никому — это невидимые токены рассуждения, в которые ты выбрасываешь ответственность и дисциплину делегирования: перестаёшь думать, как инструктировать, и надеешься, что модель догадается сама. Задача при этом остаётся цельной — просто теперь этого не видно ни тебе, ни кому-либо ещё. Исключение одно: если сложность видна до старта, и high/xhigh в таком случае — честная цена. Это эквивалент ситуации, когда у тебя не хватает экспертизы, и ты просишь помощи у внешнего эксперта. Со всеми рисками, которые бывают в таких ситуациях.

Чем ты платишь за выкрученный эффорт

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

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

Осторожно: сам по себе этот совет вреден

Если просто выставить low и работать как раньше, станет хуже, а не лучше: слабая постановка задачи, которую высокий эффорт хоть как-то замазывал, теперь приведёт к молчаливому провалу — и он уедет прямо в готовый артефакт, где цена ошибки максимальна. Дело в природе исполнителя: агент додумывает дыры постановки — противоречие в инструкции он по умолчанию не отмечает, а тихо выбирает одну из веток и работает дальше. Надеяться что модель сама додумается рапортовать о таких проблемах бессмысленно; флаг надо встраивать структурно. Или же устранять противоречия в корне. Но тут другая проблема: иногда противоречия неизбежны.

План и явные допущения

Что с этим делать? Требуй план и явные допущения ещё до исполнения: изложи, что собираешься делать, и перечисли всё, что додумал за меня. Рассогласование в этих допущениях ловишь ты сам, когда читаешь план, — само оно не всплывёт. Смотришь на пять строк и видишь: здесь агент вывернул мою мысль, а тут молча залил бетоном дыру, которую я не заметил в постановке. У меня это минуты на плане против часов дебага готового артефакта. Минуты, но твои — ранний фильтр не бесплатен, просто он самый дешёвый из всех, что есть.

Что делать в понедельник

Звучит как красивая теория. А что реально делать иначе?

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

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

«Я и так прошу план»

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

Практика целиком

  • Low по умолчанию.
  • План до исполнения.
  • Эффорт только в ответ на провал при признании своих объективных границ компетенции.

Это не три разных совета, это единая практика.

Долг этой практики

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

Если эксперт отличается от новичка исключительно числом прожитых провалов, то каждый пойманный провал — это сырьё твоей экспертизы. Выбросить его, или отдать чёрному ящику, — значит выбросить капитал. Я именно это и делал поначалу, и даже более изощрённым способом, чем описывал выше: лечил промах мантрой «постараюсь запомнить» — самым искренним и самым бесполезным обещанием в этом ремесле — и наступал на тот же фейл снова, в новой одежде, через месяц. Так продолжалось, пока я не завёл своим провалам постоянное место жительства. Не в контексте или памяти агента, где они просто исчезают к следующей неделе, и не в мёртвых заметках, куда ни я, ни агент в имплементационном раже даже не заглядываем. Там, где они сохраняются, накапливаются, и молча работают на каждую следующую задачу.

У каждого моего провала теперь есть адрес. А у твоего?