Привет, Хабр! Меня зовут Александр Петрушин, я старший разработчик в VK Tech, и сегодня хочу рассказать о нашем опыте создания технического радара.

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

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

Если вы хотите привести технологии в компании к порядку и при этом не утонуть в бюрократии, этот текст для вас.

Зачем нужен технический радар

Чем больше команда или компания, тем выше риск фрагментации: разные подразделения могут использовать разные фреймворки, библиотеки или подходы к разработке. Это приводит к дублированию усилий, конфликтам при интеграции и затратным миграциям в будущем.

Представим ситуацию. В компании работает фронтенд-разработчик Ваня. Ему поручают запустить новый внутренний проект. Ваня вдохновлен последними трендами и решает использовать Solid.js — современный фреймворк, о котором говорят в блогах. Но есть нюанс: вся остальная компания давно использует React. Спустя полгода проект растет, его нужно поддерживать и дорабатывать, но теперь никто, кроме Вани, не может в нем эффективно работать. Команде приходится либо переучиваться, либо переписывать всё заново. Такие ситуации стоят дорого — и не только в деньгах.

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

  • понимать, что, где и как используется;

  • видеть, какие решения признаны стандартными, а какие требуют осторожности;

  • избегать технологического разнобоя и спонтанного выбора стека;

  • снижать издержки на поддержку и рефакторинг;

  • ускорять Time-To-Market (время вывода решений в продакшен) за счет готовых проверенных подходов;

  • повышать прозрачность технической стратегии внутри команды.

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

Немного истории: путь длиной в полвека

Уже в 60–80-х годах крупные компании начали осознавать необходимость управлять технологическим стеком. Так, IBM, Microsoft и другие ИТ-гиганты создавали внутренние каталоги одобренных технологий — списки, которые рекомендовались к использованию. Часто этим занимались архитектурные комитеты, которые контролировали внедрение новых решений, чтобы избежать излишней фрагментации.

В 1990–2000-х годах появились Technology Roadmaps — дорожные карты развития технологий, которые отражали эволюцию платформ, языков, инфраструктурных подходов. Компании вроде Gartner и Forrester стали публиковать аналитические квадранты, например Gartner Magic Quadrant — визуализации зрелости и рыночной позиции технологий. Это был первый шаг к систематизации решений, но скорее на уровне бизнеса, чем на уровне команд.

Gartner Magic Quadrant

Technology Roadmaps

Настоящий сдвиг произошел в 2010 году, когда ThoughtWorks выпустила первый публичный Technology Radar — круговую диаграмму с четырьмя секторами (техники, инструменты, языки, платформы) и четырьмя уровнями зрелости (Adopt, Trial, Assess, Hold). Этот формат стал де-факто стандартом. Он был понятен, нагляден и адаптируем под разные масштабы.

Технический радар от ThoughtWorks

Почему именно в 2010-е? Agile и DevOps стали мейнстримом, а значит, нужны были динамичные инструменты принятия технических решений.

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

С 2015 по 2020 год практика техрадаров распространилась по индустрии. Такие компании, как Spotify, Amazon, Google, начали внедрять свои внутренние версии Tech Radar — часто с собственными категориями, источниками данных и автоматизацией.

В наши же дни происходит улучшение техрадаров в основном за счет автоматизации сбора данных для них с использованием API GitHub, GitLab, NPM и других платформ. И сегодня это уже не просто диаграмма, а динамический инструмент управления технологическим ландшафтом компании.

Кроме того, с появлением ИИ стало еще больше возможностей автоматизации. Когда мы начали делать свой Tech Radar в VK Tech, мы не нашли примеров применения GPT или LLM в этой области. Вполне возможно, что мы стали одними из первых, кто начал интеграцию ИИ в техрадар — об этом подробнее расскажем ниже.

Контекст VK Tech: почему это стало актуально именно для нас

В VK Tech работает множество инженерных команд, каждая из которых решает разные задачи: от клиентских и веб-приложений до облачных решений, инфраструктуры и backend-сервисов. С ростом количества проектов и команд увеличивается и технологическое разнообразие.

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

У разных команд могут быть:

  • разные линтинг-правила и подходы к форматированию;

  • разные UI-библиотеки — от React Bootstrap до Chakra UI или собственного решения;

  • разные фреймворки и подходы к архитектуре;

  • даже разные базы данных и способы миграций.

Всё это приводит к тому, что:

  • возникают дублирующие решения (одна и та же задача решается пятью разными способами);

  • новички и переходящие между проектами разработчики сталкиваются с резким порогом вхождения;

  • сложно масштабировать best practices и архитектурные подходы;

  • каждая команда отстаивает «свое», и найти общий язык становится все труднее.

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

Как устроен технический радар: сектора и кольца

Технический радар — это круговая диаграмма, в которой отражены текущие и перспективные технологии, используемые в компании. Она делится на сектора (категории технологий) и кольца (уровень зрелости и рекомендации по использованию). Точка используемой технологии располагается в определенном секторе и кольце. Чем ближе к центру — тем больше использований.

Основные сектора

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

  • Languages & Frameworks (Языки и фреймворки). Языки программирования, фреймворки, большие библиотеки. Примеры: TypeScript, React, Angular, Cypress.

  • Tools (Инструменты). Devtools, библиотеки, системы логирования и мониторинга. Примеры: ESLint, Lodash, Grafana, Moment.js.

  • Platforms (Платформы). Сборщики, контейнеризация, инфраструктура и среды запуска. Примеры: Webpack, Docker, Kubernetes, NGINX.

  • Techniques (Подходы и практики). Архитектурные и инженерные практики. Примеры: CI/CD, Event-Driven Architecture, DevSecOps, Trunk-Based Development.

Кольца: уровень зрелости

Кольца показывают, насколько технология готова к использованию в масштабах организации:

  • Adopt (Рекомендуем к использованию). Надежные и проверенные временем технологии, активно применяемые в продакшене.

  • Trial (Пробуем в бою). Технологии, показавшие потенциал, но пока используемые ограниченно.

  • Assess (Изучаем). Новые или нишевые решения, которые только оцениваются.

  • Hold (Не рекомендуем). Устаревшие, проблемные или неподходящие для нашей архитектуры технологии.

Как мы проектировали наш технический радар

Проектируя технический радар в VK Tech, мы поставили перед собой две ключевые задачи:

  • разработать удобный UI для отображения технологий;

  • автоматизировать формирование точек радара, чтобы не собирать информацию вручную каждый раз по командам.

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

В этой статье мы будем показывать реализацию технического радара на примере фронтенд-проектов, где в репозиториях есть package.json. Это самый наглядный и распространенный случай, позволяющий автоматизировать сбор информации. Однако сама методика универсальна и может быть адаптирована для других стеков — бэкенда, мобильной разработки, инфраструктуры и т. д.

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

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

Для поддержки иннерсорса в VK Tech есть внутренний портал с UI, где отображаются все доступные библиотеки. Проекты добавляются в этот портал автоматически: достаточно положить специальный JSON-файл в корень репозитория, после чего краулер собирает и индексирует информацию.

Вводной информацией вооружились и теперь приступим к интересному.

Сбор проектов и зависимостей

Первый шаг — получить все проекты в GitLab, принадлежащие группам VK Tech. Делаем это при помощи API и фильтруем их по активности: активными считаем те, в которых были коммиты за последние 6 месяцев.

Затем парсим package.json каждого проекта, чтобы извлечь все зависимости. Точно так же обрабатываются и innersource-пакеты. На этом этапе мы получаем зависимости из opensource и innersource в структурированном виде, где каждой зависимости присваивается список проектов, которые используют ее.

{
  "mobx": [
    'path / to / gitlab / repo',
    'path / to / gitlab / repo 2',
    'path / to / gitlab / repo 3',
  ],
  "Moment.js": [
    'path / to / gitlab / repo 4',
  ],
  "typescript": [
    'path / to / gitlab / repo 2',
    'path / to / gitlab / repo 4',
  ]
}

Также дополнительно по зависимостям мы можем определить, например, подходы и техники к разработке. Условно, если проект использует module-federation, то можно предположить, что используются микрофронтенды.

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

{
  "language": "javascript",
  "combineDepsSubstrings": {
    "typescript-eslint": "@typescript-eslint/",
  },
  "depsSubstringExcludes": [
    "@types/",
  ],
  "ringsDistributionType": "constants",
  "ringsDistribution": {
    "hold": 0,
    "assess": 10,
    "trial": 20,
    "adopt": 30
  },
  "minProjectsThreshold": 3,
  "maxDepsInSection": 30,
  "extends": [
    { "name": "@module-federation", "technology": "Microfrontends", "category": "techniques" },
    { "name": "mobx", "technology": "State Management", "category": "techniques" }
  ]
}

Из того, что мы используем на данном этапе:

  • CombineDepsSubstrings — объединение всех зависимостей по подстроке. Например, нам в техническом радаре нужно знать, что используется typescript-eslint, но нет необходимости в знании о каждом дополнительном пакете.

  • DepsSubstringExcludes — это поле для исключения определенных зависимостей по подстроке. Например, нам не нужны пакеты с типами.

  • Extends — расширения для добавления точек на технический радар по определенным зависимостям.

Стоит также упомянуть, что мы можем искать определенные файлы в проекте и, исходя из этого, добавлять новые точки. Например, если нашли Dockerfile, то добавляем Docker как используемую технологию для этого проекта. Такую логику мы зашили в код, но это вполне также можно вынести в конфиг стека.

Популярность и фильтрация зависимостей

После парсинга мы переходим к оценке популярности зависимостей:

Внутренняя популярность: сколько проектов внутри VK Tech используют конкретную технологию. Тут используем поле minProjectsThreshold из конфига выше, чтоб отсечь совсем непопулярные зависимости.

Внешняя популярность: насколько широко она используется в мире (для JS — по данным из npm).

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

Innersource-зависимости при этом оцениваются только по внутреннему переиспользованию.

Мы формируем Top-N популярных зависимостей и сохраняем остальные в резерв — на случай если потребуется пополнить секции.

Классификация: подключаем LLM

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

Решением этого вопроса было подключение и использование модели LLaMA3 от нашего внутреннего проекта VK Copilot. Мы отправляем в модель зависимости и указываем, какие категории нам нужны: фреймворки, платформы, инструменты, техники и т. д. В ответ получаем пары «категория — зависимость», которые сохраняем в JSON. Как всегда в работе с LLM, нам нужно было сформировать правильный prompt. Тот, что на скриншоте ниже, в общем-то, справлялся хорошо и устроил нас.

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

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

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

Генерация точек на радаре

Последний шаг — формирование точек. В нашем случае можно применить полярные координаты. Таким образом, каждую точку на радаре можно описать радиусом и углом:

  • Угол θ зависит от сектора, в который должна попасть зависимость. Например, Tools — первый квадрант (от 0 до π/2).

  • Радиус r зависит от кольца (Adopt, Trial, Assess, Hold) и генерируется в заданных границах. По сути, указывая радиус, мы определяем расстояние от центра, и у него могут быть ограничения по нижней и верхней грани.

Угол и радиус точки определяется рандомно внутри границ и далее нормализуются относительно других точек. Чтобы точки не слипались и не попадали на границы между секторами и кольцами, мы используем смещение (λ). Исходя из этого:

где:

  • αmin  — минимальное значение радиуса для кольца;

  • αmax — максимальное значение радиуса для кольца;

  • λ — смещение точек от края.

Дополнительно каждой точке к значению диаметра плюсуем определенное число k, в нашем случае k=10. Этот показатель нужен для нормализации расположения точек. Например, если какая-либо точка попала на координаты, часть которых занимает другая точка (т. е. имеем пересечение координат в рамках одной секции), то эта точка должна репозиционироваться. Для такой задачи используется случайное отклонение:

В данных формулах δθ и δr — какое-то случайное сгенерированное число от θ и r соответственно. Число k применяется только для вычисления пересечения и в дальнейших расчетах не участвует.

Ниже можно увидеть изображение, где наглядно продемонстрирован выбор угла и радиуса для точки:

На этом этапе все точки расставлены на радаре. Но расставлены в полярных координатах, с которыми, само собой, в UI будет не очень удобно работать. Мы можем сделать удобнее и перевести в декартову систему координат (x и y):

Как мы определяем, в какое кольцо попадет технология

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

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

  • Проценты — какой процент от максимального числа будет относиться к тому или иному кольцу.

  • Константы — жесткие числовые границы.

Для данной задачи используются поля ringsDistribution и ringsDistributionType из конфига, который был выше.

В случае с фронтенд-проектами VK Tech нам подошел последний вариант, так как проектов слишком много. При этом, например, для Golang лучше показали себя проценты.

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

Что на выходе

На выходе скрипт генерирует структурированный JSON, в котором каждая точка описана:

  • названием зависимости;

  • категорией;

  • кольцом;

  • декартовыми координатами;

  • описанием;

  • датами, когда добавлена или изменена зависимость.

{
  "name": "MobX",
  "quadrant": 3,
  "category": "languagesAndFrameworks",
  "isNew": false,
  "createdAt": "2025-05-24T13:48:17.538Z",
  "updatedAt": "2025-05-24T13:48:17.538Z",
  "history": [
    {
      "usageCount": 59,
      "x": -62.10334901141126,
      "y": -34.663529713889154,
      "ring": "adopt",
      "group": "outer",
      "date": "2025-05-24T13:48:17.538Z",
      "teams": [
          "VK Cloud",
          "taxmonitor",
          "mail",
          "mail-core",
          "VK WorkSpace"
     ],
     "projects": [
         "path / to / repo",
         "path / to / repo 2",
     ]
   }
  ],
  "description": {
    "en": "State management library using reactive programming to manage app state.",
    "ru": "Библиотека управления состоянием, использующая реактивное программирование для управления состоянием приложения."
  }
}

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

Почему не отдали всё на откуп UI

Может возникнуть вопрос: зачем вся эта математика? Почему бы просто не построить радар прямо в UI, используя, например, D3?

Ответ — в детерминизме. Мы хотели, чтобы каждая зависимость всегда находилась на одном и том же месте. Это делает радар стабильным: пользователю проще ориентироваться, а точку — легче найти. Именно поэтому координаты генерируются заранее и передаются в UI уже готовыми.

Обновление данных радара

Обновление данных радара организуется тем же скриптом, который и создавал его. Перезапускаясь, он получает на вход уже существующий JSON и продолжает работать с ним, наполняя историю (поле history).

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

Что получилось: наш результат на сегодня

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

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

Ситуации, в которых он незаменим:

  • Быстрый онбординг новых разработчиков. Новички легко ориентируются в технологическом стеке компании. Посмотрев на радар, они сразу видят, что, например, TypeScript и Kubernetes — стандарт, а Rust еще в фазе экспериментов. Причем они могут отфильтровывать данные только по своей команде, чтоб быстро и просто понять, что используется во всех проектах этой команды.

  • Поддержка архитектурных решений. Архитекторы используют радар для оценки зрелости технологий. Например, при обсуждении внедрения GraphQL они могут увидеть, что он находится в зоне Trial — это значит, что технология уже применяется, но требует осторожности и доработок.

  • Управление техническим долгом. Если компания планирует отказаться от устаревших технологий, например AngularJS, их можно поместить в зону Hold. Это сигнал всем командам: не использовать эту технологию в новых проектах и постепенно мигрировать с нее.

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

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

Заключение: что нам дал техрадар и зачем он другим

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

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

Наша реализация радара еще не завершена — мы продолжаем развивать его:

  • автоматизируем классификацию новых технологий с помощью LLM;

  • делаем пользовательский интерфейс удобнее;

  • расширяем охват за пределы фронтенда.

Мы верим, что радар — это не статичная доска, а живой инструмент, который должен эволюционировать вместе с компанией. И чем раньше команды начинают думать в категориях Adopt, Trial, Assess и Hold, тем быстрее они переходят от хаоса к зрелой технической культуре.

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