Product-Led Growth Playbook: как построить AI-powered PQL scoring с нуля
Что такое Product Qualified Lead (PQL)?
Product Qualified Lead — это пользователь бесплатного тарифа, который продемонстрировал намерение купить через поведение в продукте: выполнил activation events, достиг лимитов использования или пригласил коллег. PQL scoring переводит этот поведенческий сигнал в числовой скоринг, который показывает sales-команде, кому звонить и почему.
TL;DR
- -MQL scoring не работает в PLG, потому что демографические и маркетинговые сигналы слабо предсказывают конверсию: пользователь может зарегистрироваться с Gmail, игнорировать все письма и всё равно конвертироваться в платного.
- -PQL score складывается из трёх компонентов: activation score (40%), engagement score (35%) и firmographic score (25%), каждый из которых основан на продуктовых событиях, аналитике использования и enrichment-данных.
- -Activation events необходимо определять для каждого продукта отдельно через когортный анализ — сравнение поведения конвертированных и ушедших пользователей в первые 14 дней — их нельзя заимствовать из кейсов.
- -LLM-обогащение превращает числовой скоринг в sales briefing: гипотеза о use case, сигнал расширения, рекомендуемое начало разговора и фактор риска — всё на основе реальных данных использования.
- -Калибруйте модель ежемесячно: фиксированные пороги деградируют за 2–3 месяца по мере того, как activation-паттерны меняются с выходом новых фич и сезонными изменениями поведения.
Компании с Product-Led Growth конвертируют free-to-paid эффективнее, чем sales-led. Но только при условии, что sales получает правильных лидов в правильный момент. Большинство команд до сих пор передают в CRM всех, кто зарегистрировался, вместо тех, кто готов покупать.
Product Qualified Lead (PQL) отличается от MQL принципиально. MQL заполнил форму. PQL использовал продукт и показал поведение, предсказывающее конверсию. Статья о том, как построить PQL scoring model с нуля: от определения activation events до автоматической классификации через LLM и синхронизации с CRM.
Что такое PQL scoring и почему MQL scoring не работает в PLG
MQL scoring опирается на демографию и маркетинговые взаимодействия: должность, размер компании, скачал whitepaper, посетил вебинар. В PLG-модели эти сигналы слабые. Пользователь мог зарегистрироваться с gmail-адресом, ни разу не открыть маркетинговое письмо и при этом активно использовать продукт каждый день.
PQL scoring использует product usage data как первичный сигнал. Три категории данных:
Activation signals. Пользователь выполнил ключевые действия, коррелирующие с долгосрочным retention. Для Slack это отправка 2000 сообщений командой. Для Dropbox — загрузка файла с одного устройства и доступ с другого. Для каждого продукта activation events уникальны.
Engagement depth. Частота использования, количество feature adoptions, время в продукте. Не просто “логинился 5 раз”, а “использовал 3+ core features за последние 7 дней”.
Expansion signals. Пользователь приглашает коллег, создаёт команду, упирается в лимиты free-плана, экспортирует данные. Эти действия сигнализируют о растущей ценности продукта для организации.
Определение activation events с помощью LLM
Первый шаг — найти activation events для конкретного продукта. Классический подход: ретроспективный анализ когорт. Берём пользователей, которые конвертировались в платных, и сравниваем их поведение с теми, кто ушёл. Это предполагает чистую event taxonomy - без единых имён событий и свойств когортные сравнения возвращают шум.
SQL-запрос для базовой когортной разбивки (если SQL для вас новый - паттерны ниже разобраны в SQL для продактов):
WITH converted_users AS (
SELECT user_id, MIN(subscription_start) AS conversion_date
FROM subscriptions
WHERE plan != 'free'
GROUP BY user_id
),
user_events AS (
SELECT
e.user_id,
e.event_name,
COUNT(*) AS event_count,
COUNT(DISTINCT DATE(e.created_at)) AS active_days,
CASE WHEN cu.user_id IS NOT NULL THEN 'converted' ELSE 'churned' END AS cohort
FROM events e
LEFT JOIN converted_users cu ON e.user_id = cu.user_id
WHERE e.created_at <= COALESCE(cu.conversion_date, e.created_at + INTERVAL '30 days')
AND e.created_at >= e.user_created_at
AND e.created_at <= e.user_created_at + INTERVAL '14 days'
GROUP BY e.user_id, e.event_name, cohort
)
SELECT
event_name,
cohort,
AVG(event_count) AS avg_count,
PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY event_count) AS median_count,
COUNT(DISTINCT user_id) AS users
FROM user_events
GROUP BY event_name, cohort
ORDER BY event_name, cohort;
Запрос сравнивает поведение конвертированных и ушедших пользователей в первые 14 дней. Результат — таблица, где видно, какие события статистически значимо отличаются между когортами.
Проблема: таблица содержит десятки событий, и не все корреляции означают причинно-следственную связь. LLM помогает интерпретировать результаты и предложить гипотезы.
Промпт для анализа activation events:
Ты — product analyst. Проанализируй данные когортного анализа для SaaS-продукта.
Контекст продукта: [описание продукта, основные use cases, ключевые features]
Данные (event_name | cohort | avg_count | median_count | users):
[вставить результат SQL-запроса]
Задачи:
1. Определи 3-5 событий с наибольшей разницей между когортами converted и churned
2. Для каждого события предложи пороговое значение (threshold), при котором вероятность конверсии значительно возрастает
3. Исключи события, которые являются следствием конверсии, а не её предиктором
4. Предложи комбинации событий (activation milestones), которые формируют "aha moment"
Формат ответа: JSON с полями event_name, threshold, confidence, reasoning
LLM не заменяет статистический анализ. Он ускоряет интерпретацию и генерирует гипотезы, которые дальше валидируются A/B-тестами. Результат промпта — набор activation events с пороговыми значениями.
Архитектура PQL scoring model
PQL score — число от 0 до 100. Складывается из трёх компонентов с разными весами:
| Компонент | Вес | Источник данных |
|---|---|---|
| Activation score | 40% | Product events |
| Engagement score | 35% | Usage analytics |
| Firmographic score | 25% | Enrichment data |
Activation score
Бинарная проверка: выполнил пользователь activation event или нет. Каждый activation event имеет свой вес внутри компонента.
WITH activation_checks AS (
SELECT
u.user_id,
u.email,
u.company_domain,
-- Activation event 1: создал проект
MAX(CASE WHEN e.event_name = 'project_created' THEN 1 ELSE 0 END) AS created_project,
-- Activation event 2: пригласил коллегу
MAX(CASE WHEN e.event_name = 'team_invite_sent' THEN 1 ELSE 0 END) AS invited_teammate,
-- Activation event 3: использовал core feature 3+ раз
CASE WHEN COUNT(CASE WHEN e.event_name = 'core_feature_used' THEN 1 END) >= 3
THEN 1 ELSE 0 END AS used_core_feature,
-- Activation event 4: настроил интеграцию
MAX(CASE WHEN e.event_name = 'integration_connected' THEN 1 ELSE 0 END) AS connected_integration
FROM users u
LEFT JOIN events e ON u.user_id = e.user_id
AND e.created_at >= u.created_at
AND e.created_at <= u.created_at + INTERVAL '14 days'
GROUP BY u.user_id, u.email, u.company_domain
)
SELECT
user_id,
email,
company_domain,
ROUND(
(created_project * 30 +
invited_teammate * 30 +
used_core_feature * 25 +
connected_integration * 15)
) AS activation_score
FROM activation_checks;
Веса activation events назначаются на основе корреляции с конверсией из когортного анализа. invited_teammate обычно получает высокий вес, потому что приглашение коллег — сильный предиктор покупки в B2B SaaS.
Engagement score
Измеряет глубину и частоту использования. В отличие от activation score, engagement score непрерывный и пересчитывается ежедневно.
WITH daily_usage AS (
SELECT
user_id,
COUNT(DISTINCT DATE(created_at)) AS active_days_last_14,
COUNT(DISTINCT event_name) AS unique_features_used,
COUNT(*) AS total_events,
MAX(created_at) AS last_active_at
FROM events
WHERE created_at >= CURRENT_DATE - INTERVAL '14 days'
GROUP BY user_id
),
engagement_scored AS (
SELECT
user_id,
-- Frequency: дни активности из 14
LEAST(active_days_last_14 / 14.0 * 100, 100) AS frequency_score,
-- Breadth: количество уникальных features (нормализовано к общему числу)
LEAST(unique_features_used / 8.0 * 100, 100) AS breadth_score,
-- Recency: штраф за неактивность
CASE
WHEN last_active_at >= CURRENT_DATE - INTERVAL '1 day' THEN 100
WHEN last_active_at >= CURRENT_DATE - INTERVAL '3 days' THEN 75
WHEN last_active_at >= CURRENT_DATE - INTERVAL '7 days' THEN 40
ELSE 10
END AS recency_score
FROM daily_usage
)
SELECT
user_id,
ROUND(frequency_score * 0.4 + breadth_score * 0.35 + recency_score * 0.25) AS engagement_score
FROM engagement_scored;
Нормализация breadth_score зависит от количества core features в продукте. В примере 8 — это число нужно заменить на реальное количество отслеживаемых фич.
Firmographic score
Product usage data даёт основной сигнал. Дополнительные 25% — данные о компании. Размер, индустрия, технологический стек. Эти данные поступают из enrichment-сервисов (Clearbit, Apollo, Clay).
SELECT
u.user_id,
CASE
WHEN c.employee_count > 500 THEN 30
WHEN c.employee_count > 100 THEN 25
WHEN c.employee_count > 20 THEN 20
WHEN c.employee_count > 5 THEN 15
ELSE 5
END +
CASE
WHEN c.industry IN ('technology', 'saas', 'fintech') THEN 25
WHEN c.industry IN ('ecommerce', 'media', 'education') THEN 20
WHEN c.industry IN ('healthcare', 'manufacturing') THEN 15
ELSE 10
END +
CASE
WHEN c.estimated_revenue > 10000000 THEN 25
WHEN c.estimated_revenue > 1000000 THEN 20
WHEN c.estimated_revenue > 100000 THEN 15
ELSE 5
END +
CASE
WHEN u.email NOT LIKE '%gmail.com'
AND u.email NOT LIKE '%yahoo.com'
AND u.email NOT LIKE '%hotmail.com' THEN 20
ELSE 0
END AS firmographic_score
FROM users u
LEFT JOIN companies c ON u.company_domain = c.domain;
Корпоративный email даёт +20 баллов. Грубый, но эффективный фильтр: пользователь с рабочим доменом конвертируется в платного значительно чаще, чем с бесплатным почтовым сервисом.
Финальный PQL score и классификация через LLM
Композитный score:
SELECT
a.user_id,
a.email,
ROUND(
a.activation_score * 0.40 +
e.engagement_score * 0.35 +
f.firmographic_score * 0.25
) AS pql_score,
CASE
WHEN ROUND(a.activation_score * 0.40 + e.engagement_score * 0.35 + f.firmographic_score * 0.25) >= 75 THEN 'hot'
WHEN ROUND(a.activation_score * 0.40 + e.engagement_score * 0.35 + f.firmographic_score * 0.25) >= 50 THEN 'warm'
WHEN ROUND(a.activation_score * 0.40 + e.engagement_score * 0.35 + f.firmographic_score * 0.25) >= 25 THEN 'nurture'
ELSE 'monitor'
END AS pql_tier
FROM activation_scores a
JOIN engagement_scores e ON a.user_id = e.user_id
JOIN firmographic_scores f ON a.user_id = f.user_id;
Четыре тира:
- Hot (75+): Передать sales немедленно. Высокая вероятность конверсии.
- Warm (50-74): In-app upsell triggers. Автоматические подсказки о premium features.
- Nurture (25-49): Onboarding drip campaigns. Подтолкнуть к activation events.
- Monitor (0-24): Наблюдение. Не тратить ресурсы sales.
Распределение по тирам - сама по себе метрика, которую стоит трекать. PLG-дашборд с динамикой hot/warm/nurture во времени показывает, улучшается activation или регрессирует, ещё до того как это видно в выручке.
Числовой score решает задачу приоритизации. Но sales-команде нужен контекст: почему этот пользователь горячий, какой use case, о чём говорить на первом звонке. LLM решает эту задачу.
Промпт для генерации sales context:
Ты — sales intelligence assistant. На основе product usage data сгенерируй briefing для sales-менеджера.
Данные пользователя:
- Email: {email}
- Компания: {company_name} ({industry}, {employee_count} сотрудников)
- PQL score: {pql_score} (tier: {pql_tier})
- Activation events выполнены: {completed_activations}
- Activation events не выполнены: {missing_activations}
- Самые используемые features: {top_features}
- Дней активности за 14 дней: {active_days}
- Количество приглашённых коллег: {invited_count}
- Текущий план: {plan}
- Упирается в лимиты: {hit_limits}
Сгенерируй:
1. Use case hypothesis (1 предложение): какую задачу решает пользователь
2. Expansion signal (1 предложение): почему готов к апгрейду
3. Recommended opening (1 предложение): с чего начать разговор
4. Risk factor (1 предложение): что может помешать конверсии
Формат: JSON. Без общих фраз. Только конкретика на основе данных.
Результат — структурированный JSON, который записывается в CRM-запись контакта. Sales-менеджер видит не просто “score: 82”, а конкретный контекст: “Пользователь ежедневно использует feature X для задачи Y, пригласил 4 коллег, упирается в лимит API-запросов. Рекомендация: предложить Enterprise план с фокусом на team collaboration.”
Автоматический pipeline: от events до CRM
Архитектура pipeline состоит из четырёх этапов:
Product Events → Event Store → Score Calculator → CRM Sync
│ │ │
Segment/ Scheduled job HubSpot/
Amplitude/ (hourly/daily) Salesforce
PostHog API
Этап 1: сбор событий
Product analytics (Segment, Amplitude, PostHog) отправляет события в warehouse. Минимальный набор полей для каждого события:
{
"user_id": "usr_abc123",
"event_name": "core_feature_used",
"properties": {
"feature": "report_builder",
"duration_seconds": 340
},
"timestamp": "2026-03-25T14:22:00Z",
"context": {
"company_domain": "acme.com"
}
}
Этап 2: расчёт score
Scheduled job (cron, Airflow, dbt) выполняет SQL-запросы из предыдущих разделов. Результат — таблица pql_scores с полями user_id, pql_score, pql_tier, activation_score, engagement_score, firmographic_score, calculated_at.
CREATE TABLE pql_scores AS
SELECT
a.user_id,
a.email,
a.company_domain,
a.activation_score,
e.engagement_score,
f.firmographic_score,
ROUND(a.activation_score * 0.40 + e.engagement_score * 0.35 + f.firmographic_score * 0.25) AS pql_score,
CASE
WHEN ROUND(a.activation_score * 0.40 + e.engagement_score * 0.35 + f.firmographic_score * 0.25) >= 75 THEN 'hot'
WHEN ROUND(a.activation_score * 0.40 + e.engagement_score * 0.35 + f.firmographic_score * 0.25) >= 50 THEN 'warm'
WHEN ROUND(a.activation_score * 0.40 + e.engagement_score * 0.35 + f.firmographic_score * 0.25) >= 25 THEN 'nurture'
ELSE 'monitor'
END AS pql_tier,
CURRENT_TIMESTAMP AS calculated_at
FROM activation_scores a
JOIN engagement_scores e ON a.user_id = e.user_id
JOIN firmographic_scores f ON a.user_id = f.user_id;
Этап 3: LLM-обогащение
Для пользователей с pql_tier = 'hot' или при переходе из warm в hot запускается LLM-классификация. Вызов API происходит batch-ом, не в реальном времени. Стоимость: ~$0.01-0.03 за одного пользователя при использовании GPT-5.4-mini (актуальные цены на platform.openai.com).
import json
from openai import OpenAI
client = OpenAI()
def generate_sales_context(user_data: dict) -> dict:
prompt = f"""Ты — sales intelligence assistant...
[промпт из предыдущего раздела с подставленными данными]"""
response = client.chat.completions.create(
model="gpt-5.4-mini",
messages=[{"role": "user", "content": prompt}],
response_format={"type": "json_object"},
temperature=0.3
)
return json.loads(response.choices[0].message.content)
Низкая temperature (0.3) обеспечивает стабильность выводов. JSON response format гарантирует парсинг без ошибок. Если используется мульти-провайдерная архитектура с LiteLLM, вызов проходит через единый прокси с fallback на альтернативные модели. Мониторинг качества промптов — через Langfuse.
Этап 4: синхронизация с CRM
HubSpot и Salesforce поддерживают custom properties через API. Минимальный набор полей для синхронизации:
import hubspot
from hubspot.crm.contacts import SimplePublicObjectInput
client = hubspot.Client.create(access_token="your_token")
def sync_pql_to_hubspot(user_email: str, pql_data: dict, sales_context: dict):
properties = {
"pql_score": str(pql_data["pql_score"]),
"pql_tier": pql_data["pql_tier"],
"pql_activation_score": str(pql_data["activation_score"]),
"pql_engagement_score": str(pql_data["engagement_score"]),
"pql_use_case": sales_context.get("use_case_hypothesis", ""),
"pql_expansion_signal": sales_context.get("expansion_signal", ""),
"pql_recommended_opening": sales_context.get("recommended_opening", ""),
"pql_last_calculated": pql_data["calculated_at"]
}
contact = SimplePublicObjectInput(properties=properties)
client.crm.contacts.basic_api.update(
contact_id=get_contact_id_by_email(user_email),
simple_public_object_input=contact
)
При переходе пользователя в tier hot CRM автоматически создаёт задачу для sales-менеджера. Чем быстрее outreach после PQL-сигнала, тем выше win rate — это хорошо изученная закономерность в B2B продажах.
Калибровка модели и пороговых значений
PQL scoring model требует регулярной калибровки. Два ключевых параметра:
Precision. Какой процент hot PQL реально конвертируется. Целевой показатель: >30%. Если precision ниже 20%, пороги слишком низкие или веса компонентов неправильные.
Recall. Какой процент реальных конверсий модель предсказала как hot/warm. Целевой показатель: >70%. Если recall ниже 50%, модель упускает паттерны поведения.
SQL-запрос для оценки precision и recall:
WITH predictions AS (
SELECT
p.user_id,
p.pql_tier,
CASE WHEN s.user_id IS NOT NULL THEN 1 ELSE 0 END AS actually_converted
FROM pql_scores p
LEFT JOIN subscriptions s ON p.user_id = s.user_id
AND s.plan != 'free'
AND s.subscription_start > p.calculated_at
AND s.subscription_start <= p.calculated_at + INTERVAL '30 days'
WHERE p.calculated_at >= CURRENT_DATE - INTERVAL '90 days'
)
SELECT
pql_tier,
COUNT(*) AS total_users,
SUM(actually_converted) AS converted,
ROUND(SUM(actually_converted)::NUMERIC / COUNT(*) * 100, 1) AS precision_pct,
ROUND(SUM(actually_converted)::NUMERIC /
(SELECT COUNT(DISTINCT user_id) FROM subscriptions
WHERE plan != 'free'
AND subscription_start >= CURRENT_DATE - INTERVAL '90 days') * 100, 1
) AS recall_pct
FROM predictions
GROUP BY pql_tier
ORDER BY pql_tier;
Калибровку проводят ежемесячно. Поведение пользователей меняется: новые features сдвигают activation patterns, сезонность влияет на engagement. Фиксированные пороги деградируют за 2-3 месяца.
Автоматизация калибровки: тот же LLM анализирует drift в метриках и предлагает корректировки весов. Финальное решение — за продуктовой командой.
Экономика PQL scoring
Стоимость внедрения зависит от инфраструктуры.
| Компонент | Стоимость (месяц) |
|---|---|
| Event tracking (Segment/PostHog) | $0-300 (free tier покрывает до 10K MAU) |
| Data warehouse (BigQuery/Snowflake) | $50-200 |
| LLM API (GPT-5.4-mini для hot leads) | ~$10-50 (при ~1000 hot PQL/месяц) |
| CRM (HubSpot/Salesforce) | Существующая подписка |
| Orchestration (Airflow/cron) | $0-50 |
Итого: $60-600/месяц для компании до 50K MAU. Сравнение с готовыми решениями: Pocus, Correlated стоят от $500/месяц при аналогичном MAU. Собственная реализация дешевле, но требует инженерных ресурсов на поддержку.
Типичные ошибки при внедрении PQL scoring
Слишком много activation events. 3-5 событий достаточно. Модель с 15+ событиями переобучается на шум и теряет предсказательную силу.
Игнорирование account-level aggregation. В B2B покупает компания, не пользователь. Если 5 сотрудников одной компании активны, но каждый получает индивидуальный score 30, модель упускает горячий аккаунт. Агрегируйте scores на уровне company_domain.
Статичные пороги. Пороги hot/warm/nurture должны адаптироваться к объёму, который sales-команда может обработать. Если hot PQL — 500 в неделю, а sales-команда из 3 человек, порог нужно поднять. Лучший PQL scoring бесполезен, если leads не обрабатываются вовремя.
Отсутствие feedback loop. Sales-менеджеры должны отмечать качество PQL в CRM (converted, not relevant, bad timing). Без обратной связи модель не улучшается. Минимальный feedback: бинарная оценка “полезный лид / не полезный” после каждого outreach.
Score без контекста. Число “82” ничего не говорит менеджеру. LLM-generated sales context превращает абстрактный score в actionable intelligence. Это не опция, а обязательный элемент.
Что дальше
PQL scoring — отправная точка. Следующие шаги:
- Predictive model. Заменить rule-based scoring на ML-модель (logistic regression или gradient boosting), обученную на исторических конверсиях. Rule-based работает на старте, ML масштабируется лучше.
- Real-time scoring. Перейти от batch (ежедневного) к stream processing. PQL score обновляется при каждом событии, sales получает уведомление в момент перехода пользователя в hot tier.
- In-product actions. Score управляет не только CRM, но и UX: paywall triggers, premium feature hints, персонализированный onboarding.
- Multi-touch attribution. Объединение PQL score с маркетинговыми touchpoints для полной картины customer journey.
PQL scoring model с LLM-обогащением собирается за 2-3 спринта. Первые результаты видны через 30 дней после запуска: sales-команда работает с меньшим количеством лидов, но конверсия каждого лида выше. Это суть Product-Led Growth: продукт сам квалифицирует покупателей.
Нужна помощь с PQL scoring? Я помогаю стартапам внедрять AI-решения и строить продукты — belov.works.
FAQ
Как организовать PQL scoring в B2B-продукте, где несколько пользователей от одной компании активны на бесплатном плане?
Агрегируйте на уровне домена компании, а не отдельного пользователя. Суммируйте или усредняйте scores всех пользователей с одного домена и добавляйте множитель за размер команды: пять активных пользователей с acme.com — более сильный сигнал, чем один пользователь с высоким индивидуальным score. SQL-паттерн: GROUP BY company_domain, и аккаунт используется как единица скоринга. Индивидуальные scores пользователей по-прежнему важны для персонализации sales briefing, но назначение тира должно отражать поведение на уровне аккаунта.
Какая минимальная версия PQL scoring, которую команда из двух человек может запустить за неделю?
Начните с одного бинарного правила: если пользователь выполнил не менее двух конкретных activation events за 14 дней И зарегистрирован с корпоративным доменом — флаг как PQL. Без весов, тиров и LLM-обогащения. Раз в неделю экспортируйте список в таблицу и звоните лично. Это даёт 80% ценности полноценной scoring-модели и требует одного дня на внедрение. Переходите к полному SQL-скорингу только после того, как подтвердите, что activation events действительно предсказывают конверсию в вашем продукте.
Как PQL scoring взаимодействует с self-serve и product-led sales — должен ли он применяться к обоим?
Да, но с разными выходными действиями. Для self-serve (пользователь конвертируется без контакта с sales) PQL scoring управляет in-product триггерами: какое upsell-сообщение показать, когда открыть pricing page, какую фичу разблокировать в trial. Для product-led sales (менеджер лично связывается) PQL scoring показывает, кому звонить и что говорить. Один и тот же базовый score управляет обоими сценариями — разница только в том, какое действие срабатывает при пересечении порога.