Привет, Хабр! Жизнь не стоит на месте, как и мое исследование, так что пришла пора пересмотреть то, как я оцениваю код.

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

  • Проблема «Чужого кода»: в реальных проектах личный почерк автора размыт правками лидов, автогенерацией и legacy-кодом. Да и кто хранит корпоративный код на GitHub?

  • Отсутствие эталона: сравнивать код банковского API и шейдеров для Unity — это как сравнивать соленое с длинным. Модели нужна точка отсчета.

  • Нейрогенерация и «заброшки»: на GitHub часто лежат либо старые учебные проекты, либо быстрые эксперименты, которые не отражают реальный уровень инженера «здесь и сейчас».

Теперь я предлагаю пойти от большего к меньшему: вместо того чтобы изучать весь «организм» (репозиторий), мы возьмем его крошечный образец.

Честно подсмотренная идея

Я решила адаптировать метод, который используют коллеги на собеседованиях: мы даем респонденту заведомо неверный, но рабочий кусок кода. Там есть всё: нарушение SOLID, раздутое наследование, отсутствие DI и «лапша» из данных. Задача инженера — «полечить» его.

Чем больше «архитектурных правок» сделает человек, тем выше его насмотренность и больше опыт. Но как оценить результат объективно и быстро?

Код – это буквально литературное произведение, поэтому будет не зазорно обратить внимание на лингвистически термины. Для оцифровки качества рефакторинга адаптируем два лингвистических параметра, вычисляемых с помощью модели GraphCodeBERT:

  1. Плотность решений: Отношение количества архитектурных маркеров (интерфейсы, инъекции, паттерны) к общему числу токенов. Такая метрика позволит оценить уровень «зашумленности» реализации.

  2. Семантическая плотность: Концентрация информационной нагрузки в одном блоке кода. Высокий показатель будет свидетельствовать об эффективном использовании архитектурных приемов вместо «воды».

Теоретическая апробация: Зонд против Репозитория

Перейдем к эксперименту: проверим, может ли компактный архитектурный «зонд» объемом всего в 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 (спасибо gemini за иллюстрацию)
Визуальное объяснение расчета показателя K (спасибо gemini за иллюстрацию)

Таким образом мы измеряем «длину пути», пройденного от сломанного кода к "идеалу", выраженного в переменной K. Если K выше единицы — значит, человек предложил решение даже более эффективное, чем выбранный эталон.

Апробация на реальности

Апробировать методику было решено на реальных людях. Респонденты делились своим опытом, грейдом, навыками в теории и правили "сломанный" зонд. Опрос все еще активен, он занимает не больше 10 минут.

Полученные ответы я использовала для расчета TSI (подробнее вот в этой статье) и K-score – то, насколько близко к идеалу респондент поправил код в промежутке от сломанного до идеального.

Логика вычисления результирующего грейда была следующей:

Дерево решений, визуализированное gemini
Дерево решений, визуализированное gemini

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

Сравнение самооценки и высчитанного грейда
Сравнение самооценки и высчитанного грейда
Визуализация близости решений к "идеалу"
Визуализация близости решений к "идеалу"

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

Выводы

Разрабатываемый подход — это не замена собеседованию, но мощный инструмент «доказательного грейдирования». Он более гибкий, чем стандартные системы, и позволяет за считанные минуты получить объективный инженерный паспорт, минимизируя человеческий фактор и предвзятость. И самое вдохновляющее здесь — это результаты K > 1, когда человек находит решение изящнее и эффективнее выбранного эталона.

Буду рада вашим комментариям и предложениям. Чем больше вы делитесь собственным опытом и указываете на "проблемные" места, тем значимее будет итоговый результат?.

Комментарии (10)


  1. vkrasikov
    30.04.2026 01:46

    1. Плотность решений: Отношение количества архитектурных маркеров (интерфейсы, инъекции, паттерны) к общему числу токенов. Такая метрика позволит оценить уровень «зашумленности» реализации.

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


    1. Dozorova_Alyona Автор
      30.04.2026 01:46

      Низкое количество использования маркеров на общий объем кода. Если, например, на весь проект один интерфейс и 15 классов, если грубо. И наоборот


      1. vkrasikov
        30.04.2026 01:46

        Метрика выражается числом же.
        Как вы вычисляете это число? И что оно вам даёт?

        на весь проект один интерфейс и 15 классов

        То есть, кол-во маркеров=16 в вашем случае?
        А сколько токенов? 1600 например. Тогда метрика равна 0,01, я правильно посчитал?
        По итогу, это хорошо или плохо? Какой показатель у вас хороший?


        1. Dozorova_Alyona Автор
          30.04.2026 01:46

          Мы берем за токен любую букво-циферную последовательность, выделенную через регулярку, и делим количество найденных маркеров на общее количество найденных последовательностей.Вы посчитали правильно, если упростить. В примере, который мы обсуждаем 1% - это плохо, так как на 100 токенов у нас есть только один значимыйХороший или плохой показатель стоит выбирать относительно второй метрики - семантической плотности. При высокой плотности решений низкая семантическая плотность - это плохо. Значит, проект перегружен архитектурными решениями, не нужными на практике. И наоборот - при низкой/умеренной плотности решений высокая семантическая нагрузка показывает умелое применение архитектурных навыков


  1. Dozorova_Alyona Автор
    30.04.2026 01:46

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


  1. datasanta
    30.04.2026 01:46

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


    1. Dozorova_Alyona Автор
      30.04.2026 01:46

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


      1. datasanta
        30.04.2026 01:46

        Цель хорошая. В ООП коде такое часто встречается, шаблонный шаблон на 500 строк, что можно переписать в одну функцию на 10 строк.

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

        А если на метрику опираться «бездумно», как вы сказали. То после ее оптимизации будет неизбежно повышаться когнитивная сложность кода и снижаться поддерживаемость


        1. Dozorova_Alyona Автор
          30.04.2026 01:46

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


  1. dedov_aa
    30.04.2026 01:46

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


    1. Dozorova_Alyona Автор
      30.04.2026 01:46

      Это больно, когда лидеры индустрии, пусть и локальные, заявляют, что им выгоднее перекупить синьора и дать ему ИИ, вместо того, что брать джунов и миддлов. Особенно больно, когда они ссылаются вот на ЭТО. То есть мы четыре года будем учить, как работает разработка, как управлять проектом, как должен быть выстроен жц и так далее, а нам в лицо заявляют "а на*** мне тратить время синьора на адаптацию новеньких, если он мне быстро наваяет. И что, что уже были коллапсы из-за ИИ? Бывает. Да, индустрия и предпринимательство в жопе. Но вы можете выстрелить, дерзайте!"

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