Привет, Хабр! Жизнь не стоит на месте, как и мое исследование, так что пришла пора пересмотреть то, как я оцениваю код.
Изначально я опиралась на анализ целых репозиториев — мы вычисляли семантическую плотность и классические метрики кода. Результаты были многообещающими, но на практике я столкнулась с «шумом», который невозможно игнорировать:
Проблема «Чужого кода»: в реальных проектах личный почерк автора размыт правками лидов, автогенерацией и legacy-кодом. Да и кто хранит корпоративный код на GitHub?
Отсутствие эталона: сравнивать код банковского API и шейдеров для Unity — это как сравнивать соленое с длинным. Модели нужна точка отсчета.
Нейрогенерация и «заброшки»: на GitHub часто лежат либо старые учебные проекты, либо быстрые эксперименты, которые не отражают реальный уровень инженера «здесь и сейчас».
Теперь я предлагаю пойти от большего к меньшему: вместо того чтобы изучать весь «организм» (репозиторий), мы возьмем его крошечный образец.
Честно подсмотренная идея
Я решила адаптировать метод, который используют коллеги на собеседованиях: мы даем респонденту заведомо неверный, но рабочий кусок кода. Там есть всё: нарушение SOLID, раздутое наследование, отсутствие DI и «лапша» из данных. Задача инженера — «полечить» его.
Чем больше «архитектурных правок» сделает человек, тем выше его насмотренность и больше опыт. Но как оценить результат объективно и быстро?
Код – это буквально литературное произведение, поэтому будет не зазорно обратить внимание на лингвистически термины. Для оцифровки качества рефакторинга адаптируем два лингвистических параметра, вычисляемых с помощью модели GraphCodeBERT:
Плотность решений: Отношение количества архитектурных маркеров (интерфейсы, инъекции, паттерны) к общему числу токенов. Такая метрика позволит оценить уровень «зашумленности» реализации.
Семантическая плотность: Концентрация информационной нагрузки в одном блоке кода. Высокий показатель будет свидетельствовать об эффективном использовании архитектурных приемов вместо «воды».
Теоретическая апробация: Зонд против Репозитория
Перейдем к эксперименту: проверим, может ли компактный архитектурный «зонд» объемом всего в 30 строк оказаться репрезентативнее целого репозитория. Этот фрагмент — результат моей совместной работы с нейросетью, синтезированный специально для данного эксперимента.
public interface INotifier { string Target { get; } void Send(string msg); } public class EmailNotifier : INotifier { public string Target { get; set; } public void Send(string msg) => Console.WriteLine($"To {Target}: {msg}"); } public class OrderProcessor { private readonly IEnumerable<INotifier> _admins; public OrderProcessor(IEnumerable<INotifier> admins) { _admins = admins; } public void ConfirmOrder(int id) { var validAdmins = _admins.Where(a => !string.IsNullOrWhiteSpace(a.Target)); foreach (var admin in validAdmins) { admin.Send($"Order {id} confirmed"); } } }
Теперь рассчитаем и сравним заявленные выше метрики для 9 репозиториев из выборки в статье о GrafCodeBert и для данного "идеального" кода.
Результаты в таблице говорят сами за себя.
Источник |
Плотность решений (DD, %) |
Семантическая плотность (SL) |
Репозиторий №0 |
1.94 |
0.029 |
Репозиторий №1 |
1.34 |
0.063 |
Репозиторий №2 |
2.85 |
0.040 |
Репозиторий №3 |
6.11 |
0.025 |
Репозиторий №4 |
2.40 |
0.034 |
Репозиторий №5 |
4.81 |
0.031 |
Репозиторий №6 |
3.79 |
0.034 |
Репозиторий №7 |
1.63 |
0.041 |
Репозиторий №8 |
0.74 |
0.034 |
Среднее по репозиториям |
2.84 |
0.037 |
Архитектурный зонд |
1.47 |
0.108 |
В среднем, при высокой плотности решений в репозиториях, видна низкая семантическая плотность, особенно в сравнении с зондом.

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

Таким образом мы измеряем «длину пути», пройденного от сломанного кода к "идеалу", выраженного в переменной K. Если K выше единицы — значит, человек предложил решение даже более эффективное, чем выбранный эталон.
Апробация на реальности
Апробировать методику было решено на реальных людях. Респонденты делились своим опытом, грейдом, навыками в теории и правили "сломанный" зонд. Опрос все еще активен, он занимает не больше 10 минут.
Полученные ответы я использовала для расчета TSI (подробнее вот в этой статье) и K-score – то, насколько близко к идеалу респондент поправил код в промежутке от сломанного до идеального.
Логика вычисления результирующего грейда была следующей:

Результаты и пояснения уже были разосланы тем, кто прошел опрос и захотел их узнать. (Очень надеюсь, что они никого не разочаровали ^_^) А теперь пришла пора посмотреть на общие обезличенные результаты.


Анализ реальных кейсов подтвердил применимость моих идей. Сводные данные подтверждают: даже на малой выборке предложенный семантический зонд позволяет идентифицировать грейд специалиста с точностью, сопоставимой с многочасовыми скринингами.
Выводы
Разрабатываемый подход — это не замена собеседованию, но мощный инструмент «доказательного грейдирования». Он более гибкий, чем стандартные системы, и позволяет за считанные минуты получить объективный инженерный паспорт, минимизируя человеческий фактор и предвзятость. И самое вдохновляющее здесь — это результаты K > 1, когда человек находит решение изящнее и эффективнее выбранного эталона.
Буду рада вашим комментариям и предложениям. Чем больше вы делитесь собственным опытом и указываете на "проблемные" места, тем значимее будет итоговый результат?.
Комментарии (10)

Dozorova_Alyona Автор
30.04.2026 01:46Возможно, в статье не прослеживается, но нельзя оценивать что-то однобоко. Все имеет свой контекст и метрики, которые используются, оцениваются так же в сумме. Навыки разработчиков оцениваются в контексте рыночной важности, код - в контексте его смысла и архитектуры

datasanta
30.04.2026 01:46Высокая «концентрация информационной нагрузки» в статье рассматривается как показатель хорошего качества кода. В линтерах же оценка когнитивной сложности кода cognitive complexity, которую стараются снижать. Также есть показатель поддерживаемости кода maintainability index, который говорит, что чем выше когнитивная сложность, тем код сложнее поддерживать.

Dozorova_Alyona Автор
30.04.2026 01:46Важен контекст использования этой метрики. В данном случае мы пытаемся оценить как человек спроектировал свою систему, насколько грамотно использовал собственные знания. Разрабатываемая методика и выбор подхода "зонд вместо репозиториев" практикой пробует доказать, что маленький кусочек может сказать больше, чем проект в несколько тысяч строк. Это не призыв бездумно повышать сложность, это направление внимания на то, как много может быть воды в проекте и как мало смысла

datasanta
30.04.2026 01:46Цель хорошая. В ООП коде такое часто встречается, шаблонный шаблон на 500 строк, что можно переписать в одну функцию на 10 строк.
Но, имхо, анализ кода должен быть автоматизирован. Если нужно еще думать, где метрику можно применять где нельзя - то это не масштабируемо и полуручной анализ получается.
А если на метрику опираться «бездумно», как вы сказали. То после ее оптимизации будет неизбежно повышаться когнитивная сложность кода и снижаться поддерживаемость

Dozorova_Alyona Автор
30.04.2026 01:46Данный вопрос рассматривался в той или иной мере вот в этой статье. Сейчас цель - разработать методику оценки грейда, которая была бы объективна и оценивала бы человека по тому, что он действительно умеет, а не показывает, что умеет. И то, что описано в этой статье значительно упрощает данный анализ. А вот если оценивать код в целом, то стоит смотреть и на классические метрики, и на смысл. Да и то, это не конечный список

dedov_aa
30.04.2026 01:46В 26 то году, когда нам говорят что мы должны отстать от нейросети и дать ей писать так как она хочет))) на носу переход в нечитаемый байткод удобный и понятный только нейросетям))) имхо все это конечно интересно но не нужно)))

Dozorova_Alyona Автор
30.04.2026 01:46Это больно, когда лидеры индустрии, пусть и локальные, заявляют, что им выгоднее перекупить синьора и дать ему ИИ, вместо того, что брать джунов и миддлов. Особенно больно, когда они ссылаются вот на ЭТО. То есть мы четыре года будем учить, как работает разработка, как управлять проектом, как должен быть выстроен жц и так далее, а нам в лицо заявляют "а на*** мне тратить время синьора на адаптацию новеньких, если он мне быстро наваяет. И что, что уже были коллапсы из-за ИИ? Бывает. Да, индустрия и предпринимательство в жопе. Но вы можете выстрелить, дерзайте!"
Как же жопа от этого горит. Как будто я не понимаю чего-то, говоря об ограничениях контекста, дороговизны обучения ИИ, ее поддержки и работы с галлюцинациями... Как-будто все, что нам рассказывают, ломается о простое долгосрочное планирование...
vkrasikov
Плотность решений: Отношение количества архитектурных маркеров (интерфейсы, инъекции, паттерны) к общему числу токенов. Такая метрика позволит оценить уровень «зашумленности» реализации.
И в каком случае реализация будет считаться зашумленной? Когда показатель высокий или низкий?
Dozorova_Alyona Автор
Низкое количество использования маркеров на общий объем кода. Если, например, на весь проект один интерфейс и 15 классов, если грубо. И наоборот
vkrasikov
Метрика выражается числом же.
Как вы вычисляете это число? И что оно вам даёт?
То есть, кол-во маркеров=16 в вашем случае?
А сколько токенов? 1600 например. Тогда метрика равна 0,01, я правильно посчитал?
По итогу, это хорошо или плохо? Какой показатель у вас хороший?
Dozorova_Alyona Автор
Мы берем за токен любую букво-циферную последовательность, выделенную через регулярку, и делим количество найденных маркеров на общее количество найденных последовательностей.Вы посчитали правильно, если упростить. В примере, который мы обсуждаем 1% - это плохо, так как на 100 токенов у нас есть только один значимыйХороший или плохой показатель стоит выбирать относительно второй метрики - семантической плотности. При высокой плотности решений низкая семантическая плотность - это плохо. Значит, проект перегружен архитектурными решениями, не нужными на практике. И наоборот - при низкой/умеренной плотности решений высокая семантическая нагрузка показывает умелое применение архитектурных навыков