Обновить

Комментарии 40

Недавно думал как раз об этом. Архитектурные практики, как способы борьбы со сложностью, были придуманы, чтобы дать возможность человеку понимать системы, выходящие по сложности за пределы его контекстного окна - кошелька Миллера - 3-5 (иногда 7) сущностей в кэше внимания. У ИИ контекстное сильно больше, но тоже ограниченное. Такая логика приводит к выводу: важность архитектуры есть функция отношения сложности проекта к размеру контекстного окна. Проще говоря, сложность проекта мы в любом случае должны компенсировать: там, где заканчивается контекстное окно, начинается архитектура. Иначе будет плохо.

Да, это ровно тот вывод, к которому я шёл всю статью, только сформулированный компактнее — «важность архитектуры есть функция отношения сложности проекта к размеру контекстного окна» я бы вынес в эпиграф. Добавлю два уточнения из практики. Первое: у LLM деградация начинается сильно раньше формальной границы окна — заявленные 200k токенов и окно, в котором модель реально удерживает все связи, это очень разные числа, так что «архитектура начинается» гораздо раньше, чем кажется по спецификации модели. Второе: даже гипотетическое бесконечное окно не отменяет архитектуру — пять чуть разных проверок баланса плохи не тем, что не влезают в контекст, а тем, что при правке нужно не забыть ни одну. Это уже не про объём внимания, а про количество мест, которые обязаны меняться согласованно.

У ИИ контекстное сильно больше, но тоже ограниченное

Против n² зависимостей между n компонентами никакое окно не поможет.

3-5 (иногда 7) сущностей в кэше внимания

Если это правильные абстракции, то их хватает.

Обезьянам раздали по гранате и теперь тут и там слышны взрывы, а форумы пухнут от историй «я не умею пользоваться инструментом, и поэтому он не работает».

Проблему узкого контекстного окна решили больше года назад, решение называется RAG, но все продолжают пытаться её решить никчемными текстами под разными названиями (скилл, субагент, и прочий мусор), которые только раздувают этот самый контекст.

а вы вообще поняли о чем статья? rag работает с семантическим слоем и отвечает на вопрос какие в базе есть релевантные по смыслу запроса чанки. в коде почти нет семантики и чанки не годятся для генерации кода потому что это не весь контекст, который нужен агенту.

Статья, my ass. Монография.

Этот, с позволения сказать, текстик — о том, что недостаток образования способен сотворить чудеса бессмысленной изобретательности.

rag работает с семантическим слоем и отвечает на вопрос какие в базе есть релевантные по смыслу запроса чанки

Да-да, конечно, жалко, что пацаны не в курсе, и давно уже используют RAG в связке с MCP для построения AST и отдачи релевантного контекста агенту, а не продолжают долбиться в набор буковок, который не влезает в контекстное окно.

ммм... срач в комментах, ну как тут устоять))) спасибо за прогрев

там помимо вашего rag еще куча тейков в статье, автору респект за труды! мега полезный материал

А можно подробности? Статьи, примеры. Я как раз недавно задумался о возможности применения семантического поиска непосредственно к коду. И хотелось бы увидеть существующие наработки.

Было бы можно, но напыщенные невежи отрезали мне возможность делиться опытом, как это всегда и бывает на хабре; напишите в личку — дам и ссылки и примеры.

RAG поверх AST — это ответ на вопрос «как быстрее найти код». А статья — про то, что находить должно быть нечего.

Если проверка баланса живёт в пяти местах, идеальный retrieval честно притащит агенту все пять копий — и что дальше? Он всё так же должен удержать их в контексте и не забыть ни одну при правке. Вы просто построили скоростную магистраль к болоту. Архитектура — это когда проверка одна, лежит в предсказуемом месте, и никакой векторный индекс для этого не нужен: хватает неймспейса.

И про «никчемные тексты» — вторая половина статьи вообще-то про обратное: тексты без enforcement не работают, поэтому deptrac и ненулевой код выхода. RAG, кстати, тут бессилен: он подскажет агенту, где лежит Doctrine-репозиторий, но не помешает заинжектить его в доменную сущность. Semantic search не заменяет запрет — он просто помогает нарушать быстрее.

Так что нет, не альтернатива. Retrieval — про доступ к контексту, архитектура — про то, чтобы контекста нужно было меньше, enforcement — про то, чтобы правила нельзя было обойти. Первое без второго и третьего — автоматизация раскопок в легаси.

Если проверка баланса живёт в пяти местах […]

Ессесно, эта проблема же появилась вчера, и люди не научились искать Code Duplication статанализом 25 примерно лет назад.

Архитектура — это когда […]

Архитектура — существительное, поэтому отвечать на вопрос «когда» не может.

где лежит Doctrine-репозиторий, но не помешает заинжектить его в доменную сущность […]

Да, я помню, что вы про статический анализ слыхом не слыхивали, ведь гораздо проще взять через раз работающие промпты.

Так что нет, не альтернатива.

Да ладно! А я что, где-то говорил, что альтернатива? Архитектура — штука важная, полезная и нужная, вот только она к LLM вообще никакого отношения в принципе не имеет.

Retrieval — про доступ к контексту […]

Это хорошо, что вы аббревиатуру уже на ⅓ расшифровали. Продолжайте в том же духе, и под конец (даже прямо на второй букве) вам откроется много нового и интересного.

Code Duplication статанализом 25 примерно лет назад.

Онанизм наш ваш лучший друг

Укрепляет мышцы рук

Стат анализ не отловит что ответственность дублирована и размазана

З. Ы. Не я токсичить начал

Стат анализ не отловит что ответственность дублирована и размазана

Да-да, конечно. Господи, когда ж вы все научитесь спрашивать: «как это сделать?» вместо огульного: «это сделать невозможно» на потеху публике, которая это делает уже сто лет в обед.

Умение говорить ещё не признак ума©

Про «слыхом не слыхивали про статический анализ» — половина статьи посвящена deptrac, это статический анализатор, конфиги приложены. Copy-paste-детекторы ловят текстуальные дубли; четыре чуть разные реализации одной проверки они как раз не ловят — это ровно то, о чём уже написал Dhwtj. А с тезисом «архитектура — штука важная, но к LLM отношения не имеет» спорит сама статья, аргументы там. На этом закончу, по кругу ходить не буду.

Архитектура — это когда […]

Тот комментарий писала нейросеть. Не нужно отвечать на него.

Скорее всего имеется ввиду не классический RAG только с векторной базой. А более комплексное понятие, где уже несколько слоев поиска по разным индексам. Это AST, LSP сервер, графы вызовов, графы зависимостей и т.д. и рядом уже векторная база.

В этой статье описывается многоуровневый поиск https://yage.ai/share/why-coding-agents-still-use-grep-en-20260327.html

вот это содержательный коммент, спасибо за статью

Спасибо, отличная ссылка — она, по-моему, ставит точку в споре выше. Индустриальный консенсус ровно обратный тезису «профессионалы используют RAG»: все шесть разобранных агентов (включая Cursor и Claude Code) базируются на grep, а эмбеддинги в этой иерархии — самый верхний и самый дорогой слой для редких чисто семантических запросов. И заметьте: чем чище архитектура, тем ниже по этим слоям можно оставаться — в кодовой базе с предсказуемыми неймспейсами grep по Core\Billing находит всё за один запрос, и никакой векторный индекс не нужен. Дешёвый поиск — это тоже дивиденд архитектуры.

Индустриальный консенсус […]

Рекламный текст ≠ индустриальный консенсус. Конечно, вам будут втюхивать греп, который токены жрет, как не в себя, — вместо инструментов, которые сокращают расходы пользователей в разы, а иногда — в десятки раз.

в кодовой базе с предсказуемыми неймспейсами

А куда делись размазанные по неправильным неймспейсам дубли из прошлого комментария?

ставит точку в споре

Никакого спора выше не было, мне недосуг спорить, особенно с твердолобыми. Я просто указал, как эту проблему решают профессионалы, если вам не надо — мне тем более.

Точнее было бы сказать: индустриальный консенсус не “против RAG”, а “против embedding-based retrieval как retrieval-механизма по умолчанию”. Большинство инструментов используют текстовый (grep/regex) retrieval вместо векторного, оставляя эмбеддинги для узкого класса семантических запросов. Grep – это тоже форма retrieval, так что RAG как класс тут никуда не исключается. Меняется лишь то, чем наполнено R.

R - retard

Плюсую. Но на одного, кто эти вещи понимает и использует приходится 10, которые этим не заморачивается, и 100, кто даже не знает и гордится этим.

Но на одного, кто эти вещи понимает и использует приходится 10, которые этим не заморачивается, и 100, кто даже не знает и гордится этим.


Разгребать после сотни и будет наш хлеб.

Раз в 50 промптов или 20 коммитов остановка, выдох*, мини архитектурное ревью на свежую голову.

*Смотрим на часы и принудительно идём спать

По необходимости расширенное ревью и рефакторинг

Архитектура — это не эстетика. Это способ минимизировать объём контекста, необходимый для одного изменения.

Ценная мысль. Я всегда подсознательно стремился к простоте в коде, и вот теперь этому есть обоснование.

Когда код пишет агент со скоростью тысячи строк в час, ревьюить его глазами на соответствие архитектуре невозможно — вы станете бутылочным горлышком или начнёте пропускать.

Это правда, если ревьювить каждую строчку, то наверное, было бы быстрее самому написать. Но выход есть: надо разбивать работу на этапы. Я все изменения (за исключением самых мелких) пускаю через superpowers: сначала сам пишу описание фичи или изменения в отдельном .md, потом он пишет полную спецификацию, я просматриваю и корректирую по необходимости, и далее он на основе этой спецификации пишет план реализации. Код в нём тоже есть, но на него я особо не смотрю даже, а обращаю внимание в первую очередь именно на соответствие предложенного плана архитектурным решениям. Ну и на заключительном этапе, конечно, обязательное ревью другим агентом. Пока результат (на проекте в ~30K строк кода) меня устраивает.

Что любопытно, при таком подходе количество строк документации в .md (49K) превышает количество строк собственно кода.

То, что вы описываете, — это по сути SDD, Spec-Driven Development: спецификация становится первичным артефактом, а код — её производной. Spec Kit у GitHub, Kiro у Amazon — та же идея. И ваши 49K строк .md против 30K кода — характерный признак подхода: центр тяжести проекта переехал из кода в спеки.

Это рассуждение в другую сторону от моей статьи, и мне кажется, они не конкурируют, а дополняют друг друга. Общий диагноз один: ревьюить глазами каждую строчку невозможно, контроль надо куда-то смещать. SDD смещает его вверх — в намерение: вы ревьюите спеку и план, что в разы дешевле чтения дифа. Статья — про смещение вниз, в факт: что бы агент ни задумал, deptrac и ревьювер с чистым контекстом проверят результат.

Одно другое не отменяет, потому что план агент нарушает так же непринуждённо, как и CLAUDE.md: на этапе «пишу код по спеке» его тянет в ту же копипасту и те же дырки между слоями. Согласованный план — не гарантия согласованного кода. Поэтому в идеале это два конца одного конвейера: спека/план (намерение) → генерация → машинная проверка факта. Судя по тому, что у вас в конце стоит обязательное ревью другим агентом — вы к этой же схеме и пришли, просто с другого конца.

Использовать ИИ можно очень по-разному, и любопытно, что разные пути сходятся к одному и тому же выводу: человек уходит с ревью строк на ревью намерений и границ.

Использовать ИИ можно очень по-разному, и любопытно, что разные пути сходятся к одному и тому же выводу: человек уходит с ревью строк на ревью намерений и границ.

Именно так. ИИ генерирует слишком много кода в единицу времени, чтобы человек мог его хотя бы оценивать в том же темпе. Да и честно говоря, претензию именно к качеству кода свежим моделям предъявить трудно – чисто технически они пишут хорошо. При условии, что задача, ограничения и критерии успеха сформулированы точно и недвусмысленно. Со знаменитыми галлюцинациями практически не сталкиваюсь – ну может, пару раз что-то похожее было. Вероятно, в силу именно того, что каждый шаг проекта документирован, причины принятых решений понятны и особого простора для фантазий не оставляют.

KISS + YAGNI. А вот тут обратная беда. LLM обожает «на всякий случай»: фабрику для класса с одной реализацией, конфигурируемость, которую никто не просил, слой абстракции над слоем абстракции. Выглядит солидно, ревью проходит легко («ну, аккуратно же написано»), а через месяц эта преждевременная гибкость становится тем самым лишним контекстом, который мешает следующим правкам.

не понял. Какая еще фабрика в KISS, если принцип предполагает простоту кода - в том числе меньше кода там, где он не требуется?

а поиск по кодовой базе — дорогая операция, съедающая контекст

тоже ерунда - когда вместо spec-driven-development описываю только общие правила, а cursor без отдельного по стилю ориентируется на уже существующие классы как шаблоны, то получается неплохая экономия токенов (а значит и контекст засоряется меньше). Вплоть до того, что на работе удивлялись, как это мне хватает 20$ подписки. Но это конечно, если вы используете агентов именно как помощников, а не пытаетесь генерить вообще весь проект автоматически.

Замечательная статья, спасибо. 👍

Небольшая “реплика из зала”.

Но выстраданное уточнение: DDD – это про бакенд. Именно там живёт то, ради чего DDD придуман: инварианты, транзакции, бизнес-правила, согласованность данных.

Однако, DDD придуман для другого. А именно – для синхронизации людей (domain experts <-> engineers, заказчик <-> исполнитель) вокруг одной модели предметной области, для управления сложностью решения задач из предметной области через построение декомпозированной модели, разделяемой бизнесом и разработчиками через общий язык – Ubiquitous Language.

И вот этот самый Ubiquitous Language – он вполне уместен для пояснения “фронтовикам”, что же нужно сделать. Собственно, ТЗ составляется с использованием понятийного аппарата из соответствующего bounded context. Далее по коду, который написан в соответствии со словарём, можно “грепать” или “триграмить” (как это делает Cursor для объёмных кодовых баз) или даже делать RAG.

Стратегическая часть DDD – описание домена, карта контекстов и Ubiquitous language – ключевая для понимания системы со стороны участников процесса. Да и для onboarding отличная штука. Именно UL и нужен, чтобы с “фронтовиком” общаться.

Возьмём тактическую часть DDD – допустим, Aggregate. Как паттерн моделирования (кластер сущностей + инварианты) он нужен везде, где есть сложная составная сущность, редактируемая как единое целое, включая фронт.

Соглашусь, что тот структурный шаблон, что Вы рассмотрели, на фронте действительно не приживается. Но bounded context и Ubiquitous Language относятся и к фронту, и к бэку одновременно: у обоих один и тот же язык и одни и те же понятия внутри контекста, просто бэкенд защищает инварианты, а фронт их использует (отображение, редактирование). Поэтому документы стратегического DDD (описание доменов, карта контекстов, словарь) остаются отличным источником для генерации фронтового кода – типов, форм, текстов ошибок.

Спасибо, поправка справедливая. Мне надо было разделить: «DDD — это про бакенд» относится к тактической части — агрегаты, репозитории, слоистая структура. Ровно тот шаблон, который, как вы согласились, на фронте не приживается.

Стратегическая часть — bounded contexts, карта контекстов, Ubiquitous Language — конечно, общая для всей системы. В статье она неявно так и работает: «карта» для агента и deptrac-contexts.yaml как исполняемая context map — это стратегический DDD и есть. А типизированный API-клиент из контрактов бакенда — способ протащить тот же словарь на фронт: имена типов, полей и ошибок приезжают из UL автоматически. И ваше наблюдение про грепабельность очень в тему: для агента единый язык — это буквально работающий поиск по кодовой базе.

:)

первую часть статьи я пытался донести до тебя еще весной

Что ещё за бакэнд такой

а еще его очень хочется прочитать с ударением на первый слог.

уже и в личку пишут что надо через Э. На хабре везде Э, а еще “Этот вариант зафиксирован в «Русском орфографическом словаре» РАН (Академос) и рекомендован Грамотой.ру”. В статье исправил, в комментариях осталось.

Задачу для AI можно упростить, используя High-Level Building Blocks.

На внутренней разработке и тестировании:
1. Spec-Driven Design and Development;
2. Архитектура на базе Best Practices: репозиторий Best Practices;
3. Набор UI Components вместо Low-Level UI Coding;
4. Spec Drift Monitoring.

Согласен, всё это про одно — сократить агенту пространство решений. Пункты 2 и 3 — то, что в статье названо «дайте машине продолжения паттернов чистый паттерн»: UI-кит для фронта играет ту же роль, что шаблон Command/Handler для бэкенда.

Про SDD одно уточнение: это заход с другой стороны, но на выходе всё равно код, и агент работает всё с той же кодовой базой. Спека снимает вопрос «что делать», но цена реализации по-прежнему определяется архитектурой: если для правки надо удержать в контексте 20 файлов, агент промахнётся и с идеальной спекой. Да и выполнить спеку дословно можно, попутно нарушив слои — она про это молчит.

А вот про Spec Drift Monitoring расскажите подробнее — чем проверяете? Дрейф зависимостей ловится deptrac’ом, но дрейф реализации от спеки в общем виде — задача заметно труднее. Если у вас это оформлено инструментально — интересно, как.

А вот про Spec Drift Monitoring расскажите подробнее — чем проверяете?

Отдельный экзешник лезет прямо в сессии среды разработки (Курсор).
В новой версии тестирую Курсов в дебаг режиме, чтобы можно было контролировать каждое окно, но мониторинг файловой системы более надежный.

Про экзешник не понятно - это какое-то самописное решение? Что он делает? А сам дрейф кто определяет — что сравнивает пойманное изменение со спекой и решает, что разъехалось? LLM со спекой в контексте или что-то детерминированное?

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации