AI-система Upsell-рекомендацій: підвищуємо середній чек
Менеджер з продажу бачить, що клієнт поклав у кошик 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% обороту.
Чому 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 робочих днів — зв'яжіться з нами для аудиту вашого сценарію. Отримайте демо-прототип — зв'яжіться з нами для консультації.







