Менеджер по продажам видит, что клиент положил в корзину 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% оборота, а экономия на ручном подборе предложений достигает $11k–16k в год.
Почему 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 рабочих дней — свяжитесь с нами для аудита вашего сценария. Получите демо-прототип — свяжитесь с нами для консультации.







