Почему рекомендации Netflix такие предсказуемые (и как это исправить)
Современные стриминги кидают вам один и тот же набор фильмов. Вы посмотрели "Довод"? Вот вам весь Нолан. Посмотрели один сериал Marvel? Добро пожаловать в ловушку супергероев.
Проблема старых рекомендательных систем в их слепоте. Они видят только цифры: жанр, рейтинг, просмотры. Они не понимают контекст, настроение, тонкие нюансы. Хотите меланхоличную научную фантастику с философским подтекстом? Система предложит "Звездные войны" — потому что там тоже космос.
Архитектура агента, который понимает больше вашего друга-киномана
Наш агент не один большой LLM. Это система из четырех специализированных компонентов, работающих по принципу суб-агентов.
| Компонент | Модель/Технология | Зачем нужен |
|---|---|---|
| Оркестратор диалога | Amazon Nova Sonic 2.0 | Управляет разговором, понимает интенты, решает, какой суб-агент вызывать |
| Семантический поиск | Amazon Titan Embeddings + OpenSearch | Находит фильмы по описанию настроения, а не по тегам |
| Анализ профиля | Коллаборативная фильтрация (SageMaker) | Строит классические рекомендации на основе истории просмотров |
| Генерация объяснений | Claude 3.7 Sonnet | Объясняет, почему рекомендует именно этот фильм, связывает с вашими предпочтениями |
Все это работает на Amazon Bedrock AgentCore — платформе, которая из коробки умеет вызывать функции, управлять контекстом и обрабатывать многошаговые диалоги. Не нужно писать тонны glue-кода.
Ключевой нюанс: Nova Sonic 2.0 (выпущена в начале 2026) специально заточена под управление агентами. Она на 40% лучше понимает, когда нужно вызывать инструменты, чем предыдущие версии. Не пытайтесь использовать для этого обычные LLM — потратите месяцы на дообучение.
1 Готовим данные: не просто база фильмов, а энциклопедия настроений
Большинство падает на этом этапе. Берут готовый датасет MovieLens с оценками и думают, что этого достаточно. Недостаточно.
Нужны векторные эмбеддинги описаний, сюжетов, рецензий. Берем Amazon Titan Embeddings модель последней версии (на март 2026 это v2.1 с контекстом 8000 токенов) и пропускаем через нее синопсисы.
import boto3
import json
from typing import List
bedrock = boto3.client('bedrock-runtime', region_name='us-east-1')
def get_embeddings(texts: List[str]) -> List[List[float]]:
body = json.dumps({
"inputTexts": texts,
"embeddingConfig": {
"outputEmbeddingLength": 1024 # Оптимально для поиска
}
})
response = bedrock.invoke_model(
modelId='amazon.titan-embed-text-v2:1',
body=body
)
result = json.loads(response['body'].read())
return result['embeddings']
# Пример для одного фильма
synopsis = "Фильм о кибернетическом детективе в будущем Токио, расследующем серию загадочных убийств, связанных с виртуальной реальностью."
embedding = get_embeddings([synopsis])[0]
Эти векторы сохраняем в OpenSearch с гибридным индексом. Почему гибридный? Потому что вместе с векторным поиском нужно оставить и традиционные фильтры по году, жанру, рейтингу. Иначе агент будет рекомендовать вам черно-белое немое кино, когда вы просите "что-то современное".
2 Создаем агента в Bedrock AgentCore: инструкции важнее кода
Здесь большинство совершает критическую ошибку: пишут слишком общие инструкции. "Ты помощник по рекомендациям фильмов" — это ничего не значит для LLM.
Правильная инструкция выглядит так:
Ты кинокритик-консультант с 20-летним стажем. Твоя задача — не просто назвать фильм, а понять настроение пользователя.
ПРАВИЛА:
1. Всегда уточняй контекст. Если пользователь говорит "хочу что-то легкое", спроси: "Легкое как комедия или как красивая драма без тяжелых сцен?"
2. Никогда не рекомендую больше 3 фильмов за раз.
3. Для каждого фильма объясняю ОДНОЙ фразой, почему он подходит именно этому пользователю.
4. Если пользователь спрашивает про актеров или режиссеров — сначала проверяю факты через инструмент поиска.
5. Не выдумываю фильмы. Если не уверен — говорю "не помню такой фильм, давайте поищем другой".
СТРУКТУРА ДИАЛОГА:
1. Уточнение запроса (1-2 вопроса)
2. Поиск вариантов (использую инструменты)
3. Предложение 2-3 фильмов с пояснениями
4. Уточнение, подходит ли вариант
Эти инструкции загружаем в Agent Console. Используем шаблон FAST для быстрого старта — он уже включает базовую настройку Lambda функций и API Gateway.
3 Настраиваем инструменты: поиск, который понимает абстракции
Инструменты в AgentCore — это функции, которые агент может вызывать. Нам нужно три основных:
- semantic_movie_search: векторный поиск по описанию настроения
- collaborative_recommendations: рекомендации на основе похожих пользователей
- get_movie_details: получение точных данных (год, режиссер, актеры)
Самое интересное — первый инструмент. Его схема выглядит так:
{
"name": "semantic_movie_search",
"description": "Ищет фильмы по описанию настроения, атмосферы или эмоций. НЕ использует жанры или названия.",
"inputSchema": {
"json": {
"type": "object",
"properties": {
"mood_description": {
"type": "string",
"description": "Описание настроения: 'меланхоличный осенний вечер в большом городе' или 'энергичная музыкальная комедия с танцами'"
},
"avoid_genres": {
"type": "array",
"items": {
"type": "string"
},
"description": "Жанры, которые нужно исключить"
}
},
"required": ["mood_description"]
}
}
}
Когда пользователь говорит "Хочу что-то меланхоличное про одиночество в большом городе", агент преобразует это в вектор через ту же Titan Embeddings, ищет ближайшие синопсисы в OpenSearch и возвращает варианты.
Важно: настройте ограничение на количество вызовов инструментов. Nova Sonic 2.0 иногда увлекается и делает 5-6 поисковых запросов для одного вопроса. Ставьте лимит 3 вызова на один turn диалога.
Тонкая настройка: почему ваш агент глупеет через неделю
Собрали агента, он работает. Довольные пользователи начинают с ним общаться. И через 7-10 дней качество рекомендаций падает.
Проблема в дрейфе контекста. AgentCore сохраняет историю диалогов, и со временем в контекст попадает слишком много информации. LLM начинает учитывать не только последний запрос, а весь мешанину из прошлых разговоров.
Решение:
- Включайте очистку контекста каждые 10 сообщений
- Создайте отдельный инструмент save_preferences, который выносит ключевые данные пользователя (любимые жанры, актеров, режиссеров) в отдельную базу
- При старте нового диалога загружайте эти предпочтения обратно в контекст
Это похоже на то, как работает Catalog AI от Amazon — система постоянно обновляет профиль пользователя на основе взаимодействий.
Мониторинг и улучшения: смотрите не на метрики, а на диалоги
Типичная ошибка: отслеживаете только Accuracy@10 или CTR рекомендаций. Это бесполезно для агентной системы.
Нужно смотреть на:
- Коэффициент уточняющих вопросов: сколько раз агент спрашивает уточнения перед рекомендацией. Идеально — 1-2 раза
- Длину успешного диалога: сколько сообщений проходит пользователь до выбора фильма
- Процент возвратов: как часто пользователи возвращаются к агенту после просмотра рекомендованного фильма
Установите CloudWatch Logs Insights для анализа диалогов. Ищите паттерны:
fields @timestamp, @message
| filter @message like /"function_call": "semantic_movie_search"/
| stats count(*) as search_calls by bin(5m)
| sort @timestamp desc
Самый частый баг: агент игнорирует инструменты и начинает выдумывать фильмы. Это происходит, когда в инструкциях нет четкого запрета на галлюцинации. Добавьте фразу: "Если не нашел фильм через инструменты — говори 'не нашел подходящего, давайте уточним запрос' НЕ ПРИДУМЫВАЙ".
Чего ждать дальше: когда агенты заменят кинокритиков
Текущие системы уже понимают запросы вроде "порекомендуй что-то похожее на первые сезоны 'Игры престолов', но без фэнтези". Через год они смогут анализировать ваш текущий настрой по камере (серьезно, Alexa+ уже тестирует это) и предлагать фильм под ваше сегодняшнее состояние.
Следующий шаг — интеграция с продакшн-студиями. Представьте агента, который не только рекомендует фильмы, но и помогает создателям тестировать концепции. Это уже происходит в экспериментах Amazon с ИИ-студией.
Главный совет: не пытайтесь сделать агента, который знает всё. Лучше узкий специалист по криминальным драмам 90-х, чем всезнайка, который путает Бергмана с Бёртом Рейнолдсом.