almcreate Авторский IT-блог

Первый момент, когда я отдал AI задачу целиком

Я не объяснял, какой сервис написать. Я отдал задачу — и увидел, где AI разбирается сам, а где без моего контекста он не справится.

Александр Морозов · 18 фев 2026 · 11 мин чтения · 3 просмотра
Рука передаёт папку с задачей компактному устройству на ночном рабочем столе — эксперимент отдать AI feature целиком
Сгенерированная обложка · AI · задача целикомalmcreate

Я довольно хорошо помню момент, когда впервые поймал себя на непривычной мысли:

Я сейчас не объясняю AI, какой код написать. Я отдаю ему задачу.

До этого разница казалась почти косметической.

Можно попросить:

Напиши сервис для повторной отправки уведомления.

А можно:

Добавь возможность повторно отправить уведомление пользователю.

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

И именно это оказалось для меня самым интересным.

Раньше я почти всегда приносил готовое решение

Представим обычную задачу.

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

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

Например:

  • добавить метод в существующий сервис;
  • сделать endpoint;
  • проверить права;
  • добавить кнопку в интерфейс;
  • записывать результат повторной отправки;
  • добавить тесты.

После этого я мог обратиться к AI:

Вот сервис. Добавь метод resend().

Он должен принимать идентификатор уведомления, проверять статус и повторно отправлять сообщение через существующий transport.

Это вполне нормальная задача для AI. Но фактически всё главное уже произошло до запроса. Я нашёл нужное место. Я разобрал архитектуру. Я придумал решение. Я определил границы изменения. AI оставалось написать код.

В какой-то момент мне стало интересно: а что будет, если не делать эту часть самому?

Я специально сформулировал задачу иначе

Вместо описания реализации я написал примерно следующее:

Нужно добавить возможность вручную повторно отправить неуспешное уведомление.

Разберись, как сейчас устроена отправка уведомлений, где хранятся результаты и каким образом сотрудник работает с ними в интерфейсе.

Существующую успешную отправку менять нельзя.

Сначала предложи план реализации. Пока код не меняй.

Для меня тогда это было довольно непривычно. Я знал, как примерно решил бы задачу сам. Поэтому постоянно хотелось помочь. Написать: «Посмотри вот этот класс». Или: «Там есть такой-то сервис». Или сразу: «Лучше добавь отдельный action».

Но я специально этого не делал. Хотел посмотреть, что произойдёт, если дать AI возможность самому исследовать проект.

Первые несколько минут выглядели почти бесполезно

AI начал искать. Открыл сущность уведомления. Потом sender. Потом несколько обработчиков. Нашёл controller. Посмотрел шаблон интерфейса. Вернулся к модели уведомления. Пошёл искать события.

Некоторые файлы, которые он открывал, я сам бы даже не стал смотреть.

В какой-то момент у меня возникло знакомое ощущение:

Я бы уже давно начал писать код.

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

Но потом произошло то, ради чего весь эксперимент вообще стоило проводить. AI нашёл деталь, о которой я сам в начале задачи не вспомнил.

Повторная отправка уже частично существовала

В одном из фоновых обработчиков была логика автоматического retry. Не полноценная функция повторной отправки. Но часть нужного поведения уже существовала. Причём она находилась не там, куда я сначала собирался идти.

Если бы я сразу дал AI инструкцию:

Добавь resend() в NotificationService,

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

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

В тот момент я впервые очень хорошо почувствовал разницу между:

«напиши мне код»

и

«реши задачу в этом проекте».

План выглядел вполне разумно

После исследования AI предложил примерно такую схему:

  1. Не создавать отдельную реализацию отправки.
  2. Использовать существующий механизм dispatch.
  3. Добавить отдельную операцию ручного retry.
  4. Ограничить её только уведомлениями с ошибкой.
  5. Проверить права пользователя.
  6. Добавить действие в интерфейсе.
  7. Покрыть новый сценарий тестами.

Я посмотрел план. Задал несколько вопросов. Попросил отдельно проверить, можно ли безопасно повторно отправлять уведомление после частичной ошибки.

После ещё одного небольшого исследования план немного изменился. И только после этого я написал:

Реализуй.

Это было странное ощущение. Обычно к этому моменту я уже сам написал бы значительную часть кода. А здесь пока не написал ни одной строки.

И всё почти сработало

AI изменил несколько файлов. Добавил backend-операцию. Подключил её к существующему механизму отправки. Добавил кнопку. Написал тесты. Запустил их. Тесты прошли.

На первый взгляд задача была выполнена.

И вот здесь начинается самая полезная часть этой истории. Потому что реализация была неправильной. Не катастрофически. Не так, чтобы всё пришлось выбросить. Но достаточно неправильно, чтобы я не мог принять её как есть.

AI решил техническую задачу, но не понял пользовательский сценарий

Он разрешил повторную отправку для любого уведомления со статусом ошибки. Технически это соответствовало поставленной формулировке.

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

То есть:

технически можнопо смыслу уже нельзя
уведомление не отправилось
    ↓
прошло время
    ↓
бизнес-состояние изменилось
    ↓
сотрудник нажимает «отправить повторно»
    ↓
пользователь получает уже неактуальное сообщение

Все тесты были зелёными. Архитектурно решение выглядело нормально. Код был аккуратным. Но feature была реализована неправильно.

AI проверил:

Можно ли повторно отправить уведомление?

А настоящий вопрос был:

Имеет ли смысл отправлять это уведомление сейчас?

И это уже совсем другой уровень контекста.

Мне пришлось вернуть задачу назад

Раньше в такой ситуации я просто открыл бы код и начал исправлять его вручную. Но раз уж это был эксперимент, я решил продолжить в том же формате.

Написал примерно так:

Реализация технически работает, но здесь упущено бизнес-ограничение.

Нельзя считать ошибку отправки достаточным условием для retry.

Нужно проверить, актуально ли само уведомление относительно текущего состояния связанной сущности.

Исследуй существующие правила и предложи, где лучше проводить такую проверку.

AI снова пошёл изучать проект. Нашёл несколько условий. Посмотрел, как определяется допустимость других действий. После этого предложил добавить отдельную проверку возможности повторной отправки.

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

Это был не тот результат, который я ожидал

Когда я впервые отдавал задачу целиком, мне казалось, что эксперимент проверяет один вопрос:

Может ли AI самостоятельно реализовать feature?

Но после него меня гораздо больше заинтересовал другой:

Где именно AI перестаёт понимать задачу без моего участия?

Оказалось, что граница проходит совсем не там, где я ожидал.

Найти файлы — смог. Разобраться в связях — смог. Обнаружить существующую реализацию, которую можно переиспользовать, — смог. Предложить архитектурно нормальный вариант — смог. Написать код — смог. Добавить тесты — смог.

А вот понять одно неявное бизнес-правило — нет. Причём это правило нигде явно не было написано. Оно существовало в моём понимании системы. И, вероятно, в понимании ещё нескольких людей, которые с ней давно работают. AI просто неоткуда было его взять.

Именно тогда я иначе посмотрел на контекст

До этого слово «контекст» для меня в основном означало техническую информацию. Дай AI нужные файлы. Покажи структуру проекта. Расскажи, какие библиотеки используются. Опиши coding style.

Но оказалось, что самый важный контекст часто вообще не находится в коде.

Почему эта функция существует? Кто ей пользуется? Что считается корректным поведением? Какие действия технически возможны, но бизнес-смысл уже потеряли? Какие ограничения команда считает очевидными и поэтому нигде не документирует?

Когда работаешь над проектом годами, ты практически не замечаешь этот слой знаний. Просто принимаешь решения с его учётом. А когда задачу получает AI, отсутствие этого слоя становится очень заметным.

Но я не пожалел, что отдал задачу целиком

Можно было сделать вывод:

Вот поэтому нельзя давать AI большие задачи.

У меня получился противоположный.

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

AI самостоятельно нашёл существующий retry-механизм. Не стал дублировать логику. Собрал довольно хорошую картину связей. Предложил нормальный план.

То есть проблема была не в том, что задача оказалась слишком большой. Проблема была в том, что часть требований существовала только у меня в голове. И это уже не столько проблема AI, сколько проблема постановки задачи.

Feature — это не большой кусок кода

Наверное, именно это стало главным выводом того эксперимента.

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

Feature устроена иначе. Она пересекает несколько слоёв приложения.

featureсамое важное — между слоями
бизнес-требование
    ↓
существующее поведение
    ↓
архитектурные ограничения
    ↓
backend
    ↓
данные
    ↓
интерфейс
    ↓
права
    ↓
пограничные сценарии
    ↓
тесты

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

После этого я стал чаще отдавать AI результат, а не способ его получения

Раньше мои запросы описывали действия:

Создай класс.

Добавь метод.

Измени controller.

Напиши тест.

Теперь я стараюсь сначала описывать результат:

Пользователь должен получить возможность сделать X при условиях Y, но действие не должно быть доступно в случае Z.

А уже потом прошу AI исследовать, как лучше встроить это в существующую систему.

Иногда его вариант совпадает с моим. Иногда оказывается хуже. А иногда он находит решение, до которого я сам не дошёл, потому что слишком хорошо знаю проект и автоматически иду по привычному пути.

Это, пожалуй, одна из самых неожиданных сторон работы с coding agents. Опыт помогает быстро находить решения. Но иногда он же заставляет слишком быстро решить, где именно нужно искать.

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

Я всё ещё не отдаю задачу и не ухожу

После первых экспериментов стало понятно, что фраза «отдать AI задачу целиком» может звучать немного обманчиво.

Это не означает:

не такответственность остаётся
задача
    ↓
AI
    ↓
готово

По крайней мере мой процесс пока совсем не такой. Скорее:

скорее такзадача целиком, не ответственность
задача
    ↓
AI исследует
    ↓
я смотрю, правильно ли он понял систему
    ↓
AI предлагает план
    ↓
я проверяю предположения
    ↓
AI реализует
    ↓
тесты
    ↓
review
    ↓
находим то, чего не учли
    ↓
ещё одна итерация

То есть я действительно отдаю ему задачу целиком. Но не ответственность за то, что результат окажется правильным. Эта разница для меня пока принципиальна.

Именно тогда AI впервые перестал быть просто инструментом для написания кода

До этого я мог использовать его очень много. Но схема оставалась прежней:

раньшея думаю, AI пишет
я думаю
    ↓
AI пишет

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

после экспериментасовместное исследование
мы исследуем
    ↓
обсуждаем решение
    ↓
AI реализует
    ↓
я проверяю

Она оказалась не всегда быстрее. Иногда я действительно мог бы решить маленькую задачу самостоятельно быстрее, чем агент успеет исследовать половину проекта.

Она не гарантировала правильного результата. Первый же эксперимент это прекрасно показал.

Но она открывала совершенно другой способ разработки. Я больше не был обязан заранее знать, какой класс нужно изменить. Мне было достаточно знать, какой результат нужен системе. А поиск пути к этому результату впервые можно было разделить с AI.

И, наверное, именно с этого момента для меня началась настоящая работа с coding agents. Не тогда, когда AI впервые написал хороший PHP-код. А тогда, когда я впервые сказал ему не «напиши мне этот сервис». А:

Вот задача. Сначала разберись, как её правильно решить.

К этому я шёл через долгий этап, когда использовал AI как хороший autocomplete.

#ai #code review #coding agents #контекст #постановка задач #feature

Соседние рубрики