Как создавался агрегатор ИБ-новостей: склейка сюжетов, семь признаков важности и порог по данным

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Идея агрегатора новостей по кибербезопасности зародилась еще давно. Хотелось получать самое важное и без инфошума. LLM тогда ещё не были повседневным инструментом, и первую версию реализовал на модели суммаризации rut5_base_sum_gazeta, а важность считал textrank. Работало так себе. Потом появились сервисы, которые сами подбирают новости под настроенную ленту. Но оптимального решения так и не увидел – это либо про всё сразу, либо что-то про одну узкую тему.

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

Что есть сейчас. В агрегатор приходит около тысячи материалов в сутки из более 200 источников кибербезопасности. До публикации доходит ~0,5%. Решение «важно или нет» принимает уже формула из семи признаков с открытыми весами: каждый балл виден в журнале, и с ним можно спорить. Языковая модель же делает две другие вещи: отсекает нерелевантное и пишет текст.

Почему просто не «спросить модель»?

Самый простой агрегатор любых новостей на LLM выглядит так: скормить модели ленту и спросить: «Что из этого важно?». Такой агрегатор работает до первого вопроса «почему этот материал прошёл, а тот нет». Ответ модели будет непрогнозируемым. Два прогона дают разные вердикты, а поправить поведение можно только переписыванием промпта.

Мне же нужно было ранжирование, в котором каждый балл имеет физический смысл и виден в логе с объяснением: «есть 5 изданий с этой новостью, есть первоисточник, обозначен CVSS 9,8, еще и эксплуатируется». При таком устройстве порог калибруется по весам конкретного признака.

Что взято у агрегаторов, а что пришлось придумать

Сжатые новости придуманы очень давно. Почти каждый поисковик предоставляет новости одной строкой. Яндекс.Новости в описании устройства сервиса выделяли четыре шага:

  • сбор от партнёров

  • извлечение фактов

  • кластеризация в сюжеты

  • ранжирование

Вес сообщения там складывается из цитируемости (сколько материалов сюжета ссылаются на него), свежести и информативности. Аннотация сюжета собирается из фрагментов трёх лучших сообщений. Вес источника считается по цитируемости за два месяца и оперативности и пересчитывается еженедельно. Но, очевидно, там и масштаб другой: >6 000 партнёров и больше 110 тысяч сообщений в день.

Что взято напрямую из готовых подходов

Единица работы. У нас, как и у Яндекса, ранжируется сюжет, склеенный из материалов об одном событии, и оценка считается один раз на сюжет. Вес источника как отдельный коэффициент: у Яндекса он вычисляется, у нас задан вручную в зависимости от типа контента. Кстати, та же идея и у Google, который с сентября 2019 года поднимает в выдаче именно оригинальные материалы. У нас для этого есть признак «первоисточник», который делает то же самое.

От формата Axios с фиксированными подписями вроде «Why it matters» пришла идея сделать врезку «Что это такое»/«Контекст». Это фоновое объяснение термина/идеи и живёт отдельным блоком ниже.

Что можно еще взять, но пока не доработано

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

Извлеченная суть новости и сводка. Яндекс.Новости в разборе 2021 года показывает, что сводка собирается только из фрагментов партнёрских текстов («Новости не пишут собственные тексты, даже автоматически»), четыре предложения, эмбеддинги DSSM, кластеризация предложений. В нашем решении выбран генеративный пересказ. Главный подход при этом совпал и со статьей – больше половины ошибок сводки у Яндекса давали дубли, и у нас возникла та же проблема. Но решение быстрое и закрывается отдельным вызовом «это то же самое событие».

Ранжирование по вовлечённости. Это как у Hacker News с его формулой (P−1)/(T+2)^1.8 или у алгоритмических подборок как у «The True Story» по числу комментариев. Не используется сознательно, так как в информационной безопасности самое обсуждаемое и самое важное часто не совпадают (кстати, это может быть субъективно)

Что пришлось придумать, потому что у агрегаторов этого нет

Важность по последствиям. Это особенность новостей в кибербезопасности. Яндекс, Google и Hacker News ранжируют по цитируемости, свежести и голосам, а в безопасности в новостях часто важность задают CVSS, статус эксплуатации и первоисточник вроде каталога KEV. Отсюда признак «серьёзность» и тир primary.

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

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

Разность масштабов. Яндекс пишет, что тяжёлые модели для сводки не может себе позволить из-за потока документов. При тысяче материалов в сутки один вызов модели на сюжет доступен, и ограничение переезжает с вычислений на качество проверок.

Воронка отсева материалов: сначала формула отсекает сюжеты ниже порога важности, потом модель отсекает нерелевантное
Воронка отсева материалов: сначала формула отсекает сюжеты ниже порога важности, потом модель отсекает нерелевантное

Реестр источников – тиры и флаг topical

В реестре более 220 источников. У каждого источника есть «тир» или проще «коэффициент». Он даёт бонус сюжету, в котором этот источник присутствует:

  1. primary: CERT, каталог KEV, бюллетени вендоров.

  2. research: блоги исследователей

  3. security: профильные издания

  4. consulting: аналитические агенства и исследования

  5. eng: инженерные блоги

  6. industry и corp_ru: корпоративные и индустриальные блоги

  7. general: деловые СМИ

Склейка сюжетов

Материалы об одном событии должны стать одним сюжетом для единого поста. Три способа объединения, по убыванию строгости:

  1. Общий идентификатор: CVE, GHSA, бюллетень MS, BDU, KB

  2. Доля общих триграмм внутри одного языка

  3. Доля общих сущностей при не менее чем трёх общих. Латиница с заглавной буквы (Microsoft, SharePoint, Fortinet) связывает русские и английские публикации об одном событии

Но есть две тонкости. Сходство выше 0,80 (это условные цифры) считается перепечаткой и независимым подтверждением не является. Для материалов одного издания порог выше 0,50 (опять же, условно): издание часто пишет о смежных, но разных вещах. Например, Microsoft очень часто упоминается в самых разных контекстах в один день. Каждые полчаса собирается около 1 170 материалов, из них примерно 360 новых. Из них получается около 325 сюжетов, и лишь у шести есть второе издание. Подтверждение встречается редко, отсюда и его вес.

Логика оценки без весов: признаки прибавляют, штрафы вычитают, итог попадает в одну из пяти полос. Штраф за саморекламу снимается, когда событие подтвердило независимое издание.
Логика оценки без весов: признаки прибавляют, штрафы вычитают, итог попадает в одну из пяти полос. Штраф за саморекламу снимается, когда событие подтвердило независимое издание.

Семь признаков и штрафы

  1. Подтверждённость. Число независимых изданий в сюжете по таблице выше. Перепечатки здесь не считаются.

  2. Серьёзность. CVSS >9 даёт полный вес, далее уже по убыванию. Признак реализуемости тут важнее. Если уже «эксплуатируется», то полный вес при любом CVSS. Атака с помощью ИИ даёт низкий балл (да, уж слишком много таких новостей сейчас), если нет описания объекта и самой атаки

  3. Первоисточник. Источник primary в сюжете или оригинальное исследование вендора дают максимальный балл.

  4. Близость к читателю. Российская компания даст повыше вес, далее – российский контекст и глобальный тренд

  5. Глубина разбора. Форма разбора («анатомия атаки», «как устроено») и новизна («новый класс атак») считаются половинками и складываются. А материал, несущий и то и другое, ценнее вдвойне. Анонс продукта или фичи разбором не считается, даже если написан его языком.

  6. Авторитет. Лучший тир в сюжете: первоисточник, исследователь, аналитик, издание.

  7. Скорость. Публикаций в час от первой до последней. Одна публикация в час и быстрее даёт полный вес.

Штрафы даются за:

  • вакансии, вебинары и награды

  • самореклама вендорского блога

  • анонс и пресс-релизы своего продукта («Introducing…», «представляем» ...)

  • маркетинговые маркеры («при поддержке», сгенерированная статья ради CTA в конце)

  • листиклы, материал без источника

Штраф за саморекламу снимается автоматически, как только событие подтвердило второе независимое издание с полезным контекстом. О выходе новой модели ИИ напишут все, об обновлении UI-дашбордов напишет только вендор и перепечатывающие этот пресс-релиз. Список «важных вендоров», который пришлось бы вечно дополнять, при таком правиле не нужен.

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

Поиск оптимального числа для публикаций

Порог публикации был выставлен авансом на 55. За первые сутки его взяли два материала, оба в первый час, дальше лента молчала. Разбор всего, что легло в полосу 35-55, показал границу.

  • До 34 лежат сырые бюллетени ICS-CERT и пакеты соответствия регуляторам: у них есть первоисточник и авторитет, но ни одного признака важности

  • В полосе 36-39 стоит вендорское промо: «Defender изолировал устройство за 128 секунд», «Microsoft названа лидером квадранта KuppingerCole»

  • От 40 начинается то, ради чего лента существует: «Citrix NetScaler отдаёт root без пароля» 45, «Check Point VPN: обход аутентификации эксплуатируется с мая» (63), «TeamCity: эксплуатация подтверждена» (67).

Порог опущен на 40, сразу над промо-полосой. Ниже 35 опускать нельзя: туда сразу попадают бюллетени и самореклама.

Полосы оценки и реальные сюжеты. Полоса 35–39 «дозревает» и ждёт подтверждения вторым изданием; от 75 сюжет выходит вне очереди.
Полосы оценки и реальные сюжеты. Полоса 35–39 «дозревает» и ждёт подтверждения вторым изданием; от 75 сюжет выходит вне очереди.

Пример сюжета длиной в 23 дня – убегающие агенты OpenAI

Инцидент с агентами OpenAI и Hugging Face стал самым цитируемым сюжетом августа. 6 августа он прошёл порог с 46 баллами и был сразу опубликован. В следующие три недели о нём написали ещё 17 материалов из 15 источников: хронология Саймона Уиллисона и Брюса Шнайера, разбор на Хабре, новости о мерах OpenAI в TechCrunch и The Verge, и заметка Selectel. Заметка Selectel 25 августа получила высокий балл, но была снята вторым вызовом как «то же событие, что уже публиковали и это не был первоисточник».

27 августа в 03:05 по Москве сюжет набрал 77 баллов, максимум за замер, и вышел ночью как срочный. Что это было? METR опубликовала независимое расследование с доступом к 70 000 сообщений агентов и 1 300 транскриптам. За несколько часов о нём написали TechCrunch, MIT Technology Review, Alignment Forum и The Register. Первоисточник дал 15, пять изданий дали 22, добавились глубина разбора и скорость: четыре признака сошлись. В итоге, пять источников стали новым единым постом со своим заголовком и врезкой «Что такое ExploitGym».

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

Что и как писать про уязвимости

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

За три недели упомянуты 58 уязвимостей, от Citrix NetScaler, Check Point VPN и Progress LoadMaster до TeamCity, SharePoint и Apache Tomcat:

Критические по баллу, которые не атакуют, и умеренные, которые атакуют почти наверняка. Данные NVD, FIRST и CISA на 26 августа.
Критические по баллу, которые не атакуют, и умеренные, которые атакуют почти наверняка. Данные NVD, FIRST и CISA на 26 августа.

Пример. CVE-2026-19516, подделка запросов в mcp-grafana (это про MCP-сервер для Grafana): CVSS 9,1, EPSS 0,2%, в KEV нет. CVE-2026-34486, обход шифрования в Apache Tomcat: CVSS 7,5, EPSS 98,6%, в KEV есть.

Первая тяжелее по последствиям, но MCP-сервер редко открыт в интернет. Вторая слабее по баллу, но Tomcat открыт постоянно, и её уже используют. Очередь в публикациях:
1) Tomcat первым, обновление до 11.0.21, 10.1.54 или 9.0.117;
2) mcp-grafana вторым, обновление до 1.1.0 и закрытие доступа извне, это плановая работа.

Общее правило: сначала KEV, затем EPSS выше 10%, CVSS третьим.

Что из открытых вопросов и пока без решения

Если есть мысли или примеры как это правильнее реализовать, то буду рад изучить.


Живой результат по описанной схеме работы здесь: https://t.me/cbunit

Источник: https://habr.com/ru/articles/1076014/


Интересные статьи

Интересные статьи

Учёные Новосибирского государственного университета (НГУ) разработали метод определения авторского стиля на основе математической статистики. Разработка одинаково эффективна для четырёх язык...
Данная статья - это не научный прорыв, а лишь помощник быстрее понять как работает стандартный функционал в BitrixДавайте представим, что в разделе каталога у нас 150 запросов к БД. Вроде бы немного п...
Боль - это негативное аффективное состояние, возникающее в результате повреждения или воспаления тканей. Поскольку боль вызывает сильные не приятные ощущения сравнимые с ...
Нередко при работе с Bitrix24 REST API возникает необходимость быстро получить содержимое определенных полей всех элементов какого-то списка (например, лидов). Традиционн...
В 1С-Битрикс: Управление сайтом (как и в Битрикс24) десятки, если не сотни настраиваемых типов данных (или сущностей): инфоблоки, пользователи, заказы, склады, форумы, блоги и т.д. Стр...