Разведка роста
AI-агент разбирает всю клиентскую базу до отдельного клиента и предлагает гипотезы: кому предложить продукт, кого удержать, где банк теряет доход. Под каждой он показывает расчёт. Продуктолог решает, что проверять, аналитик-куратор сверяет расчёты.
Одну гипотезу проверяют неделями: продуктолог заказывает выгрузку, аналитик считает, продуктолог уточняет, аналитик считает снова.
Агент знает схему хранилища, сам пишет SQL и проверяет гипотезу за минуты. В итогах по сегментам не видно точек роста, а агент находит их в поведении каждого клиента.
- 8 рабочих днейхватило пилоту, чтобы найти точки ростабез агента на одну гипотезу уходят недели
- ≈70%точек роста пилот нашёл в деталях поведения клиентовклассический процесс их пропустил бы
- 400+ часованалитика освободилось за те же 8 днейаналитик уже не исполнитель выгрузок, а куратор агента
- 7–10 в деньразобранных гипотез вместо 2–3 итераций в неделю
- 21 679сочетаний по 2–5 типов можно составить из 20 типов данныхэто возможные сочетания, а не выполненные проверки; аналитик за итерацию смотрит ~10 разрезов, оценка по пилоту
Дашборд покажет готовые цифры, аналитик через дни, агент за минуты
Выберите вопрос: ответят все три.
Дашборд
Мониторинг бизнеса
Падение видно, состав не виден
Покажет, что доход и число клиентов снизились. Не покажет, сколько потеряли на ушедших, а сколько на тех, кто остался и платит меньше.
Финансовый аналитик
Выгрузки и расчёты под запрос
Разбор по каждому клиенту
Берёт два месяца и сравнивает доход каждого клиента по всем продуктам. Раскладывает падение на части, которые сходятся с итогом. На каждую новую разбивку уходит ещё день.
AI-агент
Проверка гипотез вместе с продуктологом
Состав падения, сверенный с итогом
Делит клиентов на ушедших, новых и оставшихся с меньшим доходом и считает, на сколько изменился доход в каждой группе и по каждому продукту. Видно, что делать первым: возвращать ушедших или растить доход оставшихся.
Сроки: оценка по работе продуктовых команд и пилоту аналогичного агента.
Узкое место одно, выигрывают трое
Продуктолог ждёт аналитика, аналитик тонет в выгрузках, сеть продаж получает отчёты сверху. Агент убирает очередь к аналитику: у каждого из троих своя выгода, у банка общая.
Продуктолог
проверяет гипотезы
Боль сейчасЗаказывает выгрузку и ждёт дни. За неделю успевает 2–3 итерации гипотезы.
С агентомСпрашивает агента обычными словами или берёт готовый шаблон вопроса.
РезультатЗа день разбирает 7–10 гипотез и получает около 36 инсайтов.
Что получает банкПродукт выходит на рынок с гипотезами, разобранными на данных, а не с догадками.
Финансовый аналитик
исполнитель выгрузок → куратор агента
Боль сейчасТратит до 60–70% времени на рутинные выгрузки. Каждую команду ведёт свой аналитик.
С агентомКурирует агента: берёт сложные расчёты, проверяет выводы, пополняет его знания о данных.
Результат1–2 аналитика ведут 5–10 команд, и новые команды обходятся без найма.
Что получает банкФонд оплаты труда не растёт, когда команд становится больше. Аналитики заняты сложными расчётами, а не выгрузками.
Сеть продаж
продаёт на местах
Боль сейчасПолучает отчёты сверху, сравнить своё отделение с лучшими нечем.
С агентомОтделение само смотрит свой профиль и сравнивает с лучшими.
РезультатОтделения перенимают опыт лучших.
Что получает банкРастёт проникновение продуктов, растут кросс-продажи.
Цифры из пилота аналогичного агента; сколько команд ведёт один аналитик, это расчёт по ним.
Агент показывает запрос и расчёт, а вывод проверяет аналитик
У каждой проверки своя задача. Агент берёт данные только из разрешённой витрины. Защита пропускает одно чтение и обрывает долгий запрос. Сверка ищет сбой в периоде, совпадениях и единицах. Шлюз доказательств оставляет вывод гипотезой, пока не хватает данных. Эти четыре проверки автоматические и могут пропустить ошибку в самом определении показателя, поэтому расчёт и вывод проверяет аналитик-куратор.
Продуктолог ставит задачу без очереди к аналитику
Сначала агент читает свои правила и схему базы
Агент сверяет задачу с данными и строит гипотезы
Агент выгружает данные сам и только читает: запрос откатывается
По пути агент находит новые гипотезы, а решает продуктолог
Продуктолог ставит задачу: «где вырастить доход от эквайринга?». Агент сначала читает свои правила (read only: SELECT, WITH, EXPLAIN; months: closed only; client income: income_month; missing data: name it, do not guess) и схему витрины mart.client_month: region (регион), industry (отрасль), status (активный клиент), acquiring_active_flag (эквайринг), income_month (доход клиента), month (закрытый месяц). Сверяет задачу с данными: «эквайринг»: acquiring_active_flag; «доход»: income_month; «где»: region × industry; «доход от эквайринга»: нет, в витрине такого поля нет: считаем доход клиентов с эквайрингом. Строит гипотезы: 1) слабые регионы отстают от портфеля; 2) в каких отраслях эквайринг берут реже; 3) похожие клиенты уже с эквайрингом; 1 и 2 проверит один запрос, 3 следом. Пишет SQL; защита пропускает только select, with, explain, запросы без записи, а delete отклоняет: Write/admin SQL is blocked. База выполняет запрос и откатывает его, данные остаются как были: rows 14 · 2,8 s · ROLLBACK. Ответ: клиентов с эквайрингом, Регион 1, 20%; в среднем по портфелю 47%; разрыв +260 млн ₽/мес по доходу клиентов с эквайрингом, пример расчёта для крупного банка. По пути агент заметил: платежи тают у части клиентов: риск оттока? (копать); новые когорты держатся лучше: дело в тарифе? (отложить); второго продукта нет: кросс-продажа? (копать). Решает продуктолог: копать сейчас или отложить.
Реконструкция сессии, цифры условные; разрыв в деньгах: пример расчёта для крупного банка. Правила агента и запрос: реконструкция по приёмам боевого кода; поля витрины и строки защиты: код автора · обезличено.
Не сошлось: агент сам находит причину
В сегменте «малый бизнес, открыт в этом году» 124 000 клиентов, а средний доход вышел нулём. Агент не отвечает «Данные не сошлись», а проверяет три гипотезы: период (причина), совпадения (следствие), единицы (снята). Причина в периоде: август загружен на 12% от обычного объёма. С данными о доходе совпало 0 из 124 000 клиентов: это следствие той же причины. Гипотезу про единицы агент снимает: суммы не в миллионах. Вывод: август не закрыт: считаем по последнему полному месяцу.
Данные синтетические; запросы: код автора · обезличено.
Без новых данных: из 20 типов можно составить 21 679 сочетаний
База остаётся той же, новых таблиц нет. Агент пересекает 20 типов данных: платежи (входящие платежи, исходящие платежи, контрагенты, обороты по картам, эквайринг); продукты (счёт и тариф, кредиты, депозиты и остатки, зарплатный проект, бизнес-карты); клиент (отрасль, регион, размер бизнеса, возраст компании, каналы обслуживания); динамика (сезонность, когорта прихода, доход с клиента, обращения и отзывы, отток и возврат). Если брать типы по 2, выходит 190 сочетаний; по 3 типа 1 140; по 4 типа 4 845; по 5 типов 15 504. Всего можно составить 21 679 сочетаний. Потом агент пропускает сочетания через фильтры. Каждый фильтр ищет одну находку: похожие клиенты (отрасль, регион, размер бизнеса, обороты по картам); сезонный провал (сезонность, обороты по картам, входящие платежи); платежи тают (входящие платежи, исходящие платежи, отток и возврат); карты без эквайринга (бизнес-карты, эквайринг, обороты по картам). Аналитик смотрит ~10 разрезов за итерацию, агент 20–30+ разрезов на гипотезу.
Типы данных: примеры; возможные сочетания по 2–5 из 20 типов, не число проверок; разрезы за итерацию и на гипотезу: пилот аналогичного агента.
Без доказательств агент не выдаёт гипотезу за тезис
Вопрос: Где проникновение эквайринга ниже среднего по портфелю и сколько это стоит? База отдаёт доказательства: penetration_by_region: Регион 1: 20% · Регион 2: 63%; portfolio_norm: в среднем 47%; income_with_product: 8 150 ₽ на клиента; client_reviews: statement timeout, необязательный источник. Coverage score: 100 из 100. «В Регионе 1 проникновение вдвое ниже среднего по портфелю»: тезис; «Разрыв стоит денег каждый месяц»: тезис; «Часть клиентов не подключает эквайринг из-за комиссии»: гипотеза, запрос данных: отзывы клиентов об эквайринге за полгода.
Данные в карточках синтетические; шлюз доказательств: код автора · обезличено.
Уточнение у аналитика стоит от 4 ч до недели, у агента минуты
Агент готовит презентацию за день, запуск на 1–6 недель раньше
После запуска агент отделит эффект акции от других
Продуктологу нужен анализ данных. Классическая цепочка: продуктолог → финансовый аналитик → финансовый департамент. Выгрузка занимает 0,5–3 дня, очередь до недели. Каждое уточнение возвращает вопрос аналитику и добавляет от 4 ч до 1 недели. После 4 уточнений цепочка занимает 2,5–28 раб. дн., у агента 5–50 мин. Дальше защита идеи: неделя на презентацию и неделя на согласование. Презентацию с данными, графиками и текстами агент собирает за 1 день; согласование агент не сокращает. Time to market, путь от вопроса к запуску, занимает 12,5–38 раб. дн. без агента и ≈6 раб. дн. с агентом. Через 3–6 месяцев после запуска эффекты нескольких акций на одной базе клиентов смешаны; агент отделяет эффект каждой по тому, как меняется поведение клиентов. Без агента разбор эффекта занимает 4 ч–8 раб. дн., с агентом 1–10 мин.
Оценка по цепочке: выгрузка 0,5–3 дня и очередь до недели, уточнение от 4 часов до недели, защита идеи две недели, эффект разбирают одной выгрузкой через цепочку; с агентом цикл 1–10 минут, презентация за день, согласование, как и раньше, неделя.
Код этого раздела
# Data rules the analyst agent reads before a task (reconstruction on top of the production prompts) read only: SELECT, WITH, EXPLAINmonths: closed onlyactive client: status = 'active'client income: income_monthgroups under :min_clients: hiddenmissing data: name it, do not guessevery figure: the query it came fromАгент находит точки роста, которых нет в отчётах, и считает их потенциал
Суммы и число клиентов в карточках: пример расчёта для крупного банка, реальные цифры закрыты NDA. Это расчётный потенциал, а не результат пилота и не полученный доход: связь в данных, даже прослеженная до отдельного клиента, ещё не доказывает, что предложение принесёт эти деньги. Три находки из пилота аналогичного агента: за 8 рабочих дней 306 запросов дали 61 гипотезу и 329 инсайтов. Персональный кэшбэк из практики автора. Ниже четыре находки. Другие точки роста пилот нашёл в активации клиентов, в продажах по городам и в новых срезах клиентской базы.
«Около 70% находок пилота скрыты в деталях того, как ведут себя клиенты. Классический процесс их пропустил бы: они видны, только если свести вместе нестандартные срезы, аномалии и разные источники.»
Итог разбора · Автор решения: постановка задачи, устройство агента, метрики для пилота, дорожная карта.
Нажмите на находку: ниже появится ход агента к ней, под ним запрос.
Находка 1 из 4 · пример расчёта для крупного банка
Разрыв проникновения между регионами
В сильном регионе ключевой продукт у 63% клиентов сегмента, в слабом у 20%. Если подтянуть слабые регионы до среднего по портфелю, в пересчёте на крупный банк это плюс 260 млн рублей в месяц. Сумма считает весь доход банка от клиентов с продуктом, а не только от самого продукта: отдельного поля в витрине нет.
Ход агента: каждый ответ рождает новый вопросв пилоте на одну гипотезу 20–30+ разрезов данных · ход: реконструкция
Где ключевой продукт берут реже, чем в среднем по портфелю?
регион × отрасль→ в слабом регионе 20%, в сильном 63%- ↳ новый вопрос
Разрыв во всём регионе или в отдельных отраслях?
тот же срез по отраслям→ в отдельных отраслях, остальные на уровне портфеля - ↳ новый вопрос
Кто в этих отраслях уже активно пользуется банком?
оборот по картам→ часть клиентов каждый месяц платит картами банка - ↳ пересечение 2 × 3
Кого подключать первым?
слабые отрасли × оборот по картам→ клиентов с оборотом по картам, но без продукта - ↳ новый вопрос
Почему они не подключают продукт?
отзывы клиентов→ комиссия пока гипотеза, агент просит данные
Находка+260 млн ₽/месдоход банка от клиентов с продуктомпример расчёта для крупного банка
Запрос, который дал находку
WITH base AS ( SELECT region, industry, COUNT(*) AS clients, AVG(acquiring_active_flag::numeric) AS penetration, AVG(income_month) FILTER (WHERE acquiring_active_flag = 1) AS income_with_product FROM mart.client_month WHERE month = :month AND status = 'active' GROUP BY region, industry HAVING COUNT(*) >= :min_clients),portfolio AS ( SELECT industry, AVG(acquiring_active_flag::numeric) AS portfolio_penetration FROM mart.client_month WHERE month = :month AND status = 'active' GROUP BY industry)SELECT b.region, b.industry, b.clients, ROUND(100 * b.penetration, 1) AS penetration_pct, ROUND(100 * p.portfolio_penetration, 1) AS portfolio_pct, ROUND((p.portfolio_penetration - b.penetration) * b.clients * b.income_with_product) AS monthly_gapFROM base bJOIN portfolio p USING (industry)WHERE b.penetration < p.portfolio_penetrationORDER BY monthly_gap DESC;Метод
Из 100 получивших предложение у агента уйти собирались 80, по дашборду 10
Бюджет одинаковый: предложение получают 1 000 клиентов. Продуктолог берёт сегмент по дашборду, аналитик срез прошлых периодов, агент отбирает клиентов по одному: сводит данные хранилища с тем, что говорили ушедшие клиенты с похожим поведением и набором продуктов, и называет вероятную причину ухода. Счёт показывает, до кого дошло предложение, а не кого оно удержало. Точность списка проверена на прошлых уходах, это практика автора. Удержание меряют после акции на клиентах, по которым список не настраивали.
Кто выбирает, кому отправить предложение
Что видит агент
- данные хранилища: оборот, платежи, остатки, продукты
- голос ушедших: что они говорили в звонках и отзывах
- похожие клиенты: поведение и набор продуктов
Агент выбирает клиентов по одному: из 1 000 получивших предложение уйти собирались 800, и для каждого известна вероятная причина. Тот же бюджет доходит до уходящих в 8 раз чаще, чем акция по дашборду.
Почему уходят: по словам ушедших клиентов с похожим поведением
- дорого обслуживание35%
- у другого банка выгоднее ставка25%
- нет нужного продукта20%
- долго решают проблемы20%
Чтобы предложение дошло до 100 уходящих клиентов, по дашборду нужно 1 000 предложений, по отчёту аналитика 333, агенту 125. Экономию можно оставить банку или вложить в более сильное предложение тем, кто уходит.
С чего агент начинает: сигналы угасания по каждому клиенту
WITH signals AS ( SELECT client_id, (turnover_3m < 0.5 * turnover_prev_3m)::int AS turnover_fell, (days_since_last_payment > 45)::int AS went_quiet, (balance_avg_3m < 0.7 * balance_avg_prev_3m)::int AS balance_fell, (products_closed_3m > 0)::int AS closed_product FROM mart.client_month WHERE month = :month AND status = 'active'),scored AS ( SELECT client_id, turnover_fell + went_quiet + balance_fell + closed_product AS risk_score FROM signals)SELECT client_id, risk_scoreFROM scoredWHERE risk_score >= 3ORDER BY risk_score DESC;Продуктолог с агентом разбирает 7–10 гипотез в день вместо 2–3 итераций в неделю
Показатели взяты из презентации, на команду и месяц их не пересчитывали.
Источник цифр: внешний пилот аналогичного агента. За 8 рабочих дней: 11 сессий, 306 запросов, 61 гипотеза, 329 инсайтов, 277 аналитических обращений. За тот же срок освободилось 400+ часов работы аналитика.
Проверка гипотезы: медиана. Половина проверок укладывается в этот срок, а раньше уходили недели.
~10 мин
Данные без очереди. За 11 сессий пилота.
277 обращений
За один день. Гипотезы и инсайты считаются отдельно.
- Гипотез в день на одного продуктолога
- 7–10
- Инсайтов и точек роста в день
- ~36
Пилот: 1–2 месяца, три человека, закрытый контур банка
Для пилота нужны три человека, обезличенный срез данных и один продуктовый домен. Нажмите на пункт: откроется, что нужно, что это даёт и как это выглядит на доске спринта.
Что нужно
только чтение
Данные и контур
Агент работает внутри закрытого контура банка, а данные берёт из обезличенного среза хранилища. Каждый запрос проходит защиту: агенту можно только читать (SELECT, WITH и EXPLAIN). Долгий запрос обрывает таймаут. В конце запрос откатывается, и данные остаются как были. Менять код, настройки и базу агент не может: сначала заявка, потом проверка, и только после неё агент-исполнитель вносит изменение.
Агент только читает данные, а любое изменение проходит заявку и проверку
Пример рабочей доски спринта: люди, компании и числа вымышлены Код контура: защита, доказательства, правило агента
scripts/db-query.shкод автора · обезличено#!/usr/bin/env bashset -euo pipefail STACK_DIR="ops/analytics-db"ENV_FILE="$STACK_DIR/.env"COMPOSE=(docker compose --env-file "$ENV_FILE" -f "$STACK_DIR/docker-compose.yml") set -asource "$ENV_FILE" # credentials stay on the server, never in the reposet +a if [[ $# -gt 0 ]]; then SQL="$*"else SQL="$(cat)"fi SQL_TRIMMED="$(printf '%s' "$SQL" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"SQL_LOWER="$(printf '%s' "$SQL_TRIMMED" | tr '[:upper:]' '[:lower:]')" if [[ -z "$SQL_TRIMMED" ]]; then echo "Empty SQL" >&2 exit 2fi if [[ ! "$SQL_LOWER" =~ ^(select|with|explain)[[:space:]] ]]; then echo "Only SELECT/WITH/EXPLAIN queries are allowed" >&2 exit 2fi if [[ "$SQL_LOWER" =~ (^|[^a-z])(insert|update|delete|drop|alter|create|truncate|grant|revoke|copy|vacuum|analyze|call|do)([^a-z]|$) ]]; then echo "Write/admin SQL is blocked" >&2 exit 2fi "${COMPOSE[@]}" exec -T -e PGPASSWORD \ postgres psql -v ON_ERROR_STOP=1 -U "$READONLY_USER" -d "$ANALYTICS_DB" -P pager=off \ -c "BEGIN READ ONLY; SET LOCAL statement_timeout = '15s'; SET LOCAL lock_timeout = '2s'; ${SQL_TRIMMED}; ROLLBACK;"
Этапы
только чтение
Данные и контур
Агент работает внутри закрытого контура банка, а данные берёт из обезличенного среза хранилища. Каждый запрос проходит защиту: агенту можно только читать (SELECT, WITH и EXPLAIN). Долгий запрос обрывает таймаут. В конце запрос откатывается, и данные остаются как были. Менять код, настройки и базу агент не может: сначала заявка, потом проверка, и только после неё агент-исполнитель вносит изменение.
Агент только читает данные, а любое изменение проходит заявку и проверку
Код контура: защита, доказательства, правило агента
#!/usr/bin/env bashset -euo pipefail STACK_DIR="ops/analytics-db"ENV_FILE="$STACK_DIR/.env"COMPOSE=(docker compose --env-file "$ENV_FILE" -f "$STACK_DIR/docker-compose.yml") set -asource "$ENV_FILE" # credentials stay on the server, never in the reposet +a if [[ $# -gt 0 ]]; then SQL="$*"else SQL="$(cat)"fi SQL_TRIMMED="$(printf '%s' "$SQL" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"SQL_LOWER="$(printf '%s' "$SQL_TRIMMED" | tr '[:upper:]' '[:lower:]')" if [[ -z "$SQL_TRIMMED" ]]; then echo "Empty SQL" >&2 exit 2fi if [[ ! "$SQL_LOWER" =~ ^(select|with|explain)[[:space:]] ]]; then echo "Only SELECT/WITH/EXPLAIN queries are allowed" >&2 exit 2fi if [[ "$SQL_LOWER" =~ (^|[^a-z])(insert|update|delete|drop|alter|create|truncate|grant|revoke|copy|vacuum|analyze|call|do)([^a-z]|$) ]]; then echo "Write/admin SQL is blocked" >&2 exit 2fi "${COMPOSE[@]}" exec -T -e PGPASSWORD \ postgres psql -v ON_ERROR_STOP=1 -U "$READONLY_USER" -d "$ANALYTICS_DB" -P pager=off \ -c "BEGIN READ ONLY; SET LOCAL statement_timeout = '15s'; SET LOCAL lock_timeout = '2s'; ${SQL_TRIMMED}; ROLLBACK;"Пилот сравнивает три цифры до и после запуска агента
от вопроса до ответа
Вопрос
БылоЗаявка аналитику ждёт в очереди до недели
С агентомЗадача агенту, ответ за минуты
В пилоте замеряют: срок проверки гипотезы
Цифры: пилот аналогичного агента
от вопроса до ответа
Вопрос
Заявка аналитику ждёт в очереди до недели
Задача агенту, ответ за минуты
В пилоте замеряют: срок проверки гипотезы
Цифры: пилот аналогичного агента
Пилот идёт 1–2 месяца на одном продуктовом направлении. Агент работает с обезличенным срезом хранилища. До и после пилота замеряют те же три цифры, что стоят на шагах выше: срок проверки гипотезы, число разобранных гипотез и время аналитика на команду.
- код автора · обезличенокод, который работает в агентах автора; имена систем, пути и доступы заменены.
- перенесено из боевого кода · проверено тестамибоевой код, перенесённый на TypeScript: защита отвечает на 28 тестовых запросов так же, как боевой скрипт, а подсчёт доказательств работает в шаге «Доказательства» выше.
- реконструкция по приёмам боевого кодазапросы, написанные для страницы теми же приёмами.
О статистике сайта
Сайт считает просмотры и действия без профилей посетителей.
На моём сервере в России хранятся день, страница, тип события и общий счётчик. Считаются просмотры страниц, переходы к резюме на hh.ru, запуски видео и демо, появление конца кейса на экране.
Статистика работает без cookie, идентификаторов и отпечатков устройств. Содержимое форм и адреса с параметрами в сводки не попадают. Сервисам аналитики я данные не передаю.
При соединении сервер получает IP-адрес. В статистику он не входит, но может попасть в журнал ошибок. Новые журналы ошибок хранятся отдельно до 14 дней, сводные счётчики до удаления владельцем сайта.
Если в браузере включён сигнал запрета отслеживания Do Not Track или Global Privacy Control, события не отправляются.