В обычном режиме это заняло бы 2-3 недели. Но мы смогли затолкать за сутки. В общем, как это было.
Конвейер
Нас было трое: я и два ревьюера - @IvanKirpichnikov и @powersemmi.
Задача - сделать CI гораздо суровее ко внешним контрибуторам. А для этого пришлось чинить кучу ruff и mypy косяков в самом FastStream. Например, тесты у нас не были покрыты mypy - и там было что-то около 4к ошибок. Естественно, такую дичь делать руками не хочется, но и на полный откуп LLM отдавать нельзя - поэтому работали так:
1️⃣ нарезаю задачи Claude'у
2️⃣ пока он пыхтит - ревьюю предыдущую
3️⃣ отдаю парням, они смотрят после меня
4️⃣ комменты от всех троих уходят обратно в Claude
5️⃣ следующая задача
И так до полуночи, а потом еще утром посмотреть, что нейронка наделала за ночь.
В итоге затащили много всего, но в основном гигиену: strict mypy на все тесты, новые правила линтера, дыры в типах, CI-гейты, правки по документации, фиксы флакающих тестов. Задачи мелкие и проверяемые - поэтому конвейер и не встал.
НА УДИВЛЕНИЕ формат оказался очень здравым - работа шла довольно споро, ревьюить было легко, никто не заебался (надеюсь), результат меня полностью устраивает. Этакий формат парного вайб-программирования. Пофиксили даже некоторые штуки, про которые я думал, что это невозможно🤯
Затык - в ревью
Я уже давно заметил, что затык в разработке сейчас состоит не в скорости генерации кода, а в постановке задач и ревью. В соло я могу поставить 40 задач за вечер, а потом 2 недели их ревьюить🥲 Поэтому ревью - это сейчас самая тяжелая работа. Но формат, когда одна нейронка слопит на несколько человек ревьюеров - это какое-то спасение. У каждого свои баясы, свой набор критериев в голове, поэтому и получается довольно комплексный гейт качества на выходе.
И тут есть нюанс, как катить такие PR'ы, чтобы люди могли их смотреть как семечки:
БЕЙТЕ, сука, задачу
Можно было бы затащить mypy одним большим PR'ом с названием "mypy в тестах", но я разбил их логически штук на 13. В среднем PR выходил на +134 / -87 строк кода. Некоторые были вообще по +2/-2. Посмотреть такой можно за минуту. Поэтому и катить их можно десятками в час.
Это правило было актуально всегда, но с LLM приобрело особое значение. Слопус постоянно что-то находит в коде - то тип не бьет, то тест в CI флакнул и упал, то бага нашлась. А еще из-за высокой скорости слопописания у тебя постоянно возникает соблазн кинуть в него еще пару задач (так я, например, стащил кучу проверок из CI Django Modern Rest😁). В общем, легко моргнуть, открыть глаза - и увидеть PR на +1500/-1000 строк.
Stacked PRs
В таких ситуациях нужно не паниковать, а открывать новую сессию и отправлять слопус бить PR на несколько логических последовательных секций. Тут, кстати, очень выручает новая (и моя любимая) фича GitHub - Stacked PRs. Это когда у тебя есть 5-6-10 PR'ов, которые нужно мержить последовательно. Их можно связать в stack прямо на уровне GitHub и ревью каждого будет занимать 100-200 строк кода, а не 1500, как в общем. Или, например, у тебя есть 6 PR'ов от main, которые 100% дадут конфликты при мерже каждого из них. Ты же не хочешь решать конфликты 6 раз? Тогда отправь агента выстроить эти 6 PR'ов в stack - и они уедут в main одним паровозиком без конфликтов.
А еще крайне рекомендую всякие "вбоковые" задачи отправлять в другую сессию. CI упал из-за непонятного флакающего теста - кидаешь ссылку на ран в соседнюю сессию и просишь открыть новый PR от main с фиксом, а в текущем мерже просто ставишь ретрай запуск CI - и побежал дальше.
В общем, вещь довольно банальная, но я сильно рекомендую вам такой подход в командном слопинге. Лучше насрать 20 PR'ов по 100 строк, чем один на 2000🌚