И поняли, что лучше не отдавать нейросети эту работу целиком
Привет! Мы BI-разработчики: Айгуль Ахметова из команды аналитиков Авито Рекламы и Валерия Смирнова из Товаров. Вместе мы создаём аналитическую отчётность, которая помогает командам быстрее разбираться в бизнес-метриках. А ещё сделали бота, который снял с аналитиков часть рутины.
Команда Core BI отвечает за основной финансовый дашборд. Каждое утро начинается примерно одинаково:
Открываем основной финансовый отчёт.
Проверяем, успели ли обновиться данные.
Смотрим динамику выручки и проходимся по разрезам.
Если цифра заметно изменилась — разбираемся, где именно и почему. Для этого подключаем аналитиков метрик из разных команд.
Коротко объясняем результат коллегам, а если с данными что-то не так — предупреждаем, когда они будут готовы.

Ничего сверхъестественного, но эти действия каждый день отнимают минимум полчаса. Не потому, что каждый раз нужно провести сложное исследование или глубоко погрузиться в детали. Просто между просмотром графика и ответом на вопрос «Что случилось?» есть несколько обязательных проверок — пропустить их нельзя.
Мы решили автоматизировать эту часть работы и сделали Big10 Pulse — бота в корпоративном мессенджере Mattermost. Он ежедневно мониторит ключевые бизнес-метрики. Как только свежие данные готовы, присылает PDF-отчёт и аналитическую записку с факторным анализом изменений и найденных отклонений.
Так аналитику не приходится каждый день повторять одни и те же действия, а пользователю — постоянно проверять, обновились ли данные.
Звучит как идеальная задача для большой языковой модели — как мы любим: собрать контекст из разных источников и тредов, а затем объяснить найденную аномалию. Но довольно быстро мы поняли, что главное здесь не то, какую работу можно поручить модели, а то, какую — нельзя.
В статье расскажем:
почему обычного алерта об изменении метрики оказалось недостаточно;
как бот отличает аномалию от календарного эффекта;
как мы разделили расчёты и работу языковой модели;
зачем и как проверяем готовый комментарий перед отправкой;
сколько времени бот экономит пользователям.

Содержание
Почему только графика недостаточно
Как работает Big10 Pulse и почему ИИ отдали не всё
Какой результат получили в итоге
Как собрать похожее решение у себя
Почему только графика недостаточно
Big10 собирает в одном месте ключевые финансовые показатели Авито. В нём удобно следить за общей динамикой, но сам график лишь показывает, что метрика изменилась. Он не объясняет, почему это произошло и не раскладывает изменение на конкретные факторы.
Допустим, утром команда видит снижение выручки. Прежде чем обсуждать причины, аналитику нужно проверить:
все ли данные за день загрузились;
отличается ли рост или падение от обычных колебаний;
корректно ли выбрана база для сравнения;
какое направление бизнеса внесло основной вклад в изменение;
какой тип выручки внутри этого направления повлиял на результат.
Последние два пункта особенно важны. Самое большое изменение в процентах не всегда сильнее всего влияет на общую метрику. Небольшой сегмент может заметно вырасти или упасть, но почти не изменить итог. Поэтому мы смотрим не только на динамику отдельных категорий, но и на их вклад в общее отклонение.
И только после этого можно сформулировать гипотезу. Если начать с объяснения, а проверки оставить на потом, легко принять неполную загрузку за падение бизнеса, а обычный праздничный эффект — за инцидент. График при этом будет выглядеть вполне убедительно — в этом чаще всего и проблема.
Поэтому мы не стали делать универсальный чат с отчётом. Задачу сузили до первого аналитического разбора:
Проверить готовность данных.
Отделить сигнал от шума.
Разложить изменение на факторы.
Показать пользователю, куда смотреть дальше.
Как работает Big10 Pulse и почему ИИ отдали не всё
Пользователь заходит в админ-панель бота. Если ещё нет доступа, система предлагает его запросить. После этого можно выбрать нужный отчёт, проверить действующие подписки и указать разрезы, таргеты или фичи, за которыми хочется следить.
Бот сохраняет подписку в базе данных и ждёт обновления источников. Когда данные готовы, присылает пользователю графики, ссылку на отчёт с нужными фильтрами и короткую аналитическую записку.
Перед этим бот выполняет несколько проверок:
Убеждается, что все источники обновились.
Сравнивает метрику с сохранёнными срезами за предыдущие периоды.
Оценивает значимость изменения и раскладывает общую разницу по направлениям бизнеса и типам выручки.
На основе готовых расчётов формируется текст, а отдельный этап проверки определяет, можно ли показывать его пользователю.
В итоге вместо сообщения «выручка снизилась на N%» пользователь получает первый ориентир: насколько изменение типично, в каком сегменте возникло и какие цифры это подтверждают.
На этом анализ не заканчивается. Бот обращается к детальному отчёту по факторам и проверяет, что именно внутри категории могло повлиять на результат. Например, изменение количества CPC-кликов, звонков или других продуктовых показателей.
Так комментарий показывает не только, где изменилась метрика, но и с чем может быть связано это изменение.

Сначала проверяем готовность данных
Это самая приземлённая часть системы и, пожалуй, самая важная. Хотелось бы сразу перейти к модели и аналитическим выводам, но сначала приходится выяснить, актуальны ли сегодняшние данные.
Если один из источников задержался, общий показатель может выглядеть как резкое падение. Разрезы тоже будут выглядеть убедительно: один сегмент просел сильнее другого, доли перераспределились, на графике образовалась некрасивая аномалия. Только анализировать её бессмысленно — мы сравнили полный прошлый день с неполным текущим.
Поэтому бот сначала не ищет причины, а проверяет дату последнего обновления. Пока данные не готовы, расчёт не запускается. После успешной проверки система отправляет отчёт один раз. Факт отправки сохраняется, чтобы пользователь не получил несколько одинаковых сообщений.
Здесь языковая модель не участвует. Она может складно объяснить даже ошибку загрузки, но нам в такой ситуации нужен не складный текст, а отсутствие текста.
Не каждое изменение — аномалия
Сравнивать сегодняшнее значение только со вчерашним недостаточно. У бизнес-метрик есть недельная, а иногда и месячная сезонность.
Одни показатели закономерно меняются в начале и конце месяца, другие зависят от дня недели. Поведение метрики может отличаться и в зависимости от специфики продукта: например, в категории путешествий рост в выходные может быть ожидаемым, а не аномальным.
Отдельный случай — праздники. Предпраздничные дни, сами праздники и возвращение к обычному ритму после них влияют на метрики по-разному. Поэтому резкий скачок после длинных выходных ещё не означает, что произошло что-то необычное.
Бот сравнивает текущее значение с показателем за прошлую неделю и семидневным средним. Допустимые границы зависят от типа дня и исторического поведения конкретной метрики. Отдельное правило помогает отсеивать ожидаемый отскок после праздников.
Пороговые значения рассчитываются обычным кодом. Для нас это принципиально: на одинаковых данных система должна принимать одинаковое решение. Мы не просим языковую модель посмотреть на график и определить, похоже ли это на аномалию.
При этом само срабатывание правила ещё не доказывает, что возникла проблема. Это только сигнал: изменение вышло за ожидаемые границы и его стоит разобрать подробнее.

Ищем не самый большой процент, а самый большой вклад
Когда система нашла отклонение, нужно понять, где именно оно возникло. Для этого бот раскладывает общую разницу по направлениям бизнеса и типам выручки.
Допустим, что общий показатель снизился на 100 условных единиц. Одно направление дало минус 80, другое — минус 30, а третье выросло на 10. В сумме получаем те же минус 100, но теперь понятно, с какого участка начинать проверку.
Из сообщения бота можно перейти в исходный отчёт. Пользователь выбирает разрезы и сразу видит нужное представление данных. Не приходится заново выставлять фильтры и искать место, где произошло изменение.
При этом смотреть только на проценты недостаточно. Маленькая категория может вырасти на десятки процентов и почти не повлиять на общий результат. Поэтому бот ранжирует факторы по их вкладу в общую разницу.
И здесь появляется важная граница. Вклад отвечает на вопрос «где произошло изменение?», но не всегда — на вопрос «почему?». Эти два вопроса легко перепутать, особенно когда хочется быстро принести готовый ответ.
Если на один сегмент пришлась большая часть падения, это ещё не доказывает, что именно в нём произошёл технический сбой или возникла продуктовая проблема. Для такого вывода нужен дополнительный контекст — поэтому, когда бот определил основной фактор, он более детально анализирует показатели внутри сегмента.

Что всё-таки поручили модели
К этому моменту все содержательные расчёты уже закончены. Система знает, готовы ли данные, насколько изменилась метрика, с чем её сравнивали и какие сегменты дали основной вклад.
Модель получает только этот короткий набор фактов и превращает его в связный комментарий. Относительные изменения заранее рассчитаны, абсолютные значения подставляет Python-код. Модель не считает выручку, не выбирает пороги и не заполняет пропуски.
Такое разделение оказалось удобным и немного контринтуитивным:
Чем меньше свободы мы оставляли модели, тем полезнее становился её ответ
Всё, что можно однозначно выразить правилом, остаётся в коде. Модели достаётся работа, для которой она действительно полезна: собрать несколько фактов в короткий текст и не заставлять пользователя расшифровывать таблицу.
А ещё мы не передаём ей весь отчёт. Лишний контекст здесь не помогает: чем больше случайных связей видит модель, тем проще ей придумать правдоподобное объяснение. Для записки достаточно данных по конкретному отклонению.
Почему хорошего промпта мало
Даже на правильных входных данных модель иногда усиливает вывод. Расчёт говорит: «Основной отрицательный вклад пришёлся на направление A». В тексте внезапно появляется: «Выручка снизилась из-за технической ошибки в направлении A». Звучит логично, но сведений о технической ошибке у модели не было.
Поэтому перед тем, как бот отправит пользователю готовую записку, она проходит две проверки:
Отсеиваем заглушки, шаблонные ответы и сообщения без данных.
Сверяем текст с исходным набором фактов и ищем числа или утверждения, которых там не было.
Но проверять только текст без исходных данных бесполезно: в таком случае мы оцениваем убедительность формулировки, а не достоверность.
Вот как могут отличаться два ответа:
🟢 Метрика отклонилась от недельного ориентира. Основной отрицательный вклад дали направление A и тип выручки B. По имеющимся данным изменение локализовано в этом сегменте, но определить первопричину пока нельзя.
🔴 Метрика снизилась из-за технической ошибки в направлении A.
Второй ответ короче, увереннее и даже приятнее читается. Именно поэтому его нельзя отправлять: система не знает ничего о технической ошибке.
Одна система — разные отчёты
Разным командам нужны разные части Big10. Одному пользователю важна конкретная вертикаль, другому — категория внутри неё. Подписка хранит выбранный срез, язык и тип отчёта. Юзер сам меняет настройки через кнопки в Mattermost, без нашей помощи.
Если несколько человек выбрали одинаковый срез, бот не повторяет один и тот же расчёт для каждого. Результат переиспользуется, а от дублей защищает журнал отправок.
После дайджеста можно задать уточняющий вопрос в том же диалоге. Бот подбирает доступный контекст, передаёт его модели вместе с вопросом и снова проверяет ответ. Права доступа при этом не меняются: бот не должен показывать сведения, которых пользователь не увидел бы в исходной системе.
Что выяснили по дороге
Качество объяснения начинается с качества данных. Звучит очевидно, но именно это спасает от самых неприятных ошибок. Никакой промпт не исправит неполную загрузку и не превратит некорректную цифру в надёжный вывод. Поэтому перед анализом бот всегда проверяет готовность источников.
Аномалия, вклад и причина — не одно и то же. Автоматическое правило обнаруживает необычное движение метрики. Декомпозиция показывает, где оно возникло. А первопричину обычно подтверждает человек — иногда с помощью дополнительных источников. Если смешать эти этапы, система начнёт выдавать правдоподобные гипотезы за установленные факты.
Ограничения делают языковую модель полезнее. Чем меньше свободы мы оставляем ей в работе с числами и фактами, тем надёжнее она справляется со своей задачей — формулирует понятный комментарий на основе уже рассчитанных данных.
Проверяющему компоненту нужны те же исходные факты, которые получил генератор. Иначе одна вероятностная модель просто оценивает ответ другой — убедительно, но без возможности проверить, соответствует ли он данным.
По мере развития Big10 Pulse появились и менее очевидные задачи:
Управление доступами. Если пользователь не может открыть исходный отчёт, бот не должен присылать ему содержимое. Поэтому сначала система проверяет права и, если их нет, предлагает запросить доступ.
Наблюдаемость. Важно понимать не только, работает ли бот технически, но и как им пользуются: на какие отчёты подписываются, как растёт аудитория и на каких этапах возникают ошибки. Для мониторинга мы выбрали Grafana — там следим за использованием продукта и сбоями в его работе.
Сбор обратной связи. Основные пользователи Big10 Pulse — руководители и менеджеры, которым важно быстро получать ответ и так же быстро сообщать, если в отчёте не хватает нужного разреза, контекста или функции. Поэтому обратная связь для нас — не дополнительная опция, а часть развития продукта.
Какой результат получили в итоге
На этапе пользовательского тестирования у бота было 9 подтверждённых подписчиков. Даже на этой небольшой базе мы оценили экономию примерно в 99 человеко-часов в месяц: 9 пользователей × 30 минут в день × 22 рабочих дня. Позже подписку на сервис самостоятельно настроили ещё 55 пользователей.
Это расчётная оценка, а не точный хронометраж сэкономленного времени. Более показательно изменение самого сценария:
⏱️ Вместо 30–60 минут на проверку отчёта пользователь тратит одну-две минуты на чтение уже подготовленного разбора.
🤖 Бот не заменил аналитика и не научился сам находить первопричину любого движения. Он снял более узкую задачу: дожидается корректных данных → замечает отклонения → показывает человеку основные факторы и проводит к первой проверяемой гипотезе.
Самым важным решением оказалось не добавить языковую модель, а вовремя её остановить
Цифры, календарь и правила остались в обычном коде. Модель получила маленькую, но подходящую ей роль — объяснить, на что человеку стоит посмотреть первым. Иногда лучший способ сделать AI-инструмент надёжнее — дать AI чуть меньше работы.

Как собрать похожее решение у себя
Архитектура Big10 Pulse привязана к нашим отчётам, но порядок действий можно перенести на другой мониторинг.
Начните с одного отчёта и одной метрики. Опишите, когда данные считаются готовыми, с какими периодами их корректно сравнивать и какие колебания ожидаемы. Эти правила лучше написать обычным кодом и покрыть несколькими примерами — модель здесь не нужна.
Добавьте разложение общей разницы на составляющие. Оно должно отвечать на вопрос «где произошло изменение», не пытаясь автоматически доказать причину.
Только после этого подключайте языковую модель. Передавайте ей короткий набор уже рассчитанных фактов и просите сформулировать комментарий. Отдельная проверка должна получить и текст, и тот же набор исходных данных.
Доставку и персонализацию можно добавлять последними. Они полезны, когда сам расчёт стабилен и вы понимаете, какие срезы действительно нужны пользователям.
Вся статья кратко
👉 Big10 Pulse дожидается готовности финансового отчёта, находит необычные изменения выручки, раскладывает их по направлениям и присылает пользователю первый разбор в Mattermost.
👉 Расчёты, календарные правила и числа остаются в обычном коде. Языковая модель получает готовые факты и пишет по ним короткий комментарий. Перед отправкой текст сверяется с исходными данными.
👉 Бот не устанавливает первопричину и не принимает решение за аналитика. Его задача — снять повторяемую часть работы и быстрее привести человека к месту, с которого стоит начать расследование.
Заходите на огонёк в «Коммуналку аналитиков» — наш канал, где обсуждаем победы и фейлы из рабочих будней, ну и, конечно, нейросети.
А в канале «Любовь, BI и графики» Валерия Смирнова рассказывает про рабочие проекты, показывает датавиз и делится советами о профессии.

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