Vibe coding 180 000 строк: как Claude пересобрал Direct2D для Paint.NET на Linux
Создатель Paint.NET доверил Claude переписать Direct2D для WINE — 180 000 строк без ревью. Разбираем, что сработало, а что пришлось контролировать вручную.
Создатель Paint.NET Рик Брюстер (Rick Brewster) объявил, что редактор наконец нормально работает на WINE — прослойке, которая позволяет запускать Windows-программы на Linux. Проблему решил не патч и не костыль, а полностью написанная с нуля Claude'ом реализация Direct2D объёмом 180 000 строк кода, которую Брюстер честно называет «vibe coded» и признаётся, что не смог её всю прочитать. Это редкий публичный кейс, когда автор крупного коммерческого продукта открыто описывает, где AI-агент реально спас проект, а где его пришлось буквально одёргивать.
История интересна не сама по себе, а как чек-лист для всех, кто думает доверить агенту не мелкий скрипт, а инфраструктурный кусок кода, который потом невозможно вручную вычитать.
Почему готовые решения не подошли
Direct2D — графический API Microsoft, на котором построен весь рендеринг в Paint.NET. Команда WINE годами пыталась реализовать Direct2D, но это огромная и сложная спецификация, и, по словам Брюстера, «ясно, что она никогда не будет доделана достаточно, чтобы Paint.NET мог ей пользоваться». Отключить Direct2D тоже нельзя — редактор на нём завязан целиком.
Единственный оставшийся вариант — написать собственную, чистую (clean-room) реализацию Direct2D специально под WINE, не трогая основной код продукта. Именно эту задачу Брюстер отдал Claude. Библиотека получила название PaintDotNet.Windows.Direct2D1.Managed.dll и включается флагом /wine — то есть работает как отдельный, изолированный слой, а не вмешивается в остальные 700 000 строк проекта, над которым Брюстер работает больше 20 лет.
Изоляция — первый практический урок: если отдаёте агенту генерацию большого объёма кода, выносите его в отдельный модуль с явной точкой входа. Так масштаб «доверия» ограничен одним компонентом, а не всей кодовой базой.
Что реально умеет агент на такой задаче
Брюстер отдельно отмечает, что часть работы Claude выполнил не хуже, чем «десять только что расковавшихся Эйнштейнов уровня 10x-разработчика» — это касается reverse engineering встроенной библиотеки эффектов Direct2D. Формулы для эффектов нигде не задокументированы официально, их нужно было восстанавливать по наблюдаемому поведению и косвенным данным. Именно в такой задаче — итеративном подборе, проверке гипотез, переборе вариантов реализации — агент показал выносливость, которой не хватает человеку при работе с сотнями похожих, но не идентичных случаев.
Это второй урок: агенты особенно полезны там, где задача состоит из множества однотипных, но объёмных подзадач — портирование API, восстановление форматов, генерация похожих модулей по шаблону. Человек устаёт от рутины на пятидесятом повторении, агент — нет.
Где агент ошибался и что с этим делать
Брюстер прямо говорит: «мне пришлось нянчиться с Claude, чтобы убедиться, что управление ресурсами делается правильно». Конкретный баг — агент какое-то время не вызывал аналог AddRef() для объектов со счётчиком ссылок (COM-модель управления памятью, где каждый объект должен инкрементировать счётчик при передаче ссылки, иначе он будет уничтожен раньше времени). Это тихая, но фатальная ошибка: она не ломает компиляцию, а вызывает утечки или падения в рантайме спустя много шагов после источника проблемы.
Второй класс проблем — архитектурные решения. Брюстер пишет, что «пришлось пару раз шлёпнуть» агента за откровенно плохой дизайн. Это типичная слепая зона любого LLM: он умеет писать синтаксически корректный и даже работающий код, но не всегда видит долгосрочные последствия структурных решений — как код будет расширяться, где появится дублирование, где сломается инкапсуляция.
Практический вывод для тех, кто повторяет такой подход:
- Заведите чек-лист специфичных для домена паттернов управления ресурсами (счётчики ссылок, закрытие хендлов, dispose-паттерны) и просите агента явно подтверждать их соблюдение в каждом крупном модуле.
- Не полагайтесь на «код компилируется и тесты зелёные» как на признак корректности управления памятью — баги вроде отсутствующего
AddRef()тесты обычно не ловят. - Просматривайте архитектуру модуля до того, как агент начнёт генерировать десятки файлов по этому шаблону — исправить решение на уровне 5 файлов дешевле, чем на уровне 180 000 строк.
Как ревьюить код, который физически невозможно прочитать целиком
Ключевое признание Брюстера: «Я не могу просмотреть 180 000 строк кода, это просто слишком много». Для сравнения — весь остальной Paint.NET, написанный вручную за два десятилетия, это 700 000 строк. То есть агент за относительно короткое время сгенерировал код объёмом в четверть основного продукта, и полноценный построчный ревью такого объёма нереалистичен ни для одного человека.
Отсюда стратегия «trust me bro», которую Брюстер описывает открыто: он не претендует на то, что весь код проверен. Вместо тотального ревью применяется выборочный контроль в критичных точках — управление ресурсами, архитектура, работоспособность на реальных сценариях использования. Это осознанный компромисс, а не халатность: продукт работает, тестируется пользователями, а код изолирован в отдельном модуле, который включается явным флагом.
Для собственных проектов это означает: если объём агентской генерации превышает разумный порог ревью (у каждой команды свой, но ориентир — если вы физически не успеваете прочитать код за разумное время), закладывайте:
- Изоляцию сгенерированного кода в отдельный модуль с чёткой границей ответственности.
- Явный флаг или механизм включения/выключения этого модуля — путь к откату, если что-то пойдёт не так.
- Точечный ревью критичных зон (память, потоки, безопасность) вместо построчного чтения всего.
- Реальное тестирование на живых сценариях как основной инструмент валидации, раз построчный ревью невозможен.
Что попробовать дальше
Если у вас есть застрявший инфраструктурный кусок проекта — что-то, что годами не удаётся доделать силами команды или сторонних библиотек, — попробуйте выделить его в изолированный модуль и отдать агенту на reverse engineering или переписывание с нуля, как это сделал Брюстер с Direct2D. Начните с малого масштаба, зафиксируйте домен-специфичные паттерны (в вашем случае это не COM-счётчики, а что-то своё — транзакции, блокировки, сериализация) и явно проговаривайте их агенту на каждом крупном этапе. И заранее решите, что будет вашим критерием «код готов», если прочитать его целиком не получится.
FAQ
Что такое clean-room reverse engineering и зачем это делать через AI-агента?
Это разработка совместимой реализации API без доступа к исходному коду оригинала — только по документации и наблюдаемому поведению. Агент здесь полезен тем, что может перебирать множество гипотез о поведении системы быстрее человека, особенно там, где формулы и алгоритмы не задокументированы официально.
Можно ли доверять агенту код, который никто не прочитает целиком?
Да, но с оговорками: код должен быть изолирован в отдельный модуль с явной точкой включения, критичные зоны (память, ресурсы, архитектура) нужно проверять точечно, а основным критерием качества становится реальное тестирование, а не построчный ревью.
Какие ошибки чаще всего допускают AI-агенты в системном коде?
Из этого кейса — пропуск инкрементов счётчика ссылок для управления памятью (COM-модель) и слабые архитектурные решения. Оба класса ошибок не ловятся стандартными тестами и требуют целевой проверки человеком.
Как решить, когда объём сгенерированного кода становится непроверяемым?
Ориентируйтесь не на абсолютное число строк, а на реальную возможность вашей команды его прочитать за разумное время. Если модуль растёт быстрее, чем вы успеваете его ревьюить, переходите на выборочный контроль критичных зон и полагайтесь на изоляцию и тестирование на реальных сценариях.
Почему Брюстер не переписал весь Paint.NET с помощью Claude?
Потому что основной код продукта — 700 000 строк, написанных и проверенных вручную за 20 лет, и риск непроверяемых изменений в нём выше, чем в изолированном новом модуле под конкретную платформу. Агенту отдали ровно ту часть, где альтернативы не было и где ошибка не затрагивает основной продукт напрямую.
Источники
Читайте также
Комментарии
Пока никто не написал. Будьте первым.
