Comments 38
Спасибо за статью, пока читал, аж пульс повысился))
Хорошее предостережение. Я ожидал, что такие задачи должны для claude быть прям тривиальными, все таки очень мало творческой части, формальное преобразования одного диалекта в другой, а оказывается и тут все не так просто.
Проблема в том, что невозможно толком его консервативностью управлять. Ну т.е. с человеком можно договориться, с чатботом нельзя. Можно только надеяться.
Если ты позовешь собаку - она придет. Если кота - он, возможно, примет во внимание.
Было бы интересно узнать сколько PR пришлось возвращать на доработку и сколько реальных косяков всё-таки пропустили (но это через годик). И сколько все денег по итогу стоило...
По возвратам примерно каждый пятый PR шёл на доработку, чаще не из-за ошибок а из-за того что Claude выбирал тип который формально правильный но не наш паттерн. Реальных косяков в продакшене не было, но именно потому что тестовое покрытие держали жёстко, без этого страшно даже думать. По деньгам вышло примерно $800-850 на токены за весь проект, это в два-три раза дешевле ручной работы если считать честно с зарплатой.
С человеком тоже не всегда договоришься, особенно если это джун, дорвавшийся до рефакторинга. Нейронке хотя бы можно жесткие системные промпты прописать и она не будет обижаться
Я тоже так думал пока не начали. Типы это самое простое, дальше идут conditional types, overloads, дженерики которые Claude пишет корректно но не так как я написал бы сам, и потом ревью которое в итоге съело больше времени чем сама миграция. Формально один диалект в другой, по факту архитектурные решения пачками.
Думаю многим нейросетям сейчас не хватает одного - приостановка написания кода и уточнение вопросом по типу: «я хочу преобразовать этот кусок кода таким образом, но не уверен, так ли надо сделать конкретно в этой ситуации?». Это и количество потраченных токенов уменьшило бы, да и время потраченное на рефакторинг кратно снизилось.
У меня было такое, что агент остановился и задал вопрос. Но только один раз такое было.
В курсоре есть plan mode и он вполне переспрашивает, показывает план того что будет делать итд итп.
Но радости от этого немного. Если всё это проверять, то ... оно конем, проще и быстрее сделать самому.
Согласен, у нас это решалось через правило в CLAUDE.md что перед изменением публичных интерфейсов надо выписать план и дождаться ок. Не идеально, иногда пропускал, но лучше чем ничего. Хочется чтобы это было встроено в модель, а не костыль через промпт.
Современные агенты уже умеют делать паузы через вызов специальных тулзов для запроса апрува у юзера. Нужно просто правильно настроить песочницу перед запуском скрипта
Полезно было бы вычитать статью и убрать из нее чуждую для русского языка форму подачи мысли. Ну не говорят люди таким языком, как следствие читается плохо, нейрослоп-детектор забирает внимание...
Опять слоп...
Год назад Claude вроде такого не умел, а проект стартовал не ранее сентября 2025 года, судя по статье (6 месяцев + 10 недель)
Про silent logic change — тот же класс ошибок у меня на компиляторе. Был план, где агент перетипизировал утилитную функцию, тесты прошли, а через день я случайно открыл вызов из другого модуля и увидел что возвращается не то.
Помогает второй агент — после закрытия плана отдельный смотрит допущения, на которых тесты держатся. Пару раз ловил то, что ревью пропускало.
5-15 файлов в батче — это эмпирика? У меня плавает.
Второй агент для ревью неплохая идея, но он точно так же может галлюцинировать и в итоге все равно нужен живой разраб, который понимает изначальную бизнес-логику этой функци
Согласен, критик тоже галлюцинирует, не панацея. У меня он ловит другой класс ошибок: провисшие допущения из плана. Например, план говорил «функция идемпотентна», критик идёт проверяет, а что будет если её случайно вызвать дважды? Тесты этого не проверяют, билд зелёный, допущение тихо не работает.
Финальное «годен/негоден» всё равно у меня. Цепочка агент → критик → я. Без понимания бизнес-логики на моей стороне ничего не починить, тут согласен.
Провисшие допущения, хороший термин. У нас были такие же случаи, план фиксировал инвариант, критик его не оспаривал, а оспорить надо было. Добавил в процесс шаг: после закрытия плана явно перечисляем каждое допущение и задаём вопрос «что если это неправда». За два месяца поймали так три кейса, один из которых точно ушёл бы в прод без этого.
Да, именно такой кейс. Скомпилилось, тесты зелёные, а в runtime ведёт себя иначе. Второй агент который смотрит на допущения после закрытия плана, хорошая идея, беру в копилку. У нас такого не было только потому что ревью делал вручную после каждого батча. По 5-15 файлам да, эмпирика. Плавает от размера и плотности типов. На простых утилитах можно и 20, на файлах с дженериками лучше ближе к 5. Ориентировался на то когда начинал чувствовать что контекст расплывается.
Про плотность типов точно, у меня то же на плотности абстракций в плане. На задачах вида «поправить дженерик в трёх местах» батч держит 10-15 файлов. Когда план трогает type inference, режу до 3-5; дальше агент теряет нить между файлами. «Контекст расплывается» это в точности то ощущение, что у тебя на дженериках.
Плотность абстракций лучше описывает проблему чем размер батча. У меня похожая точка разреза: сколько разных файлов нужно держать в голове чтобы принять одно решение. Три и меньше, батч большой. Пять и больше, режу агрессивно. С type inference всё сложнее, там решения каскадируют и часто не видно заранее насколько далеко цепочка тянется.
Промпты с явным указанием контекста вызовов работают отлично, забрал себе на заметку. Жаль только что вся эта магия рассыпается, как только у тебя в базе появляется хитрая фабрика с динамическими импортами
Логически «правильно» — типы проставлены верно. Но поведение изменилось:
nullтеперь рендерится как строка"null"вместо пустой строки. В продакшене это сломало отображение имён пользователей у которых не заполнено поле.
Это говорит о том, что у вас не хватает юнит тестов.
Создание юнит тестов даже казалось бы тупых это важный шаг для улучшения контекста и принятия более правильных решений в миграции.
Занимаюсь типизацией больших проектов на Python. Без предварительного покрытия тестами всяких граничных случаев получаем много ошибок. Плюсом получаем дополнительные проверки и более надёжный код.
Согласен. У нас тесты на бизнес-логику были, а вот граничные случаи, null, undefined, пустая строка, не везде. Именно там и поймали. Теперь это первое что проверяю перед тем как запускать миграцию.
Что действительно хорошего принесли нам модели это за секунды получить все эти тесты которые никто не хочет писать и отнимают уйму времени.
Раньше делали спеки со всеми граничными случаями , потом начали забивать на это.
А сегодня это всего лишь вопрос желания и понимания.
Именно. Мы раньше тоже срезали на граничниках, “потом допишем”. Потом превращалось в никогда. Сейчас описываю кейсы словами, Claude пишет тесты за минуту. Уровень покрытия вырос, и это не заслуга дисциплины, просто стоимость написать тест упала до нуля.
Очень рад, что к вам в команду пришло поднимание.
У меня пока это не встречается с большим энтузиазмом.
Покрытие простых случаев до сих пор считается как ненужные проверки.
Хотя тоже какая разница. Это бежит миллисекунды и требует 0 времени на поддержку сегодня.
Высокий уровень покрытия не отражает качество тестов, вообще никак. Тесты, которые тестируют некачественно права на жизнь не имеют.
Согласен. Я имел в виду не процент, а сам факт что граничные случаи теперь описаны и проверены, пусть и несовершенно. До этого их не было вообще. Процент сам по себе не метрика.
А что такое некачественно?
Положим у нас JS функция sum(a,b) ожидает объект.
По вашему проверки на null, undefined,NaN не нужны ведь этого никогда не произойдёт?:)
Я перевёл 200K строк JS на TS с Claude Code. Что прошло, что сломалось