Comments 34
У меня не получилось забивать винты молотком, поэтому, я заменил их на гвозди, клинья и заклепки.
Открыл чистую архитектору штоле?
Low coupling high cohesion, слои, ACL, ща до домена дойдешь
Бггг
Не совсем, вероятно, я плохо выразил основную мысль.
Моя гипотеза не в том, что рефакторинг плох сам по себе или что нужно бездумно плодить дублирование.
Идея была в другом.
Когда проект становится достаточно большим, ИИ начинает ломать его из-за связности. Наследование, графы импортов, неявные зависимости и постоянно меняющиеся контракты требуют удерживать в контексте слишком большой объём системы одновременно.
Человек постепенно строит ментальную модель проекта. ИИ каждый раз вынужден восстанавливать её заново из ограниченного контекста.
Поэтому моя гипотеза звучит скорее так:
Если убрать большую часть связности и собирать систему из независимых блоков с наглухо прибитыми интерфейсами, то ИИ сможет работать с существенно большими системами.
В такой модели реализация блока становится расходным материалом. Если блок работает неправильно, мы не трогаем соседние части системы. Мы просто переписываем реализацию внутри того же контракта.
Стоимость такой операции для ИИ становится близкой к нулю, потому что переписывается не система целиком, а изолированный блок с заранее известным интерфейсом.
Возможно, это тупиковая идея. Возможно, это просто переоткрытие старых архитектурных принципов под новым углом. Но мне кажется интересным посмотреть, как изменятся оптимальные архитектурные решения, если исходить из предположения, что основной автор кода — не человек, а модель.
Да. Всё верно. Программирование с агентом требует регулярного переписывания. Переписывание снижает связность и улучшает код. Это, кстати, одна из причин, почему вчитываться в код нейронки бесполезно. Что его толку читать, если уже послезавтра вы его перепишите...
Стоит поаккуратней обходиться с терминологией "Отказ от рефакторинга". То что вы предлагаете - это и есть рефакторинг. Ре фактор. Переделение, деление по другому. Это оно и есть
Справедливое замечание.
Возможно, термин «отказ от рефакторинга» действительно оказался слишком провокационным.
Я скорее имел в виду отказ от постоянного изменения уже существующих контрактов и постепенного усложнения старых модулей.
Если смотреть формально, то полная замена реализации при сохранении интерфейса действительно тоже может считаться разновидностью рефакторинга.
Наверное, точнее будет сказать так:
Не «не рефакторить», а «предпочитать замену изолированного блока изменению связанной системы».
В статье меня интересовала именно эта разница.
У меня ничего не ломается, просто им должен обязательно писать тесты. С помощью ИИ можно сделать близкое к 100 процентам покрытие тестами и этим надо пользоваться. Ну и грамотная архитектура. Я когда и сам писал, всегда использовал дерево а не граф как организацию кода, ибо сложность графа растет экспоненциально а дерева линейно
Согласен, но
Golden Armada поднимает уровень разработки с уровня кода и архитектуры на уровень описания функциональности, понятной даже человеку без технического бэкграунда.
Пользователь описывает не реализацию, а поведение системы — то, что он ожидает увидеть в результате.
При этом тесты и трейсинги остаются критически важной частью процесса. Они не заменяются и не обесцениваются — наоборот, становятся встроенной частью системы наблюдаемости и проверки корректности.
Просто их роль меняется: это уже не внешний инструмент контроля над кодом, а часть самой архитектуры, обеспечивающая прозрачность и воспроизводимость поведения системы.
А откуда такая радикальная идея - не исправлять, а писать заного?
У меня тоже мысли в том же направлении идут. Все что мы считаем аксиомой в разработке (OOP, DRY, KISS, Clean code, рефакторинг, и т.п.) имеет целью помочь человеку управляться со сложностью с учетом ментальных ограничений человека:
мы лучше понимаем объекты когда это черный ящик с парой методов,
мы забываем обновить все копии кода если что-то надо поменять, поэтому нужны функции, наследование и прочие приемы повторного использования кода,
нам проще читать чем писать, поэтому упор всегда на читаемость и дедупликацию
нам нужно делать рефакторинг потому что в какой-то момент мы запутались и не можем разобраться в сложности.
и т.д.
У ИИ все по другому:
ИИ проще сгенерировать несколько кусков похожего кода, чем прочитать функцию, реконструировать взаимосвязи и понять что она делает;
от ИИ не надо прятать внутреннюю реализацию объекта, и вообще объект для ИИ может быть не нужен или даже вредить
ИИ легко преобразует код из одного языка или синтаксиса в другой, сохраняя эквивалентность, так что традиционные тесты делаются ненужными
Сейчас код является основным артефактом, определяющим систему. Для ИИ таким артефактом тоже скорее всего будет код, но язык был бы заточен для описания архитектуры, спецификаций, графа зависимостей, движка политик и ограничений и системы формальных контрактов. А сгенерированный код не традиционном ЯП делается вторичен.
И было бы интересно увидеть как будет выглядеть что-то сложное на таком языке. Человеку все равно надо это как-то понимать...
если архитектура изначально построена правильно (послойная, с чёткими границами, инкапсуляцией и модульностью), то ИИ отлично с ней справляется.
Значит, проблема автора статьи не в том, что «все архитектуры плохи для ИИ», а в том, что он либо не умеет строить правильную послойную архитектуру, либо его проект был изначально «кашей», и он пытается вылечить её радикальным методом, который справедливо называется костылём.
Автор, судя по описанию, допустил ошибки:
Возможно, у него были циклические зависимости или «божественные» классы, которые тянули всё на себе.
Интерфейсы были размытыми или часто менялись.
Отсутствовала строгая иерархия, и модули знали друг о друге слишком много.
Когда он поручал ИИ рефакторинг, тот не мог удержать в голове все неявные связи, потому что их не было видно из кода (например, через глобальные переменные, синглтоны или косвенные вызовы).
В такой ситуации даже человеку трудно рефакторить без ошибок, а ИИ — тем более. Автор решил проблему не исправлением архитектуры (что было бы правильнее), а запретом на рефакторинг и плодя новых сущностей — это действительно выглядит как «я не умею строить нормальную архитектуру, поэтому буду дублировать».
какой размер кодо базы, когда начались проблемы, и какой размер средний одного файла кода?
И да, и нет.
Я не утверждаю, что послойная архитектура, модульность или инкапсуляция перестали работать. Наоборот, моя гипотеза выросла именно из попыток строить системы с понятными границами.
Проблема, которую я наблюдал, была немного другой.
Человек постепенно строит ментальную модель системы. Если он два часа назад изменил интерфейс или переименовал метод, то обычно помнит об этом и учитывает последствия.
Для LLM каждая новая итерация в каком-то смысле начинается заново. Модель не обладает долговременным пониманием проекта и каждый раз восстанавливает картину из доступного контекста.
Поэтому возникает ситуация, когда изменение в одном месте исправляется, а в другом месте начинает проявляться старая версия представления о системе. Отсюда и эффект «починили здесь — сломали там».
Моя гипотеза не в том, что существующие архитектуры плохие.
Скорее в том, что если проектировать систему исходя из ограничений LLM — минимизировать связность, фиксировать контракты и делать блоки максимально независимыми, — то масштаб, с которым ИИ способен работать без ошибок, может оказаться существенно больше.
Собственно, статью я и написал как попытку проверить эту гипотезу, а не как утверждение, что нашёл универсальную замену существующим подходам.
p.s. Ответ на вопрос: я не знаю. Я не считал строки и в базу не заглядывал.
Соглашусь с вами в том, что грамотная архитектура уменьшает и ментальную нагрузку. А вот ИНС как правило не способен создать хорошую архитектуру. Автор в свою очередь прав в том, что сложно для нас - то просто для ИНС и наоборот. Поэтому в проекте с нейросетями надо учитывать этот момент.
Но когда код пишет ИИ, стоимость переписывания становится нулевой.
Ну нет же. Этот новый код может содержать баги и их придётся исправлять.
Согласен, баги никуда не исчезают.
Наверное, я неудачно сформулировал мысль.
Я не имел в виду, что переписанный ИИ код автоматически будет правильным. Разумеется, новая реализация тоже может содержать ошибки.
Скорее я говорю о стоимости изменения.
Если блок имеет жёсткий интерфейс и не влияет на остальную систему, то его можно переписывать много раз практически без риска для соседних частей проекта.
А вот стоимость ошибки в связанной системе обычно выше. Изменение общего базового класса, контракта или поведения может затронуть множество зависимых компонентов сразу.
Моя гипотеза состоит не в том, что ИИ пишет без багов, а в том, что для ИИ дешевле многократно регенерировать небольшую изолированную реализацию, чем безопасно изменять сильно связанную систему, сохраняя все существующие зависимости.
Именно поэтому в статье основной акцент был не на качестве генерации, а на уменьшении связности и фиксированных контрактах.
Но когда код пишет ИИ, стоимость переписывания становится нулевой.
На работе недавно СТО решил «переписать» систему чата с помощью ИИ и crm к ней за несколько выходных, чтобы не платить SaaS. Ну решил удружить бизнесу. Радостно покликал это с фронтом и выкатил это в прод. Итог? XSS, уведенный аккаунт оператора, да еще и последующий ddos сообщениями огромного размера. Вот такая нулевая цена переписывания.
У недобросовестного клиента, в итоге, ничего не получилось, так как я в свое время со скрипом продавил идею принудительного использования впн с авторизацией через ldap и добавлением механизма, который бы вдруг становился очень придирчивым к ip пользователя, если вдруг на входе в апи появлялся бы запрос от пользователя с правами сотрудника. Но код в том числе и crm системы заботливо лежал рядом с кодом чата (километровые портянки js кода), чем пытливый клиент тут же и воспольвался.
А вам удачи.
Согласен с примером — это как раз иллюстрация обратного случая: когда границы системы не были зафиксированы, и переписывание затронуло слишком большой радиус изменений.
И на самом деле это хорошо подтверждает мою гипотезу, а не опровергает её.
Проблема возникает не из-за самого факта переписывания, а из-за отсутствия изоляции и стабильных контрактов между частями системы.
В моей модели ключевая идея как раз в том, что:
переписывание допустимо и даже желательно, но только внутри строго ограниченного блока с неизменяемым интерфейсом
То есть система должна быть устроена так, чтобы:
изменение не могло “расползаться” по зависимостям
влияние каждого блока было формально ограничено контрактом
любая замена была локальной и проверяемой
В этом смысле описанный кейс — это не контраргумент, а пример системы, где эти ограничения отсутствовали.
И именно это отсутствие границ и приводит к тем самым катастрофическим эффектам при AI-генерации или массовом переписывании.
А на основании чего вы будете уверены, что код ИИ делает именно то, что ему поручено? Тестами все не покроешь. Контракты дают только формальные границы. Если код - черный ящик, то рано или поздно он сделает то, что не должен делать.
И ладно если цена ошибки несколько часов простоя. А если несколько миллионов в деньгах? Или чья-то жизнь?
Опять же, если вы не читаете и не правите код, не убираете дублирование, неэффективные данные и код… то вы получаете тормозное раздутое приложение.
Сколько с ИИ экспериментирую, все больше убеждаюсь, что он прекрасно делает видимость того что ты хочешь, но стоит копнуть поглубже - логика там совсем не та, что ты закладывал.
Ну а читать ИИ код намного сложнее, чем код человека. Даже если код полностью покрыт комментариями. А если оставить на волю ИИ и архитектуру, это будет код: write only.
Branefuck и то читабельнее.
Согласен почти со всеми рисками, которые вы описали.
Если цена ошибки — миллионы рублей или человеческая жизнь, то никакая архитектурная идея не отменяет необходимость верификации, аудита, тестирования и ответственности человека.
Но моя гипотеза была немного о другом.
Я не предлагаю доверять ИИ без проверки и не предлагаю превращать систему в набор чёрных ящиков, которые никто не понимает.
Я пытаюсь решить более узкую проблему: как уменьшить вероятность того, что ИИ сломает уже работающую систему при внесении изменений.
Контракты в моей модели нужны не для доказательства корректности логики. Они нужны для ограничения радиуса изменений.
Другими словами, контракт отвечает на вопрос:
"Что этот блок может сломать вокруг себя?"
а не на вопрос:
"Гарантированно ли этот блок реализован без ошибок?"
Это разные задачи.
Что касается качества реализации, тут я скорее придерживаюсь классической инженерной позиции: тесты, ревью, мониторинг, верификация и человек в контуре никуда не исчезают.
Более того, именно потому что ИИ часто пишет неоптимальный или странный код, мне и хочется максимально изолировать такие реализации друг от друга.
Если блок оказался плохим, я хочу иметь возможность заменить только его, не рискуя затронуть десятки зависимых модулей.
Поэтому статья не про отказ от контроля качества. Она скорее про попытку уменьшить связность системы в мире, где значительную часть кода начинает писать модель.
Писать максимально изолированные модули - подход не новый. Он правильный, но в реальных проектах не всегда возможный.
Ограничить область изменений вносимых ИИ - это логично. Отдельный изолированный блок легче проверить, прочитать, понять логику. Он будет меньше контекста отъедать. Опять же, легче локализовать проблему при ошибка.
Но это не "подстраивать архитектуру под ИИ" (а меня именно эта фраза насторожила). Такой подход и для программистов людей хорошо работает.
Я бы сказал, что это небольшая смена парадигмы. Не исправлять плохой код, а писать заново, так как стоимость написания меньше стоимости исправления. Это не отказ от рефакторинга, это рефакторинг и есть. Просто на другом уровне.
В случае ИИ - такой подход может и сработать. Это вполне логичный способ использования ИИ. Генерируем несколько вариантов кода, выбираем тот что больше подходит и доводим до ума вручную. Если модуль достаточно небольшой или типовой - ИИ может даже с первого раза родить что-то вменяемое.
Ты немного смещаешь фокус на “качество модулей”, но моя мысль вообще не про это.
В классической модели, когда тимлид говорит “почини модуль”, разработчик почти никогда не ограничивается этим модулем. Он вынужден:
понять соседние зависимости
восстановить контекст системы
и по сути сделать мини-рефакторинг всей зоны влияния
Цена изменения высокая — поэтому включается глубокое понимание системы как целого.
С LLM ситуация другая.
LLM действительно может “починить модуль” за 10–20 секунд.
Но это уже не тот же процесс.
Потому что стоимость изменения резко падает, а радиус воздействия изменения резко растёт
И проблема не в том, что “код плохой” или “модули слабые”.
Проблема в том, что система больше не ограничивает последствия изменений через стоимость и время человеческого понимания.
В результате локально всё выглядит правильно, но глобально возникают побочные эффекты в других частях системы и они проявляются не сразу
И отсюда мой тезис:
Если стоимость переписывания кода стремится к нулю, то главным становится не “как писать модули”, а как ограничивать влияние автоматических изменений на остальную систему
И именно поэтому я говорю про усиление изоляции и “утяжеление границ” модулей — не как стиль кода, а как способ контролировать распространение изменений в системе, где цена изменений почти исчезла.
Два нюанса: то о чем вы пишите, об уменьшении влияния модулей, ни как не привязано к ИИ. Это прекрасно работает и на программистах людях и рекомендуется ни один десяток лет. Только это очень сложно реализовать на многих задачах. А так да, идея снизить зависимости, - прекрасна.
Второй нюанс: если вы замените один плохой модуль на другой плохой модуль, чем это поможет? Дешевизна ИИ-шного кода иллюзорна. Вы просто перекладываете стоимость с разработки на тестирование и поддержку.
Да, вы не пишите код неделю. Вы его месяц отлаживаете и переписываете. Причем, уже после того как код вышел в продуктив. Потому что ИИ прекрасно проходит синтетические тесты, на которых он создавался. А в реальной работе всплывают артефакты и человеческий фактор.
Верно, полностью согласен. Я бы даже сказал, если код пишет ии, а ревьюит человек, то стоимость ии-шного кода нулевая. Скорость не возрастает, Mr быстрее не апрувятся. Это абсолютно точно. Я к этому и веду, что если код пишет ии, то у человека должны быть другие механизмы верификации, другие метрики и подходы к разработке. Какие? Я не знаю. Поэтому я и хотел попробовать начать эту дискуссию.
Абсолютно с вами согласен, оставляя существующий проект на съедение вайбкодингу, без какого либо рефакторинга и контроля того, что пишет ИИ — учесть проекта сведётся к нечитабельному коду, дубликатам и хаосу, ну и ещё ИИ все равно будет труднее понимать такой проект. Увы руководство и менеджеры вышестоящие над разработчиками не всегда это понимают и больше заставляют забывать о качестве и выдавать количество (функционала)
Что если принять новую аксиому: Основным автором кода является AI, а человек является проектировщиком системы.
«А вы, друзья, как ни садитесь, всё в музыканты не годитесь» И. А. Крылов, «Квартет» ИИ-агентов
Ты немного упрощаешь идею до “AI пишет код, человек проектирует систему”, но это не то, о чём речь.
Если бы всё сводилось к роли “автор vs проектировщик”, это уже давно бы решалось архитектурой и автоматизацией.
Проблема в другом.
Когда стоимость генерации кода становится почти нулевой, меняется не роль человека, а поведение системы:
код начинает меняться слишком быстро
локальные изменения становятся дешёвыми
но их влияние на систему становится непредсказуемым
И в этот момент классическая модель “архитектор → разработчик → код” перестаёт объяснять происходящее.
Дело не в том, кто “пишет код”.
Дело в том, что:
мы больше не успеваем осмыслять последствия изменений на уровне всей системы, потому что скорость модификации превышает скорость человеческого контекстного восприятия
Поэтому вопрос не в том, что AI “заменяет разработчика” или что человек становится “проектировщиком системы”.
Вопрос в другом:
как оценивать поведение системы, если изменения стали настолько быстрыми, что человеческая модель причинно-следственных связей больше не успевает за ними?
И именно здесь появляется идея вроде Golden Armada — не как “новый способ писать код”, а как попытка восстановить наблюдаемость системы на уровне её эволюции, а не отдельных решений.
Интересные мысли (хотя и очень спорные) о том, каким должен быть код проекта, когда переходим на агентную разработку.
вайп кодинг 🫣 это про одноразовый код
LLM это не искусственный интеллект, а статистически правдоподобная машина🤷 - может сработать, а может и нет - не зря поэтому предупреждают что модели могут ошибаться. В Microsoft вовсе писали что GitHub Copilot это только для развлечения и всё полностью на ваш страх и риск "мы ни за что не отвечаем"
https://www.businessinsider.com/microsoft-copilot-entertainment-purposes-terms-of-service-agreement-2026-4?IR=T
Как я перестал исправлять ИИ код и начал проектировать под него архитектуру