Слепые зоны DevRel: как превратить выступления спикеров в метрики

Обычно DevRel меряет себя количеством выступлений: «в этом квартале у нас 40 докладов, в прошлом было 28, растём». Цифра красивая, но почти ничего не говорит о людях, которые за ней стоят. Когда мы проектировали внутренний инструмент для учёта спикеров, то пришли к другой главной метрике. Важно не «сколько выступлений», а «о ком из спикеров я ничего не знаю».В статье расскажу, из чего мы собрали оценку спикера, почему оценку спикера нужно хранить историей, а не одним числом, как устроен рейтинг команды и почему отдельный блок «Слепые зоны» оказался полезнее любого рейтинга. Покажу модель данных, правила и код на Java, а также грабли, на которые мы наступили.Статья будет полезна DevRel-специалистам, руководителям спикерских программ и разработчикам внутренних аналитических дашбордов, особенно тем, кто считает людей по агрегатам и хочет понимать, насколько этим агрегатам можно верить.

Предыстория: спикер выступил, DevRel узнал через месяц

Знакомая картина. Инженер съездил на региональный митап, рассказал про миграцию на новый стек, собрал хорошие отзывы. DevRel узнаёт об этом через месяц: из поста в чате, из чужого анонса или вообще случайно. Отзывы к тому времени потерялись, слайды лежат у спикера на ноутбуке, а в табличке учёта докладов новая строка так и не появилась.Пока спикеров десять, это не страшно: всех знаешь лично, держишь в голове, кто где выступал и как прошло. Когда их становится пятьдесят, сто, несколько сотен в разных городах и командах, оценивать людей на глаз уже не получается. Остаются ощущения: «кажется, Андрей хорошо выступает», «Марина вроде давно никуда не ездила». Решения о том, кого отправить на большую конференцию и в кого вложить время на подготовку, принимаются по этим ощущениям.

Как это сейчас: три вопроса без ответа

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

1. Кто из спикеров растёт? Не кто сейчас лучший, а у кого есть динамика: стал выступать чаще, вышел на новый уровень площадок, получает отзывы лучше прежних.

2. Кого везти на топ-конференцию? Слотов на федеральных и международных конференциях мало, а подготовка дорогая. Ошибиться с кандидатом обидно и спикеру, и компании.

3. Кого я давно не оценивал? Самый неудобный вопрос. Человек мог за полгода вырасти или выгореть, а в голове у DevRel остался его образ годичной давности.Первые два вопроса про рейтинг. Третий про то, насколько этому рейтингу можно верить. С этого и начнём.

Из чего складывается оценка спикера

Первое решение, которое многое упростило: единица учёта — доклад, а не спикер. Спикер в нашей модели — это агрегат над своими докладами. У доклада есть дата, тема, тип площадки (митап, воркшоп, конференция и так далее), а позже к нему подтягиваются отзывы слушателей и оценка выступления. Всё остальное вычисляется из этих фактов: сколько выступлений, как часто, на каком уровне, о чём.Почему так, а не «карточка спикера с полями»? Потому что поля в карточке устаревают молча. Если DevRel однажды поставил спикеру «федеральный уровень», это значение будет висеть годами. Агрегат над докладами пересчитывается сам: нет новых докладов, значит активность падает, и это сразу видно.Оценка спикера — композит из четырёх групп сигналов:

  • Активность — сколько человек выступает, как часто, растёт ли частота и сколько у него тем. Считается как агрегат над докладами.
  • Оценка спикера — балл от 1 до 10 и то, как он меняется со временем. Её ставит DevRel вручную или система вычисляет по отзывам слушателей. Берётся из истории оценок.
  • Уровень влияния — на каких площадках человек выступает: внутренних, региональных, федеральных или международных. Складывается из микса докладов по типам площадок и текущего уровня спикера.
  • Полнота профиля — насколько мы вообще знаем человека: био, темы, контакты, материалы. Это процент заполнения профиля.

Дальше разберём каждую группу.

Активность: сколько и какого уровня

Активность — самая очевидная часть, но и в ней есть тонкости. В карточке спикера мы показываем:

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

Рост активности считается просто: временной ряд за период делим пополам и сравниваем вторую половину с первой. Если в первой половине выступлений не было, а во второй появились, это +100%, а не деление на ноль:

private int computeActivityGrowth(TrendSeries series) { List<Integer> talks = series.talks(); // число докладов по корзинам периода if (talks.size() < 2) { return 0; // сравнивать не с чем } int midpoint = Math.max(1, talks.size() / 2); int previous = talks.subList(0, midpoint).stream().mapToInt(Integer::intValue).sum(); int current = talks.subList(midpoint, talks.size()).stream().mapToInt(Integer::intValue).sum(); if (previous == 0) { // первые выступления после затишья — считаем как +100%, а не делим на ноль return current == 0 ? 0 : 100; } return Math.round((current - previous) / (previous / 100f)); // рост в процентах }

Уникальные темы — тоже простой подсчёт: нормализуем строку темы (trim, lower case), отбрасываем пустые и считаем различные. Наивно, но для ответа на вопрос «у человека один доклад или он развивает несколько направлений» этого хватает.! Почему 12 внутренних митапов ≠ доклад на федеральной конференцииЕсли считать только количество, лидерами рейтинга станут люди, которые каждую неделю выступают на внутренних митапах своей команды. Это ценно: они делятся знаниями и держат культуру. Но на вопрос «кого везти на топ-конференцию» количество не отвечает. Двенадцать докладов перед своими коллегами и один доклад на федеральной конференции перед незнакомой аудиторией — это разный опыт, разная подготовка и разный уровень стресса.

Поэтому мы раскладываем доклады спикера по четырём уровням влияния:

private InfluenceBreakdown buildTalkMix(List<TalksRecord> talks) { int local = 0, regional = 0, federal = 0, international = 0; for (TalksRecord talk : talks) { String type = Optional.ofNullable(talk.getConferenceType()).orElse(""); switch (type.toUpperCase(Locale.ROOT)) { case "MEETUP" -> local++; // внутренний case "WORKSHOP" -> regional++; // региональный case "CONFERENCE" -> federal++; // федеральный default -> international++; // международный } } return new InfluenceBreakdown(local, regional, federal, international); }

Маппинг типа площадки на уровень пока грубый, и мы это понимаем: бывают и федеральные митапы, и международные воркшопы. Но даже такая разметка сразу показывает форму профиля. У кого-то «пирамида» с широким основанием из митапов и парой конференций сверху. У кого-то один громкий доклад и больше ничего. Это два очень разных разговора о развитии.

Тренды по четырём периодам

Одна и та же активность выглядит по-разному в разных масштабах. Поэтому для каждого спикера мы сразу строим ряды по четырём периодам:

  • 30 дней — четыре недели, точки подписаны W1…W4.
  • Квартал — три месяца, подписи по месяцам: янв, фев, мар.
  • Год — двенадцать месяцев, тоже по месяцам.
  • Всё время — по годам, начиная с года первого доклада: 2022, 2023 и так далее.

Все четыре ряда считаются на бэкенде и уходят на фронт одним ответом, поэтому переключение периода в интерфейсе мгновенное и не требует нового запроса. На коротком периоде видно «человек выступил на этой неделе». На годовом видно сезонность и спады. На «всё время» видна траектория: растёт человек или выдыхается.

Оценка спикера: история и динамика, а не текущий балл

Самый прямой сигнал о спикере — его оценка по шкале от 1 до 10. У неё два источника.

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

Зачем два источника. Ручная оценка не масштабируется: при сотне спикеров DevRel физически не успевает оценить каждого после каждого доклада. Именно отсюда растут слепые зоны, о которых пойдёт речь ниже. Автоматическая оценка закрывает этот разрыв, но знает только то, что написали слушатели. Вместе они дают регулярность без потери экспертного взгляда.

Сначала мы сделали так же, как делают почти все: одно поле с оценкой в профиле спикера. Быстро стало понятно, что это тупик. Балл 8,2 сам по себе почти ничего не говорит. Это рост с шести или падение с девяти? Ответ на вопрос «кто растёт» лежит не в текущем значении, а в его изменении.

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

CREATE TABLE speaker_score_history ( id BIGSERIAL PRIMARY KEY, speaker_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE, score DECIMAL(3,1) NOT NULL CHECK (score >= 1 AND score <= 10), measured_at TIMESTAMP NOT NULL, source VARCHAR(50) NOT NULL DEFAULT 'manual' );

Поле `source` отличает ручную оценку DevRel (`manual`) от вычисленной по отзывам (`feedback`). В карточке спикера рядом с баллом видно, откуда он взялся. Текущая оценка — это последняя запись в истории, неважно из какого источника. Если DevRel не согласен с автоматическим баллом, он просто ставит свою оценку, и она становится текущей.

Анкета для слушателей намеренно короткая: пять вопросов, на каждый три варианта ответа. Длинную форму после доклада никто не заполнит.

1. Насколько полезным было выступление?
2. Насколько понятной была подача материала?
3. Хватило ли практических примеров?
4. Как оцениваете темп выступления?
5. Насколько интересной была подача?

Каждый вариант ответа переводится в баллы: лучший даёт 10, средний 6, худший 2. С темпом чуть хитрее: «комфортный» даёт 10, а «слишком быстрый» и «слишком медленный» — по 4. Плохо в обе стороны, но это не провал доклада. Оценка анкеты — среднее по пяти вопросам, оценка доклада — среднее по всем анкетам.

private static final int MIN_RESPONSES = 5; // null, если отзывов слишком мало для честной оценки Optional<BigDecimal> computeFeedbackScore(List<TalkFeedback> responses) { if (responses.size() < MIN_RESPONSES) { return Optional.empty(); // два отзыва от друзей спикера — ещё не оценка } double avg = responses.stream() .mapToDouble(this::scoreOfResponse) // среднее по пяти вопросам, 2..10 .average() .orElseThrow(); // приводим к шкале 1–10 с одним знаком после запятой double clamped = Math.max(1.0, Math.min(10.0, avg)); return Optional.of(BigDecimal.valueOf(clamped).setScale(1, RoundingMode.HALF_UP)); }

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

Пересчёт запускается при каждой новой анкете. Если оценка доклада изменилась, в историю пишется новая запись с `source = 'feedback'`. Чтобы история не превращалась в шум из почти одинаковых значений, мы пишем запись только при изменении балла хотя бы на 0,5 или раз в сутки, если анкеты продолжают приходить.

Высокий балл без свежей оценки — это иллюзия

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

Рейтинг показывает спикера с оценкой 90 на третьем месте. DevRel видит его в шорт-листе на федеральную конференцию и почти отправляет заявку. А в слепых зонах тот же человек висит с причинами «Нет свежей оценки, 400 дней» и «Низкая активность». За это время он мог сменить команду, перестать выступать или полностью уйти в менеджмент. Девяносто баллов — это фотография человека, которого уже нет.

Поэтому мы смотрим на рейтинг и слепые зоны вместе. Рейтинг отвечает на вопрос «кто лучший из тех, о ком мы знаем». Слепые зоны отвечают на вопрос «насколько хорошо мы знаем». Второй вопрос должен звучать первым.

Что дальше: слабые сигналы

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

Для этого мы начали выносить в отдельный сервис оценку по «слабым сигналам». На вход идут числовые признаки спикера: всего докладов, докладов за последние 3 месяца, средняя оценка слушателей из отзывов, число отзывов, оценка спикера, полнота профиля, прогресс по ачивкам, количество CFP с высоким совпадением. К ним добавляется текстовый контекст: последние доклады и отзывы, упоминания из внешних источников, теги профиля. LLM возвращает оценку потенциала от 1 до 5, короткое обоснование и уровень уверенности (`low`, `medium`, `high`).

Упоминания из внешних источников проходят через ту же логику, что и всё остальное: каждое попадает в статус «новое», «дубликат», «подтверждено» или «отклонено». На дашборде виден процент подтверждённых из проверенных. Пока DevRel не подтвердил упоминание, оно не считается фактом.

Уровень уверенности здесь не украшение, а прямое продолжение идеи слепых зон. Модель тоже должна уметь сказать «я про этого человека знаю мало». Веса и пороги для этой части мы ещё не утвердили и в интерфейсе честно об этом пишем.

Итоги

- Единица учёта — доклад. Спикер — агрегат над докладами, поэтому его оценка не устаревает молча.

- Оценка — гибрид из активности, оценки спикера, уровня влияния и полноты профиля. Ни одна группа по отдельности не отвечает на вопрос «кого везти на топ-конференцию».

- Количество докладов без микса по уровням вводит в заблуждение: 12 внутренних митапов ≠ доклад на федеральной конференции.

- Оценку спикера храним историей. Её ставит DevRel или система вычисляет по отзывам слушателей. Динамика — это сравнение с предыдущей оценкой, а при одной оценке тренда нет.

- Личный экран спикера показывает те же данные как карту роста: ачивки и CFP вместо места в рейтинге.

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

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

22