Довольно долго мне казалось, что я активно использую AI в разработке.
Я спрашивал у него про библиотеки. Просил написать отдельные функции. Генерировал тесты. Показывал ошибки. Иногда отдавал класс целиком и просил предложить рефакторинг.
Со стороны всё выглядело вполне современно. AI уже был частью моей ежедневной работы.
Но сейчас я понимаю, что использовал достаточно мощный инструмент примерно так же, как когда-то использовал хороший autocomplete. Он помогал мне писать быстрее. Но почти не участвовал в самой разработке.
Моя первая модель была очень простой
Большинство задач выглядело примерно так:
задача
↓
я придумываю решение
↓
AI пишет кусок кода
↓
я вставляю
То есть вся настоящая инженерная работа всё равно оставалась на мне.
Я разбирался в задаче. Я изучал существующий код. Я решал, какие классы нужно изменить. Я выбирал архитектурный подход. Я определял, какие зависимости использовать. Я думал о граничных случаях.
А потом в какой-то момент обращался к AI:
Напиши мне вот этот метод.
И он писал. Иногда хорошо. Иногда требовал нескольких уточнений. Иногда уверенно придумывал API, которого не существовало.
Но это уже детали. Главное — я использовал AI только на самом последнем участке пути. Когда решение уже практически существовало у меня в голове.
Получалось быстрее, но не сильно иначе
Такой подход действительно полезен. Особенно когда нужно написать что-то рутинное. DTO. Mapper. Тестовый fixture. SQL-запрос. Регулярное выражение. Миграцию. Небольшой сервис.
В таких задачах AI экономит время. И это уже немало.
Но постепенно я начал замечать странную вещь. Я мог говорить, что использую AI каждый день, но сам процесс разработки почти не изменился. Я всё так же сначала полностью решал задачу самостоятельно. Просто теперь часть клавиатурной работы выполнял кто-то другой.
Получался своеобразный очень умный генератор boilerplate. Я думал. AI печатал.
Наверное, это было естественно
Когда появляется новый инструмент, мы почти всегда сначала пытаемся встроить его в старый процесс.
Первые автомобили называли безлошадными экипажами. Первые веб-приложения пытались копировать интерфейсы desktop-программ. А AI я долго пытался встроить в привычную схему работы программиста.
У меня уже был процесс. IDE. Документация. Google. Stack Overflow. Debugger. Тесты. Code review. И в эту цепочку просто добавился ещё один инструмент.
Теперь вместо того чтобы искать пример на Stack Overflow, можно было спросить модель. Вместо того чтобы вручную набирать двадцать строк стандартного кода, можно было попросить её сгенерировать их. Вместо чтения нескольких страниц документации можно было попросить краткое объяснение.
То есть AI получил своё место. Но само место оказалось довольно маленьким.
Я задавал слишком маленькие вопросы
Это особенно хорошо видно сейчас.
Раньше типичный запрос мог выглядеть так:
Напиши Symfony EventSubscriber, который будет делать X.
Или:
Как лучше реализовать Value Object для Money?
Или:
Напиши тест для этого метода.
Сам по себе такой запрос вполне нормальный. Проблема появляется, когда почти вся работа с AI состоит только из таких запросов.
Потому что тогда модель знает только маленький фрагмент задачи. Она не знает проект. Не знает соседние классы. Не знает архитектурные ограничения. Не знает, как похожая задача уже решена в другом модуле. Не знает, что через два файла есть готовый сервис, который можно переиспользовать. Не знает, что предлагаемое ею решение нарушит договорённость, принятую командой полгода назад.
И получается довольно странно. У тебя есть инструмент, который способен анализировать большие объёмы контекста. А ты показываешь ему один метод.
Я слишком рано придумывал решение сам
Это, наверное, было более важной ошибкой.
Допустим, приходила задача:
Нужно добавить возможность повторной отправки уведомления.
Я открывал проект. Сам находил существующий сервис. Смотрел, как отправляются уведомления. Решал, куда добавить новый метод. Продумывал интерфейс.
А потом приходил к AI примерно с таким запросом:
Добавь метод
resend()в этот сервис.
В этот момент пространство решений уже практически исчезло. AI не решал задачу. Он реализовывал мой вариант решения.
Причём вполне возможно, что вариант был хорошим. Но тогда возникает вопрос: а зачем мне вообще была нужна достаточно мощная модель? Чтобы быстрее написать десять строк? Наверное, можно было использовать её интереснее.
Переломным стал очень простой вопрос
В какой-то момент вместо:
Как мне реализовать это?
я начал чаще писать:
Посмотри, как это уже устроено в проекте.
На первый взгляд разница небольшая. Но она полностью меняет характер взаимодействия.
Теперь AI сначала должен что-то узнать. Найти связанные классы. Посмотреть существующие реализации. Понять зависимости. Собрать контекст. И только после этого предложить изменение.
Следующий шаг оказался ещё интереснее:
Пока ничего не меняй. Сначала объясни, как работает эта часть проекта и где лучше внести изменение.
И внезапно AI перестал быть только генератором кода. Он начал участвовать в исследовании задачи.
Сегодня моя схема выглядит скорее так
Не всегда. Не для каждой задачи. Но для достаточно крупных изменений процесс всё чаще выглядит примерно так:
задача
↓
AI исследует проект
↓
AI предлагает решение
↓
мы уточняем
↓
AI реализует
↓
проверка
Иногда между этими этапами появляется ещё несколько кругов. AI нашёл два варианта реализации. Я выбрал один. Попросил проверить, не ломает ли он публичный API. Нашлась ещё одна зависимость. План изменился. Только после этого начинается реализация.
И это уже принципиально другой способ работы.
Самое важное происходит до генерации кода
Раньше моментом использования AI для меня было появление кода. Теперь всё чаще самая полезная часть происходит до него.
Например, можно попросить:
Найди все места, связанные с изменением статуса заказа.
И получить карту зависимостей. Можно спросить:
Какие части системы могут сломаться, если изменить этот интерфейс?
Можно попросить:
Посмотри, как похожая задача решена в других модулях.
Или:
Предложи три варианта реализации и объясни компромиссы.
Ни одной строки production-кода ещё не написано. Но значительная часть инженерной работы уже выполнена.
И именно здесь я начал видеть настоящую ценность инструмента. Не в том, что он быстрее печатает PHP. А в том, что он может помогать думать о проекте целиком.
Это не значит, что AI теперь должен принимать все решения
Здесь легко уйти в другую крайность. Если раньше я использовал AI как autocomplete, можно решить, что теперь нужно просто отдавать ему задачу целиком:
Сделай всё.
Это тоже редко работает хорошо. По крайней мере в моих сценариях.
Проблема не исчезает. Она просто меняет форму. AI может исследовать не те части проекта. Сделать неправильные предположения. Выбрать технически красивое решение, которое не подходит бизнесу. Не заметить неявное ограничение.
Поэтому сегодняшняя модель для меня — не:
задача
↓
AI всё делает
А скорее совместная работа. Он исследует. Предлагает. Я задаю направление. Он уточняет. Я добавляю контекст. Он реализует. Потом результат проверяется.
То есть уменьшается не роль разработчика. Меняется место, где эта роль особенно важна.
Я стал меньше объяснять, как писать код
Это ещё одно любопытное изменение.
Раньше мои запросы часто были очень конкретными:
Создай класс X.
Добавь метод Y.
Используй такой-то паттерн.
Внедри вот эти зависимости.
Верни такой объект.
Фактически я писал реализацию естественным языком. Модель только переводила её в PHP.
Теперь я чаще пытаюсь описать другое: что нужно получить; какие есть ограничения; что нельзя ломать; какое поведение важно сохранить; как понять, что задача выполнена правильно.
Например, вместо:
Создай
OrderCancellationService, внедри туда repository и event dispatcher...
можно сказать:
Нужно добавить отмену заказа до момента его передачи во внешнюю систему. Посмотри текущую модель статусов, существующие сервисы и события. Публичное API менять нельзя. Сначала предложи вариант реализации.
Второй запрос оставляет AI пространство для исследования. И заодно позволяет проверить, совпадает ли его понимание проекта с моим.
Оказалось, что хороший AI-процесс похож на хороший code review
Наверное, потому что и там, и там полезно не просто смотреть на код. Полезно задавать вопросы.
Почему выбран этот подход? Какие альтернативы рассматривались? Что произойдёт в таком сценарии? Есть ли уже похожая реализация? Какие места зависят от этого изменения? Можно ли сделать проще? Что будет при ошибке?
То есть взаимодействие с AI постепенно перестало напоминать заказ кода. Оно стало больше напоминать разговор с разработчиком.
Разумеется, с важной оговоркой: этот разработчик способен очень уверенно ошибаться. Поэтому доверие здесь всегда должно быть проверяемым.
Я всё ещё использую AI как autocomplete
И в этом нет ничего плохого.
Если мне нужен маленький helper, странно запускать полноценное исследование проекта. Если нужно написать очевидный тест, проще попросить его сразу. Если я точно знаю решение, нет необходимости каждый раз устраивать архитектурную дискуссию.
Ошибка была не в использовании AI для маленьких задач. Ошибка была в том, что я считал это почти единственным способом его использования.
То есть проблема была не в конкретном инструменте. Проблема была в моей модели взаимодействия с ним.
Я оптимизировал набор текста, хотя можно было оптимизировать процесс
Наверное, именно так я сейчас сформулировал бы главное изменение.
Я долго смотрел на разработку как на цепочку, где самое очевидное место для ускорения — написание кода. Это логично. Программист пишет код. AI умеет писать код. Значит, нужно заставить AI писать код быстрее.
Но в реальной задаче само написание кода часто занимает далеко не большую часть времени. Нужно понять требования. Разобраться в существующей системе. Найти нужное место. Понять последствия изменения. Выбрать подход. Проверить гипотезу. Протестировать результат. Исправить то, что не учёл.
И если AI подключается только после всего этого, он ускоряет очень маленький участок процесса.
Сегодня мне гораздо интереснее экспериментировать с тем, что произойдёт, если дать ему участвовать почти во всей цепочке. Не обязательно принимать решения вместо меня. Но помогать их находить.
Поэтому я долго использовал AI неправильно
Хотя слово «неправильно» здесь, наверное, немного несправедливое. Скорее слишком осторожно. И слишком привычно.
Я пытался встроить новую технологию в старый способ работы. Получил хороший autocomplete. Хороший Stack Overflow. Хороший генератор тестов. Хороший помощник для написания boilerplate.
И всё это было полезно. Просто оказалось, что возможности инструмента были шире моей модели его использования.
Сегодня вместо вопроса:
Как AI может написать этот код за меня?
мне гораздо интереснее другой:
Какую часть этой задачи вообще имеет смысл решать вместе с AI?
И ответы постепенно становятся всё менее очевидными. Иногда это код. Иногда исследование проекта. Иногда поиск вариантов. Иногда review. Иногда тестирование. Иногда попытка доказать, что выбранное решение неправильное.
И в этом, пожалуй, для меня произошёл главный переход.
Я использовал достаточно мощный инструмент как очень хороший autocomplete.
А потом понял, что ускорять можно не только написание кода. Можно менять сам процесс разработки. Про то, как из-за этого снова приходится учиться программировать, я писал отдельно.