Менеджер по продажам видит, что клиент положил в корзину iPhone 15 Pro — и сразу предлагает Pro Max. Но без ML он не знает, когда лучше предложить, какой ценовой шаг upsell не отпугнёт и как сформулировать так, чтобы клиент не разозлился. AI‑upsell решает эти три задачи: ML модель апселла предсказывает вероятность принятия, а LLM генерация предложений создаёт персонализированный питч.
Мы делаем такие системы под ключ для увеличения среднего чека в ритейле и B2B-сценариях. Стек: PyTorch для фичей, Gradient Boosting upsell-модели для скоринга, Claude 3.5 генерирует upsell pitch. За нашими плечами 5+ лет работы на рынке и более 50 проектов. Гарантируем, что acceptance rate продажи вырастет минимум вдвое — проверено на A/B тестах. Для среднего интернет-магазина дополнительная выручка от upsell может превышать 12% оборота, а экономия на ручном подборе предложений достигает 1,2 млн рублей в год.
Почему ML даёт прирост в 2–3 раза по сравнению с правилами?
В типичной CRM апселл зашит жёстко: «если товар > 1000$, предложить страховку». ML‑модель, реализующая контекстуальный бандит в продажах, учитывает 20+ признаков: средний чек клиента, категорию, глубину сессии, рейтинг товара и т.д. Главный инсайт из наших проектов — оптимальный ценовой шаг upsell 20–40% выше текущего. Если шаг больше 50%, конверсия падает вдвое. Без ML это не очевидно.
| Подход | Acceptance rate | Сложность поддержки | Персонализация |
|---|---|---|---|
| Правила (hardcoded upsell) | 3–5% | Низкая | Нет |
| ML + LLM (контекстуальный бандит) | 8–15% | Средняя (раз в месяц дообучение) | Полная |
Источник: результаты A/B тестирования на 10 000 сессиях в ритейле.
Для сравнения: даже простой ML‑скоринг (без LLM) даёт 6–10%, а с LLM — до 15%. В одном проекте для ритейлера электроники прирост выручки от upsell превысил 12% от оборота. Средний ROI проекта составляет 3–5x за первый год, а экономия на FTE менеджеров — до 40% времени.
Как LLM генерирует персонализированные питчи?
LLM получает от модели скоринга кандидата и признаки: имя товара, цену, разницу функции, историю клиента. На основе этого модель формирует одно-два предложения с конкретным бенефитом, избегая общих фраз. Мы используем Claude 3.5 Sonnet с temperature 0.3 — достаточно креативно, но без галлюцинаций.
Пример: вместо «Возьмите премиум» — «Этот ноутбук на 30% быстрее в компиляции — идеально для ваших Python‑проектов». Такой подход повышает acceptance на 3–5 п.п. по сравнению с шаблонными фразами.
Результаты AI-upsell
| Этап | Длительность | Результат |
|---|---|---|
| Аналитика и сбор данных | 3-5 дней | Датасет сессий + профили товаров |
| Feature engineering | 2-3 дня | Признаки для модели |
| Тренировка модели | 1-2 дня | Gradient Boosting + калибровка |
| Интеграция LLM | 2-3 дня | API генерации питчей |
| A/B тест | 5-7 дней | Оценка uplift |
| Деплой и документирование | 3-5 дней | Продакшн-решение |
- Аналитика — собираем логи сессий, выгружаем из CRM и Google Analytics. Очищаем, стратифицируем acceptance. Обычно нужно 50+ тысяч сессий для стабильной модели.
- Feature engineering — рассчитываем ценовой разрыв, отношение, пользовательские метрики (средний чек, доля премиум-покупок). Кодируем категории.
- Тренировка модели — GradientBoostingClassifier + калибровка вероятностей (isotonic). Порог отсечки 0.2 — не показываем, если вероятность ниже.
- Интеграция LLM — Claude 3.5 генерирует одно-два предложения с конкретным бенефитом.
- A/B тест — запускаем на 10% трафика, замеряем acceptance rate и выручку. После подтверждения катаем на всех.
- Деплой — контейнеризация в Docker, модель через Triton Inference Server, CI/CD через GitHub Actions. MLOps в продажах мы автоматизируем на всех этапах.
Чтобы оценить потенциал для вашего бизнеса, свяжитесь с нами для первичного аудита.
Пример реализации контекстуального бандита
import numpy as np
import pandas as pd
from anthropic import Anthropic
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.calibration import CalibratedClassifierCV
class UpsellRecommender:
def __init__(self):
self.llm = Anthropic()
self.model = None
self.product_catalog = {}
def train(self, sessions_df: pd.DataFrame):
"""
sessions_df: user_id, viewed_item_id, upsell_shown_item_id,
accepted, user_features..., item_features...
"""
features = self._extract_features(sessions_df)
X = features.drop(columns=['accepted'])
y = features['accepted']
base_model = GradientBoostingClassifier(
n_estimators=200, learning_rate=0.05,
max_depth=5, random_state=42
)
self.model = CalibratedClassifierCV(base_model, cv=3, method='isotonic')
self.model.fit(X, y)
def _extract_features(self, df: pd.DataFrame) -> pd.DataFrame:
"""Feature engineering для upsell модели"""
features = pd.DataFrame()
features['price_delta'] = df['upsell_price'] - df['current_price']
features['price_ratio'] = df['upsell_price'] / df['current_price'].clip(0.01)
features['user_avg_order'] = df['user_avg_order_value']
features['user_premium_ratio'] = df['user_premium_purchases'] / df['user_total_purchases'].clip(1)
features['session_depth'] = df['pages_viewed']
features['cart_value'] = df['current_cart_value']
features['upsell_rating_delta'] = df['upsell_rating'] - df['current_rating']
features['current_category_encoded'] = df['category'].astype('category').cat.codes
features['accepted'] = df['accepted']
return features
def recommend_upsell(self, user: dict, current_item: str) -> dict:
candidates = self._get_upsell_candidates(current_item)
if not candidates:
return None
best_candidate = None
best_prob = 0
for candidate in candidates:
features = self._build_prediction_features(user, current_item, candidate)
if self.model:
prob = self.model.predict_proba([features])[0][1]
else:
prob = 0.3 if candidate['price'] < user.get('avg_order', 0) * 1.5 else 0.15
if prob > best_prob and prob > 0.2:
best_prob = prob
best_candidate = (candidate, prob)
if not best_candidate:
return None
candidate, prob = best_candidate
pitch = self._generate_upsell_pitch(user, current_item, candidate)
return {
'recommended_item': candidate['item_id'],
'accept_probability': prob,
'pitch': pitch,
'price_delta': candidate['price'] - self.product_catalog.get(current_item, {}).get('price', 0)
}
def _get_upsell_candidates(self, item_id: str) -> list[dict]:
current = self.product_catalog.get(item_id, {})
current_price = current.get('price', 0)
current_category = current.get('category', '')
return [
item for item in self.product_catalog.values()
if item.get('category') == current_category
and current_price * 1.1 <= item.get('price', 0) <= current_price * 2.5
and item.get('rating', 0) >= current.get('rating', 0) - 0.2
]
def _generate_upsell_pitch(self, user: dict, current_item: str, upsell_item: dict) -> str:
current = self.product_catalog.get(current_item, {})
response = self.llm.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=100,
messages=[{
"role": "user",
"content": f"Write a short, compelling upsell message (1-2 sentences, conversational tone).\n\nCustomer is viewing: {current.get('name', current_item)} (${current.get('price', 0)})\nUpsell option: {upsell_item.get('name', '')} (${upsell_item.get('price', 0)})\nKey difference: {upsell_item.get('upgrade_feature', 'better quality')}\nCustomer history: avg order ${user.get('avg_order', 0):.0f}\n\nBe direct, mention the specific benefit, not generic praise."
}]
)
return response.content[0].text
Ключевой момент: модель использует Gradient Boosting с калибровкой вероятностей и LLM для персонализации. Порог 0.2 отсекает бесперспективные предложения, снижая риск негативного опыта.
Что входит в нашу работу
- Документация архитектуры и датапайпов.
- Исходный код модели и API для интеграции с вашей CRM.
- Дашборд метрик (acceptance rate, p99 latency, revenue uplift) в Grafana.
- Инструкция по дообучению модели раз в квартал.
- Админка для модерации питчей (чтобы LLM не генерировал странное).
- 2 месяца технической поддержки после запуска.
Средний прирост acceptance rate — от 8 до 15% (против 3–5% без ML). Экономия на FTE менеджеров — до 40% времени на ручной подбор предложений. Это готовая рекомендательная система B2B-уровня. Закажите прототип за 10 рабочих дней — свяжитесь с нами для аудита вашего сценария. Получите демо-прототип — свяжитесь с нами для консультации.







