AI-система персонализации рекомендаций в автодилерах
Традиционный подход в автодилере: менеджер угадывает предпочтения клиента по первому разговору. AI-система анализирует историю поиска, финансовый профиль и поведение на сайте, предлагая автомобили с объяснением соответствия конкретным критериям клиента.
Персонализированный подбор автомобиля
import numpy as np
import pandas as pd
from anthropic import Anthropic
import json
class CarRecommendationEngine:
"""Рекомендации автомобилей под профиль покупателя"""
def __init__(self):
self.llm = Anthropic()
def build_buyer_profile(self, search_history: list[dict],
explicit_preferences: dict = None) -> dict:
"""Профиль покупателя из истории поиска"""
if not search_history:
return explicit_preferences or {}
# Анализ предпочтений из просматриваемых авто
viewed_cars = [s for s in search_history if s.get('action') == 'view_detail']
if not viewed_cars:
return explicit_preferences or {}
# Ценовой диапазон
prices = [c.get('price', 0) for c in viewed_cars if c.get('price')]
price_range = (min(prices), max(prices)) if prices else (0, float('inf'))
# Предпочитаемые типы кузова
bodies = pd.Series([c.get('body_type') for c in viewed_cars]).value_counts()
preferred_bodies = bodies.head(2).index.tolist()
# Бренд-предпочтения (если смотрит один бренд >40% времени)
brands = pd.Series([c.get('brand') for c in viewed_cars]).value_counts(normalize=True)
preferred_brands = brands[brands > 0.25].index.tolist()
# Тип топлива (по просмотрам)
fuels = pd.Series([c.get('fuel_type') for c in viewed_cars]).value_counts(normalize=True)
profile = {
'price_min': price_range[0] * 0.85,
'price_max': price_range[1] * 1.15,
'preferred_body_types': preferred_bodies,
'preferred_brands': preferred_brands,
'preferred_fuel': fuels.index[0] if len(fuels) > 0 else 'any',
'total_views': len(viewed_cars),
}
# Мёржим с явными предпочтениями
if explicit_preferences:
profile.update({k: v for k, v in explicit_preferences.items() if v})
return profile
def recommend_cars(self, buyer_profile: dict,
inventory: pd.DataFrame,
top_k: int = 5) -> list[dict]:
"""Топ автомобилей для покупателя"""
df = inventory.copy()
# Фильтр по бюджету
price_min = buyer_profile.get('price_min', 0)
price_max = buyer_profile.get('price_max', float('inf'))
df = df[(df['price'] >= price_min) & (df['price'] <= price_max)]
if df.empty:
return []
# Скоринг
scores = pd.Series(1.0, index=df.index)
# Тип кузова
preferred_bodies = buyer_profile.get('preferred_body_types', [])
if preferred_bodies:
scores += df['body_type'].isin(preferred_bodies).astype(float) * 0.3
# Бренд
preferred_brands = buyer_profile.get('preferred_brands', [])
if preferred_brands:
scores += df['brand'].isin(preferred_brands).astype(float) * 0.25
# Топливо
preferred_fuel = buyer_profile.get('preferred_fuel', 'any')
if preferred_fuel != 'any':
scores += (df.get('fuel_type', 'petrol') == preferred_fuel).astype(float) * 0.15
# Популярность (time on lot — чем дольше, тем ниже скор)
if 'days_in_inventory' in df.columns:
freshness = 1.0 - (df['days_in_inventory'] / 90).clip(0, 1)
scores += freshness * 0.1
# Маржа дилера (бизнес-интерес)
if 'dealer_margin' in df.columns:
margin_norm = (df['dealer_margin'] - df['dealer_margin'].min()) / (
df['dealer_margin'].max() - df['dealer_margin'].min() + 1e-9
)
scores += margin_norm * 0.20
df['score'] = scores
top_cars = df.nlargest(top_k, 'score').to_dict('records')
# Добавляем персонализированное объяснение
for car in top_cars:
car['match_explanation'] = self._explain_match(car, buyer_profile)
return top_cars
def _explain_match(self, car: dict, buyer_profile: dict) -> str:
"""Почему этот автомобиль подходит покупателю"""
reasons = []
if car.get('body_type') in buyer_profile.get('preferred_body_types', []):
reasons.append(f"кузов {car['body_type']}, который вас интересует")
if car.get('brand') in buyer_profile.get('preferred_brands', []):
reasons.append(f"предпочитаемый бренд {car['brand']}")
price_mid = (buyer_profile.get('price_min', 0) + buyer_profile.get('price_max', float('inf'))) / 2
if abs(car.get('price', 0) - price_mid) < price_mid * 0.15:
reasons.append("соответствует вашему ценовому диапазону")
if not reasons:
reasons.append("подбор по вашим критериям")
return "Подходит, потому что: " + ", ".join(reasons)
def generate_test_drive_proposal(self, car: dict,
buyer: dict) -> str:
"""Персонализированное предложение тест-драйва"""
response = self.llm.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=120,
messages=[{
"role": "user",
"content": f"""Write a personalized test drive invitation in Russian for an auto dealer.
Car: {car.get('year')} {car.get('brand')} {car.get('model')}, {car.get('price', 0):,.0f} руб.
Buyer's interests: {buyer.get('preferred_body_types', [])}
Key match: {car.get('match_explanation', '')}
2-3 sentences. Highlight 1 specific feature of this car that matches their profile. Include a clear call to action."""
}]
)
return response.content[0].text
AI-персонализация в автодилерах сокращает время подбора автомобиля на 30-45% и повышает test-drive conversion rate на 15-20%. Ключевой барьер внедрения — интеграция с DMS (Dealer Management System): данные об инвентаре должны обновляться в реальном времени.







