Агент проверки гипотез: десятки тысяч сочетаний на стандартных данных хранилища
Сила агента — пересечения: 20 типов данных из той же базы дают 21 679 сочетаний, команде аналитиков их не перебрать.
Одну гипотезу проверяют неделями: продуктолог заказывает выгрузку, аналитик считает, продуктолог уточняет, аналитик считает снова.
Агент знает схему хранилища, сам пишет SQL и проверяет гипотезу за минуты. Точки роста он находит в поведении каждого клиента — в итогах по сегментам их не видно.
- 8 рабочих днейхватило пилоту, чтобы найти точки роста бизнесаклассический цикл одной гипотезы — недели
- ≈70%найденных точек роста скрыто в деталях поведения клиентовклассический процесс их пропустил бы
- 400+ часовработы аналитика освободилось за те же 8 днейаналитик — уже не исполнитель выгрузок, а куратор агента
- 7–10 в деньпроверенных гипотез вместо 2–3 итераций в неделю
- 21 679сочетаний из 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 млн ₽/мес, пример расчёта для крупного банка. По пути агент заметил: платежи тают у части клиентов — риск оттока? — копать; новые когорты держатся лучше — дело в тарифе? — отложить; второго продукта нет — кросс-продажа? — копать. Решает продуктолог: копать сейчас или отложить.
Реконструкция сессии, цифры условные; разрыв в деньгах — пример расчёта для крупного банка. Правила агента и запрос — реконструкция по приёмам боевого кода; поля витрины и строки защиты — код автора · обезличено.
Не сошлось — агент сам ищет причину
Средний доход сегмента вышел нулём: segment — малый бизнес, открыт в этом году; clients — 124 000; avg_revenue — 0. Агент не отвечает «Данные не сошлись», а проверяет три гипотезы: период — причина, совпадения — следствие, единицы — снята. Причина: август загружен на 12% от обычного объёма. Вывод: август не закрыт — считаем по последнему полному.
Данные синтетические; запросы — код автора · обезличено.
Та же база — 20 типов данных, десятки тысяч сочетаний
База остаётся той же: новых таблиц нет. Агент пересекает 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 проникновение вдвое ниже среднего по портфелю» — тезис; «Разрыв стоит денег каждый месяц» — тезис; «Часть клиентов не подключает эквайринг из-за комиссии» — гипотеза, запрос данных: отзывы клиентов об эквайринге за полгода.
Данные в карточках синтетические; шлюз доказательств — код автора · обезличено.
Каждое уточнение — новый круг очереди. У агента — минуты
Агент готовит презентацию за день — запуск на 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;Метод
Тот же бюджет удержания — в 8 раз больше уходящих: у агента до них доходят 80 предложений из 100, по дашборду — 10
Агент разбирает каждого клиента: сводит данные хранилища с тем, что говорили ушедшие клиенты с похожим поведением и набором продуктов, и называет вероятную причину ухода. Банк тратит на удержание меньше или на те же деньги удерживает больше клиентов.
Кто выбирает, кому отправить предложение
Что видит агент
- данные хранилища: оборот, платежи, остатки, продукты
- голос ушедших: что они говорили в звонках и отзывах
- похожие клиенты: поведение и набор продуктов
Агент выбирает клиентов по одному: из 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 гипотез в день
Показатели из презентации, без пересчёта на команду и месяц.
Источник цифр — внешний пилот аналогичного агента. За 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 тестовых запросов так же, как боевой скрипт, а подсчёт доказательств работает в шаге «Доказательства» выше.
- реконструкция по приёмам боевого кодазапросы, написанные для страницы теми же приёмами.