Pull to refresh

Comments 15

Интересная математика!
Подскажи, Java планируется добавить в strictacode?

Если быть до конца честным, то я сам последний раз писал на java лет 15 назад и сейчас мы уже давно не используем его на проектах, kotlin встречается, а вот java нет. А добавлять язык для галочки, не понимая как это в реальной жизни работает просто нет ни времени, ни сил. Но если вы поможете проекту и добавите поддержку java, то мы не будем противиться pull request-у ;)

Разумный подход, лучше поддерживать один язык, но глубоко, чем написать парсеры для десяти языков, которые будут выдавать погоду на Марсе

уже утащил.
Модель сама разберется что ей нужно.
https://github.com/GFN-CIS/global-rules/blob/main/code-health-check.md#step-2--tooling-discovery-do-not-use-a-hardcoded-list

На тестах отлично всё находит. Учитывая что катофф у моделей обычно 12 месяцев назад - то даже искать в инете ничего не нужно. Все популярные тулзы уже есть.

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

На 100% сказать сложно, но ИИ-ку обычно тянет RP перекос, большинство проектов которые мне доводилось видеть, которые написаны нейронкой, даже если используется какой-нибудь speckit или superpowers, то там обычно этот симптом вылезает. Попробуйте последить за этим показателем, возможно получится если не на 100% задетектить, но хотя бы заподозрить.

А если быть до конца честным, то в целом какая разница пишут нейронками или нет, если проект здоров =)

По одному коммиту ничего не поймешь. Вайбкодинг убивает архитектуру постепенно, когда добавляется сотый костыль сбоку.

Проще настроить хуки в гите, которые будут блокировать коммиты с резким скачком цикломатической сложности, это остановит генерацию лапшекода на корню

Скажите пожалуйста, если проект на TypeScript, есть ли смысл на него strictacode натравливать?

У нас есть фронт на js который полностью навайбкожен и мы работам по алгоритму — сделали несколько фич, запускаем скилл strictacode и делаем план улучшений. И пока ребятам такой подход очень нравится, говорят, что он предлагает достаточно хорошие планы и результат нравится. Возможно вам тоже поможет, попробуйте, будет интересно получить обратную связь ;)

Не ну было такое. Что код давит. Ну там 10 лет назад, когда первый хеллоу ворлд писал. Потом когда дочитал нужное количество книг - стало пофигу кто и как код писал. Научился читать его и выполнять в своей голове без отладчика. Были сомнения если - включал отладчик. Потом навык чтения развился на столько, что любой код - понятный. Даже если в нём есть классы хелперы и переменные названы х1, х2. Всегда есть опция - читать код двумя полушариями - как человек и как машина.

Потом да, надоело что все пишут "плохо" - стандарты начал внедрять. Сначала парочку, потом ещё, потом ещё. Но действительно - для ускорения внедрения фич. Чтобы ревью проводить быстрее, изменения контроллировать лучше. Порог входа в проект конечно выростал, но окупалось такое деяние примерно сразу. Хоп и новая фича залетает за день, потому что она копия вон той, для который есть шаблон.

Шаблоны - да. Паттерны проектирования. Страшные монстры абстракции, когда лень вникать в них. Но стоит потратить день другой - и получаешь ускорение, контроль. А главное код, который менять легко. А код он такой да - для него в первый день всё оверинжениринг и лишние детали. А через неделю - блин, вот если бы начал с шаблона Х, не хныкал бы сейчас, что рефакторишь уже два дня, а фичи новой ещё нет.

Фреймворки - отдельное людям за них спасибо. Вот где был настоящий борщ из всего. Если в руках фреймворк - то весь мир это гвоздь. И вместо создания новых концепций - ну напихивали в коробку кучу всего. Как майкрософт офис - на планете нет человека, который знает всё что там есть на 100%. Но при первом приближении - продукт хороший, и даже понятный. Как и хороший фреймворк - не требует от тебя знать все его 100% деталий и слепо следовать всем им. В итоге ещё одним стандартом команды становится - мы используем для задачи такой то - фреймворк такой то.

Итого, и до мира нейронок были все описанные проблемы в статье. Решали из просто стандартами в рамках команды. Чтобы всем было понятно, зачем мы делаем фичу х так, а не вот так. Просто убираешь вариативность реализации у задач - и всё едет с бустом х1000%.

Финальный стандарт - чистая архитектура. Штука уже древняя, но надёжная как Швейцарские часы. Есть порог входа, но после его преодоления - вечный покой. Твой код теперь масштабируется до бесконечности без головной боли. В один репозиторий можно засунуть не один микросервис и даже не 10, а скажем м×н проектов и систем - настоящая революция. Изменения влетают в изолированные друг от друга участки, влетают быстро, тестируются изолированно и без боли. Микросервисов собирай сколько хочешь и как хочешь. У нас конечно свой вариант Роберта Мартина - потому что совсем классике слепо следовать - как минимум скучно. Но самое полезное забрать - забрали.

Ну и вот пришёл ИИ. Что он поменял? Да ничего. Мы просто его в стандарты вогнали - и он вайбкодит по нашему. Всё что он пишет - понятно, масштабируется, легко меняется. Потому что его спеки и правила по рукам бьют. Да, это ИИ и он не следует всему, что ему сказали и бывает борщит. Ну просто носом его тык в борщ - и он не спервого, так со второго раза нормально сделает.

По итогу - ИИ это множитель того, что у Вас есть. А если для вас всё ещё не знаю - фабрика функций - оверсложность - ну вот и получите умножение - весь код будет с глубиной 1. И супер простой. Потом кароче через 3 дня оно пойдёт его менять и скажет извините, но 1 млн токенов не хватает вместить весь контекст зависимостей, чтобы внести фичу х. Откуда зависимимости ? Ну везде же глубина 1, значит кругом горы импортов. Но я же не так хотел - и тут ИИ сама говорит - а может паттерн проектирования?

Спасибо, что не поленились и написали такой развернутый коммент! Когда пишешь первую статью, то вообще не ожидаешь, что кто-то потратит силы и напишет подробный комментарий, да еще и с которым не поспоришь.

Я полностью согласен, что если у тебя опыта вагон и за ним еще целый состав, то в целом проблем нет, сиди себе и пинай агента в спеки пока контекстное окно не закончится. Но я столкнулся с проблемой когда у людей не такая мощная инженерная база, команды в биг техах, как правило, разнородны, многие вообще отрицают новые подходы, да и с точки зрения опыта последнего года у меня были случаи когда пускали людей с агентами в репозиторий в котором идет очень интенсивная разработка и они буквально уничтожали репос агентами за пару месяцев и приходилось полностью откатываться и все переписывать и там было такое состояние проекта, что и strictacode бы не помог уже, а были случаи когда все достаточно гладко шло, потому, что репозиторий небольшой, работает в нем полтора человека и в целом следят за тем, что там агент делает. Но меня сейчас больше занимает вопрос того, как стабилизировать качество и получить контроль за деградацией с учетом того, что в биг техах очень интенсивная разработка, разнородные команды, многим разработчкам очень сложно читать спеки и выхлоп от агента, когда они привыкли уже мыслить трассировкой и держать в голове графовидную структуру взаимодействий, а им тут спеки подсунули, люди ломаются и либо забивают на то, что агент пишет и просто соглашаются и либо идут опять руками писать, и хорошо если второе, а вот если первое, то тут уже метрики могут помочь.

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

Все так, поэтому больше хочется quality gates, а не стандарты, но не бессмысленно трешхолды ставить которые душат, а более осмысленно это делать не мешая работе. Сейчас у нас достаточно прикольно получается, трешхолды в CI по рукам ударили в ветке, в агенте скилл запустил, план улучшений посмотрел, сделал небольшой рефкторинг сразу им же, не дал деградации усилиться. Вроде и не сложно, тк метрика по рукам ударила, но есть инструмент который сразу и поправить поможет, но и полезно, не дает на дно упасть. Хочется конечно дальше пойти, это не идеал, скорее просто старт, посмотрим куда приведет.

Код давит не когда в нем много условий. Он давит когда абстракции текут, а документация устарела еще два года назад при переходе на микросервисы

Отличная статья! Спасибо, многое утащу себе сюда https://github.com/GFN-CIS/global-rules/blob/main/code.md.

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

Насчет написания тулчейна правда не уверен, что это так уж нужно.
Я скормил агенту статью (до точки, где упоминались репы, чтоб он не пошел тупо в них и не скопировал).
дал такой промпт :

у тебя есть lsp pyright, у тебя есть ast-grep, и есть ccc. так же у тебя есть python, ты можешь использовать pandas или какую-то другую библиотеку для работы с кодом как с кодом/смысловыми блоками а не просто как с текстом. теперь проведи мне анализ качества и поддерживаемости кода и архитектуры с использованием этих и других подобных метрик и использованием этих и других инструментов, которые есть в наличии. сделай анализ этого компонента https://github.com/garuda-tunnel/router/tree/main/kube/image/ipt-server

Получил такое заключение.

ipt_server (Python) — анализ качества кода и архитектуры

  1. Какие инструменты реально использовал агент Честный список (по содержимому сохранённого скрипта docs/artifacts/ipt_server_analyze.py + bash-запуски):

Инструмент Зачем Python ast (stdlib) Парсинг исходников, обход ClassDef, Import, ImportFrom, разрешение относительных импортов, оценка MRO-глубины классов radon (cc_visit, mi_visit, raw.analyze) Цикломатическая сложность по функциям, Maintainability Index по файлам, SLOC (строки кода без пустых/комментариев) networkx Граф зависимостей модулей: in_degree/out_degree (fan_in/fan_out), betweenness_centrality, simple_cycles (детект циклов импортов), edge density pandas Агрегации, сортировки top-N, экспорт в CSV pyright Запущен отдельно через bash для статической типизации (244 диагностики, отфильтровано до 58 в production-коде) pathlib.rglob + ручные exclude-фильтры Поиск .py-файлов в дереве Не использовал (из того, что я ему предлагал):

ccc (cocoindex-индекс) — обошёлся без семантического поиска, файлы нашёл через rglob ast-grep — не понадобился, для количественных метрик хватило stdlib ast Это разумно: для quantitative analysis ast+radon+networkx достаточны и точнее (структурный обход), а ccc/ast-grep сильнее в смысловом поиске и поиске паттернов — нам это было не нужно.

  1. Объём анализа Корень: kube/image/ipt-server/ 32 файла, 3 203 SLOC, 821 единиц CC, 34 класса в 14 модулях Исключены: tests/, powerdns_test/, dev/, scripts/, helm-чарт-дубликаты, worktree-зеркало

  2. Методика (зафиксированные допущения) scale = min(1, sloc/5000) = 0.6406 k = 0.5 (штраф за дисбаланс) Граф зависимостей — на уровне модулей; per-class fan_in/fan_out наследуют значения своего модуля (это огрубление — см. §9) depth — статический обход MRO, внешний базовый класс считается за +1 Нормализация min-max по проекту; coupling — edge-density графа с потолком 0.30

  3. Итоговые цифры Метрика Значение Из чего складывается RP 40.14 Peak=48.24, Base=27.99, max_cc=24, p90_cc=7.7, density=25.63 OP 31.16 coupling_density=0.0494, avg_class_score=40.95 Score 75.79 штраф = 4.49 Вердикт умеренный перекос в RP, OP слегка повышен давление сконцентрировано в 3 файлах, один структурный «pivot» (Config) Не катастрофа на таком размере, но заметно выше уровня «чисто» (<25). Главное — длинный хвост: max_cc=24 против p90=7.7, то есть проблема не размазана, а сидит в горстке толстых функций.

  4. Худшие места Топ файлов по сложности Файл SLOC total CC max CC density MI Config.py 366 134 14 36.6 30.9 Router.py 471 127 20 27.0 25.9 (единственный «B» по MI) tasks/nexthop_monitor.py 343 100 24 29.2 35.1 nftables/nftables.py 274 74 8 27.0 45.7 ipt_server/main.py 366 64 8 17.5 46.2 Топ функций по CC Файл Функция CC tasks/nexthop_monitor.py tick (строка 252) 24 tasks/nexthopmonitor.py resolvedirect_router_nexthop (154) 23 tasks/interface_monitor.py monitor_interfaces (83) 21 Router.py Router.on_a_record (483) 20 Router.py Router.add_route (153) 18 tasks/nexthop_monitor.py findrouter_owning_address (55) 17 Config.py MySettings.parse_routes (435) 14 Router.py Router._cleanup_expired_routes (28) 14 11 из 15 худших функций — в трёх файлах: Router.py, tasks/nexthop_monitor.py, tasks/interface_monitor.py.

Топ классов по class_score Структурный pivot — Config.py: 14 Pydantic-моделей, цепочка наследования глубины 3 (BaseRoute → NetRoute/DomainRoute/CountryRoute), модуль импортируется 5 другими (fan_in=5). Класс-оценки 68–80. Дальше идут хабы по fan_out: Router.Router (52, fan_out=8) и PdnsRuntimeConfig (56, fanout=9).

  1. Граф зависимостей 32 узла, 49 рёбер, плотность 0.0494 (разрежённый) 2 кластера циклов: Router ↔ Config ↔ route ↔ ipt_server.state (4 проекции одного четырёхугольника) rule_resolvers ↔ Config (обратная связь через Pydantic-валидатор)

  2. Pyright (только production) 58 ошибок, 2 предупреждения в 9 файлах 67% — reportOptionalMemberAccess (разыменование Optional без None-check) 6× reportMissingImports — симптом sys.path-хака в ipt_server/main.py:38-40 Худшие: ipt_server/main.py (36 диагностик), Config.py (7), tasks/interface_monitor.py (7)

  3. Диагноз — три источника давления Router.py — MI 25.9, один класс с fan_out=8, сидит в импорт-цикле. Самый крупный одиночный драйвер RP. tasks/nexthop_monitor.py — два гигантских async-хэндлера (CC 24 и 23), которые внутри одного тела делают и классификацию, и сравнение, и сайд-эффекты. Пин-фактор max_cc. Config.py + legacy-модули верхнего уровня — pivot для OP. 14 моделей в одном файле с fan_in=5; весь кластер (Router.py, route.py, rule_resolvers.py, …) живёт вне пакета ipt_server/ и подгружается через рантайм-хак sys.path.

  4. Что починить в первую очередь (3 вещи с максимальным leverage) Разобрать жирные async-хэндлеры: nexthop_monitor.py::_tick (CC 24), resolvedirect_router_nexthop (CC 23), interface_monitor.py::monitor_interfaces (CC 21), Router.on_a_record (CC 20) → на pure-функции без сайд-эффектов. Снижает max_cc до ≤17, Peak падает на ~10 пунктов → RP ≈ 33. Разбить Config.py на подпакет config/: base.py, routes.py, rules.py, route_health.py, settings.py. Партиционирует унаследованный fan_in=5, снижает avg_class_score. Переложить legacy-модули в пакет ipt_server/ и убрать PACKAGEROOT.append(…) в main.py:38-40. Ломает цикловой кластер, чинит все 6 reportMissingImports, разблокирует Optional-narrowing для большинства из 37 pyright-ошибок. Ожидаемый Score после всех трёх: ≈ 50 (RP ≈ 30, OP ≈ 22)

Sign up to leave a comment.

Articles