метрикиNPSCSATпродукт

NPS, CSAT и CES: метрики лояльности для аналитика

2026-07-11 12 мин

Если у вас на дашборде висит одна цифра «удовлетворённость», вы почти наверняка меряете не то, что думаете. NPS, CSAT и CES отвечают на три разных вопроса. NPS спрашивает, готов ли человек рекомендовать продукт, — это про долгую лояльность и сарафанное радио. CSAT — доволен ли он конкретным контактом прямо сейчас: заказом, тикетом, звонком. CES — сколько усилий ему пришлось приложить, чтобы решить свою задачу. Считаются они по-разному, живут в разных точках пути пользователя, и если их перепутать, получится красивый график, по которому нельзя принять ни одного решения. Ниже разбираю, как посчитать каждую, где брать данные и как в итоге связать всё это с retention и деньгами.

Что измеряют NPS, CSAT и CES — и почему их путают?

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

NPS (Net Promoter Score) — стратегическая метрика отношения к бренду в целом. Классический вопрос: «Насколько вероятно, что вы порекомендуете нас другу или коллеге?», шкала 0–10. Это про накопленное впечатление, а не про сегодняшнее настроение.

CSAT (Customer Satisfaction) — тактическая, транзакционная. Её задают сразу после конкретного события: «Насколько вы довольны решением вашего вопроса?», обычно шкала 1–5 (иногда 1–3 или 1–7). Меряет качество одной точки контакта.

CES (Customer Effort Score) — про трение. Вопрос вида «Насколько легко вам было решить свою задачу?», шкала часто 1–7 (от «очень трудно» до «очень легко») или согласие с утверждением «Компания упростила решение моего вопроса». CES особенно хорошо предсказывает отток в сервисных сценариях: люди уходят не потому, что их не любят, а потому, что с продуктом тяжело.

Простая аналогия. NPS — это оценка за отношения в целом. CSAT — оценка за конкретное свидание. CES — насколько сложно было до этого свидания вообще добраться. Три разных вопроса, три разных решения на выходе.

Как правильно посчитать NPS в SQL?

NPS считается не как среднее по шкале — это первая ошибка новичка. Ответы 0–10 бьются на три группы: промоутеры (9–10), нейтралы или пассивы (7–8) и детракторы (0–6). Формула словами: доля промоутеров в процентах минус доля детракторов в процентах. Пассивы в расчёт не входят, но сидят в знаменателе. Итог лежит в диапазоне от -100 до +100 и обычно показывается без знака процента, хотя по сути это разница долей.

Допустим, ответы лежат в таблице nps_survey с полями user_id, score, created_at.

SELECT
    ROUND(
        100.0 * SUM(CASE WHEN score >= 9 THEN 1 ELSE 0 END) / COUNT(*)
      - 100.0 * SUM(CASE WHEN score <= 6 THEN 1 ELSE 0 END) / COUNT(*)
    , 1) AS nps,
    COUNT(*) AS responses
FROM nps_survey
WHERE created_at >= '2026-01-01';

Одна общая цифра почти бесполезна — она не подсказывает, что чинить. Гораздо полезнее NPS в разрезе тарифа, канала привлечения или когорты. Тут же добавляю порог по числу ответов, чтобы не делать выводов по десятку анкет:

SELECT
    u.plan,
    COUNT(*)                                            AS responses,
    SUM(CASE WHEN s.score >= 9 THEN 1 ELSE 0 END)       AS promoters,
    SUM(CASE WHEN s.score <= 6 THEN 1 ELSE 0 END)       AS detractors,
    ROUND(
        100.0 * (SUM(CASE WHEN s.score >= 9 THEN 1 ELSE 0 END)
               - SUM(CASE WHEN s.score <= 6 THEN 1 ELSE 0 END))
        / COUNT(*), 1)                                  AS nps
FROM nps_survey s
JOIN users u ON u.id = s.user_id
GROUP BY u.plan
HAVING COUNT(*) >= 100
ORDER BY nps DESC;

Если хотите потренировать такие CASE-агрегации и HAVING на живых таблицах, вот подходящее место — SQL-тренажёр, а разбор синтаксиса группировок держу под рукой в SQL-справочнике.

Чем отличаются CSAT и CES и как их считать?

CSAT считается проще NPS и ближе к интуиции: это доля «довольных» от всех ответивших. На шкале 1–5 довольными обычно считают тех, кто поставил 4 или 5 (top-2-box). Формула словами: количество ответов 4–5 делим на общее число ответов, умножаем на 100.

SELECT
    ROUND(100.0 * SUM(CASE WHEN rating >= 4 THEN 1 ELSE 0 END) / COUNT(*), 1) AS csat,
    COUNT(*) AS responses
FROM csat_responses
WHERE closed_at >= date('now', '-30 day');

Важный момент, который часто забывают зафиксировать в документации: где именно проходит граница «доволен». На шкале 1–5 это 4–5, на 1–7 — обычно 6–7. Если аналитик молча меняет порог, метрика «улучшается» на ровном месте, и это чистая манипуляция. Договоритесь о пороге один раз и держите его.

CES технически считается похоже на CSAT — как доля тех, кому было легко (top-2-box по «лёгкости»), либо как среднее по шкале. Я предпочитаю среднее плюс долю «тяжело», потому что именно хвост недовольных даёт отток. Полезно смотреть CES по типам обращений: оформление возврата, смена тарифа, восстановление доступа. Часто оказывается, что общий CES приличный, а один-два сценария проваливаются — вот их и надо чинить в первую очередь.

Когда применять каждую из трёх метрик?

Отталкивайтесь от того, какое решение хотите принять, а не от того, что модно.

NPS ставят периодически (раз в квартал или по «relationship»-волне) и на весь продукт. Он хорош как медленный барометр направления и как язык для разговора с руководством: одна цифра, которую все понимают. Плохо подходит для быстрых итераций — он инерционный и шумный на коротких окнах.

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

CES ставят после сервисных взаимодействий, где ключевое — усилие: прохождение воронки, самообслуживание, поддержка. Если гипотеза звучит как «люди уходят, потому что у нас сложно», мерять надо именно CES.

На практике зрелая система использует все три: NPS сверху как стратегический сигнал, CSAT и CES снизу как операционные. Главное — не подменять один другим. NPS не скажет, какой именно шаг воронки бесит; CSAT по одному тикету не расскажет про лояльность к бренду.

Почему «культ NPS» вредит аналитике?

NPS удобен, поэтому его любят превращать в единственную KPI-звезду, — и вот тут начинаются проблемы. Как только цифра попадает в премию менеджера, она перестаёт быть измерением и становится целью. По закону Гудхарта хорошая метрика, ставшая целью, ломается: продавцы начинают вымаливать десятки («если не поставите 10, у меня будут проблемы»), выборку тихо чистят, опрос показывают только довольным.

Вторая беда — сама конструкция. NPS выбрасывает всю информацию о пассивах и грубо режет непрерывную шкалу на три ведра. Клиент с оценкой 6 и клиент с оценкой 0 попадают в одну корзину детракторов, хотя это совершенно разные истории. Из-за этого NPS теряет чувствительность: реальные сдвиги в настроениях он замечает поздно.

Третье — им злоупотребляют для сравнений, которые не имеют смысла. «У нас NPS 40, а у соседей 45» звучит убедительно ровно до того момента, пока не выяснится, что опросы устроены по-разному: другая формулировка, другой момент опроса, другой канал, другая аудитория. Сравнивать NPS двух разных компаний почти всегда некорректно.

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

Как малые выборки и культура искажают опросы?

Две вещи регулярно превращают метрики лояльности в шум. Первая — маленькие выборки. NPS особенно капризен: он основан на разнице долей, поэтому его доверительный интервал широкий. На 50 ответах разброс легко может быть плюс-минус 15–20 пунктов, и «рост NPS с 30 до 40» между спринтами оказывается статистическим дрожанием. Прежде чем радоваться движению, прикиньте интервал. Простой способ — бутстрап:

import numpy as np

# scores — массив ответов 0..10
def nps(x):
    x = np.asarray(x)
    return 100 * ((x >= 9).mean() - (x <= 6).mean())

rng = np.random.default_rng(42)
boot = [nps(rng.choice(scores, size=len(scores), replace=True))
        for _ in range(5000)]

print(round(nps(scores), 1), np.percentile(boot, [2.5, 97.5]).round(1))

Если хотите покрутить это на своих данных, есть Python-тренажёр, а частые вопросы про доверительные интервалы и A/B я собрал в разделе вопросов с собеседований.

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

Сюда же — смещение отбора. Отвечают на опросы обычно люди с сильными эмоциями: очень довольные и очень злые. Молчаливое большинство недопредставлено, поэтому любой опросный показатель — это не «мнение всех клиентов», а «мнение тех, кто ответил». Держите это в голове и следите за response rate: если он упал, сравнивать периоды уже нельзя.

Как связать метрики лояльности с retention и выручкой?

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

import pandas as pd

# survey: user_id, score  |  facts: user_id, retained_6m (0/1), revenue_6m
df = survey.merge(facts, on="user_id", how="inner")

df["segment"] = pd.cut(
    df["score"],
    bins=[-1, 6, 8, 10],
    labels=["detractor", "passive", "promoter"],
)

print(
    df.groupby("segment")
      .agg(users=("user_id", "size"),
           retention_6m=("retained_6m", "mean"),
           arpu_6m=("revenue_6m", "mean"))
      .round(2)
)

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

Аккуратная формулировка про причинность: даже сильная связь NPS с retention — это корреляция, а не доказательство, что «поднимем NPS — вырастет удержание». Чтобы говорить о влиянии, нужен эксперимент над драйвером (сократили усилие в сценарии, где проседал CES, — и смотрим на отток той когорты). Про то, как раскладывать удержание по когортам и не путать причину со следствием, есть отдельные разборы кейсов, а базовые определения удержания и активности лежат в карточке метрики DAU.

С чего начать систему из трёх метрик

Практический план, который я обычно советую. Зафиксируйте пороги (промоутер 9–10, довольный 4–5, «легко» 6–7) и запишите их в документацию — чтобы никто не «улучшал» метрику сдвигом границы. Складывайте сырые ответы в отдельную таблицу с user_id, шкалой, типом опроса и таймстампом, а не только агрегат — агрегат вы всегда пересчитаете, а вот распределение и связь с поведением без сырых данных не восстановите. Всегда показывайте рядом с итоговой цифрой число ответов и response rate. И раз в квартал проверяйте, предсказывает ли метрика retention и выручку на ваших данных.

Хочется довести навык до автомата — потренируйте CASE-агрегации и джойны на практических задачах, а первые шаги в SQL с нуля удобно пройти в базовом курсе; синтаксис pandas для стыковки опросов с фактами — в Python-справочнике.

Если разбираете такие метрики системно и готовитесь к собеседованиям на аналитика, в Pro открыты все задачи, кейсы и метрики с формулами плюс безлимитный AI-тренажёр интервью — без спешки и без давления, когда захотите продолжить.

Считай метрики в тренажёре
Воронки, retention и юнит-экономика на SQL-задачах — бесплатно.
SQL-тренажёр →