Реализация AI-персонализации контента на сайте

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.
Разработка и обслуживание любых видов сайтов:
Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Реализация AI-персонализации контента на сайте
Сложная
~2-4 недели
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1214
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    852
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1041
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    823
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    815

Реализация AI-персонализации контента на сайте

Персонализация — это показывать разным пользователям разный контент на одной странице: другой порядок блоков, другой заголовок, другой CTA, другие товары. AI здесь управляет выбором вариантов на основе профиля и контекста пользователя.

Уровни персонализации

Поверхностный — переменные в тексте (имя пользователя, город), динамические заголовки. Без ML.

Сегментный — контент для сегментов (новичок / опытный, B2B / B2C, регион). Правила на основе атрибутов.

Поведенческий — контент на основе истории действий: что просматривал, покупал, читал.

Предиктивный — AI предсказывает следующее действие и оптимизирует контент под конверсию.

Профиль пользователя

// Накопление профиля в real-time
class UserProfileManager {
  constructor(userId) {
    this.userId = userId;
    this.profileKey = `profile:${userId}`;
  }

  async trackEvent(event) {
    const updates = {};

    switch (event.type) {
      case 'page_view':
        updates[`categories.${event.category}`] = { increment: 1 };
        updates['total_sessions'] = { increment: 1 };
        break;
      case 'purchase':
        updates['purchases_count'] = { increment: 1 };
        updates['total_spent'] = { increment: event.amount };
        updates['last_purchase'] = event.timestamp;
        break;
      case 'content_read':
        updates['read_count'] = { increment: 1 };
        updates[`topics.${event.topic}`] = { increment: event.readTime };
        break;
    }

    await redis.hIncrBy(this.profileKey, updates);
    await redis.expire(this.profileKey, 86400 * 30); // 30 дней
  }

  async getProfile() {
    const raw = await redis.hGetAll(this.profileKey);
    return {
      topCategories: getTopN(raw.categories, 5),
      topTopics: getTopN(raw.topics, 5),
      purchasesCount: parseInt(raw.purchases_count || 0),
      totalSpent: parseFloat(raw.total_spent || 0),
      segment: this.classifySegment(raw),
    };
  }

  classifySegment(profile) {
    if (profile.purchases_count > 10) return 'loyal';
    if (profile.purchases_count > 0) return 'buyer';
    if (profile.total_sessions > 5) return 'engaged';
    return 'new';
  }
}

Персонализация главной страницы

// API endpoint для персонализированной главной
async function getHomepageContent(userId, context) {
  const profile = await getUserProfile(userId);
  const geo = context.country || 'RU';
  const device = context.device || 'desktop';

  // Параллельно получаем все блоки
  const [hero, featured, recommendations, cta] = await Promise.all([
    getPersonalizedHero(profile, geo),
    getFeaturedContent(profile.topCategories),
    getPersonalizedProducts(userId, profile, 8),
    getPersonalizedCTA(profile),
  ]);

  return { hero, featured, recommendations, cta };
}

async function getPersonalizedHero(profile, geo) {
  const variants = await getHeroVariants(); // A/B варианты из CMS

  // Правила выбора варианта
  if (profile.segment === 'loyal') {
    return variants.find(v => v.segment === 'loyal') || variants[0];
  }
  if (geo === 'BY') {
    return variants.find(v => v.geo === 'BY') || variants[0];
  }
  if (profile.topCategories.includes('sale')) {
    return variants.find(v => v.theme === 'deals') || variants[0];
  }

  return variants[0]; // default
}

LLM-генерация персонализированного текста

Для высокоценных пользователей — динамические заголовки и описания:

async function generatePersonalizedHeadline(product, userProfile) {
  const cacheKey = `headline:${product.id}:${userProfile.segment}`;
  const cached = await redis.get(cacheKey);
  if (cached) return cached;

  const prompt = `
Сгенерируй заголовок карточки товара (до 10 слов) для пользователя.
Товар: ${product.name}, категория: ${product.category}
Профиль: сегмент=${userProfile.segment}, интересы=${userProfile.topTopics.join(',')}
Тон: профессиональный, без клише.
Верни только текст заголовка.
`;

  const response = await openai.chat.completions.create({
    model: 'gpt-4o-mini',
    messages: [{ role: 'user', content: prompt }],
    max_tokens: 30,
    temperature: 0.7,
  });

  const headline = response.choices[0].message.content.trim();
  await redis.setex(cacheKey, 3600 * 6, headline); // кэш 6 часов

  return headline;
}

Динамические CTA

const CTA_VARIANTS = {
  new: {
    text: 'Начать бесплатно',
    subtext: 'Без кредитной карты',
    color: 'blue',
  },
  engaged: {
    text: 'Попробовать Pro',
    subtext: '14 дней бесплатно',
    color: 'green',
  },
  buyer: {
    text: 'Обновить план',
    subtext: 'Разблокируй все функции',
    color: 'purple',
  },
  loyal: {
    text: 'Реферальная программа',
    subtext: 'Заработай за каждого друга',
    color: 'orange',
  },
};

function PersonalizedCTA({ userId }) {
  const { profile } = useUserProfile(userId);
  const variant = CTA_VARIANTS[profile.segment] || CTA_VARIANTS.new;

  return (
    <button
      className={`cta-button cta-${variant.color}`}
      onClick={() => {
        trackCTAClick(userId, profile.segment);
        navigate(getCtaDestination(profile.segment));
      }}
    >
      {variant.text}
      <span>{variant.subtext}</span>
    </button>
  );
}

Контекстная персонализация (без авторизации)

Для анонимных пользователей — сигналы из текущей сессии:

function getContextualSignals(request) {
  return {
    referrer: request.headers.referer,         // откуда пришёл
    utm_source: request.query.utm_source,       // рекламный канал
    utm_campaign: request.query.utm_campaign,
    geo: request.headers['cf-ipcountry'],       // Cloudflare geo
    device: detectDevice(request.headers['user-agent']),
    timeOfDay: getTimeOfDay(request.headers['x-forwarded-for']),
    entryPage: request.url,
  };
}

function getPersonalizationForAnonymous(signals) {
  // Пришёл из рекламы "скидки" → показать sale-баннер
  if (signals.utm_campaign?.includes('sale')) {
    return { hero: 'sale', cta: 'discount' };
  }
  // Мобильный + вечер → показать app download
  if (signals.device === 'mobile' && signals.timeOfDay === 'evening') {
    return { hero: 'mobile-app', cta: 'download' };
  }
  // B2B сигнал из LinkedIn
  if (signals.referrer?.includes('linkedin')) {
    return { hero: 'b2b', cta: 'demo' };
  }

  return { hero: 'default', cta: 'default' };
}

Edge Personalization (Cloudflare Workers / Vercel Edge)

Для максимальной скорости — персонализация прямо на Edge, до Origin:

// Cloudflare Worker
export default {
  async fetch(request, env) {
    const url = new URL(request.url);
    const userId = getCookie(request, 'user_id');
    const segment = userId
      ? await env.KV.get(`segment:${userId}`)
      : 'anonymous';

    // Модифицируем запрос к Origin с сегментом
    const newRequest = new Request(request.url, {
      ...request,
      headers: {
        ...Object.fromEntries(request.headers),
        'X-User-Segment': segment || 'new',
        'X-User-Geo': request.cf.country,
      },
    });

    return fetch(newRequest);
  }
};

Измерение эффекта

-- Конверсия по сегментам и вариантам персонализации
SELECT
  p.variant,
  p.segment,
  COUNT(DISTINCT p.user_id) AS shown,
  COUNT(DISTINCT c.user_id) AS converted,
  ROUND(COUNT(DISTINCT c.user_id)::numeric / COUNT(DISTINCT p.user_id) * 100, 2) AS cvr
FROM personalization_events p
LEFT JOIN conversion_events c
  ON c.user_id = p.user_id
  AND c.created_at BETWEEN p.created_at AND p.created_at + INTERVAL '7 days'
WHERE p.created_at >= NOW() - INTERVAL '30 days'
GROUP BY p.variant, p.segment
ORDER BY cvr DESC;

Сроки

  • Сегментная персонализация (правила) — 3–4 дня
  • Поведенческий профиль + персонализация рекомендаций — плюс 3–4 дня
  • LLM-генерация динамических заголовков — плюс 2 дня
  • Edge персонализация на Cloudflare Workers — плюс 2 дня
  • Полная система с аналитикой, A/B, 5+ вариантами — 3–4 недели