Решение: AI-агент рекомендаций (Trip Planner & Recommender)¶
Дата: 2026-03-25 Статус: Утверждено
1. Контекст¶
Туристы часто приходят с комплексными запросами, например: "Я буду в Архызе с 10 по 25 апреля. Найди лучшие варианты размещения, маршруты для туров и свободных инструкторов". Текущая система требует от пользователя вручную переходить по разным разделам (Отели, Туры, Инструкторы) и настраивать фильтры в каждом из них, что усложняет процесс планирования отдыха и снижает конверсию.
2. Проблема¶
Классический UI с фильтрами не справляется с мульти-доменными запросами на естественном языке. Пользователю нужен "единый консьерж", который не просто пообщается текстом, но и выдаст конкретные, доступные для бронирования предложения (карточки со ссылками) с учетом дат и других параметров.
3. Варианты решения¶
Вариант 1: Semantic Search (RAG) по всей базе¶
- Описание: Векторизация всех предложений и поиск по косинусному сходству.
- Плюсы: Легко реализовать, хорошо ищет по абстрактным описаниям ("тихое место", "красивый вид").
- Минусы: Векторный поиск плохо работает с жесткими фильтрами (даты заезда/выезда, точное наличие свободных мест, актуальные цены).
Вариант 2: LLM Agent с Function Calling (Tool Use)¶
- Описание: Использование LLM (например, OpenAI GPT-4o / Anthropic Claude) в режиме агента. Агент анализирует запрос, извлекает параметры (даты
2026-04-10-2026-04-25, локацияАрхыз, потребностиразмещение, туры, инструкторы) и вызывает внутренние инструменты (API платформы) для получения точных данных. - Плюсы: 100% актуальность цен и наличия мест. Агент возвращает структурированный ответ со ссылками и ID объектов, что позволяет фронтенду отрендерить красивые карточки предложений (виджеты).
- Минусы: Требует реализации промежуточного слоя (инструментов) на бэкенде.
4. Выбранный вариант¶
Вариант 2: LLM Agent с Function Calling. Это единственный надежный способ предоставить туристу реальные ссылки на доступные услуги, избежав галлюцинаций (когда ИИ придумывает несуществующие отели или свободные даты).
5. Архитектура и логика работы агента¶
5.1. Пайплайн обработки запроса¶
- User Input: Пользователь отправляет сообщение в чат.
- Intent & Entity Extraction (LLM): Агент понимает, что нужно искать 3 категории (Отели, Туры, Инструкторы) на даты 10-25 апреля.
- Tool Execution (Backend):
search_accommodations(check_in="2026-04-10", check_out="2026-04-25")search_tours(date_start="2026-04-10", date_end="2026-04-25")search_instructors(dates=["2026-04-10", ..., "2026-04-25"])
- Response Generation (LLM): Агент получает JSON с результатами из БД и формирует текстовый ответ, прикладывая к нему массив найденных объектов (Structured Output).
- Frontend Rendering: UI отображает текстовое сообщение от агента и под ним — карусель/список карточек отелей, туров и инструкторов с кнопками "Перейти" или "Забронировать".
5.2. Структура ответа (UI)¶
Ответ агента должен содержать:
* message: Текст ответа (например, "Я подобрал для вас отличные варианты на период с 10 по 25 апреля...").
* attachments: Массив объектов (ссылок/карточек), которые фронтенд отрендерит визуально.
6. API Методы для Stage Окружения¶
В соответствии с архитектурой stage.arkhyz-club.ru (проксируется на hotel_api_v2:8000), выносим следующие API-методы в FastAPI микросервис.
6.1. Эндпоинт взаимодействия с чатом¶
POST /api/v1/ai/chat
Описание: Основной метод для отправки сообщений агенту. Поддерживает историю контекста и возвращает текстовый ответ вместе с прикрепленными карточками (attachments).
Request (JSON):
{
"session_id": "uuid-сессии-чата",
"message": "я буду в архызе с 10 по 25 апреля - найди лушие варианты размешения и маршрутов для туров и свободных инстурктуоров",
"history": [
{"role": "user", "content": "Привет!"},
{"role": "assistant", "content": "Здравствуйте! Чем могу помочь?"}
]
}
Response (JSON):
{
"reply": "Отличный выбор дат! Конец апреля в Архызе — прекрасное время. Я проверил доступность и подобрал для вас несколько вариантов размещения, интересных туров и свободных инструкторов на эти даты.",
"attachments": {
"accommodations": [
{
"id": "acc-123",
"title": "Отель «Романтик»",
"url": "/hotels/acc-123",
"image_url": "https://cdn.arkhyz-club.ru/images/...",
"price_per_night": 7500,
"description": "Отличный отель в центре курорта."
}
],
"tours": [
{
"id": "tour-456",
"title": "Джип-тур к Софийским озерам",
"url": "/tours/tour-456",
"image_url": "https://cdn.arkhyz-club.ru/images/...",
"price": 3500,
"date": "2026-04-12"
}
],
"instructors": [
{
"id": "inst-789",
"title": "Иван Иванов",
"url": "/instructors/inst-789",
"image_url": "https://cdn.arkhyz-club.ru/images/...",
"specialization": "Горные лыжи / Фрирайд",
"available_slots": ["2026-04-11", "2026-04-15"]
}
]
}
}
6.2. Вспомогательный эндпоинт (Tool Endpoints - Internal)¶
Эти методы использует сам AI-агент под капотом (не для прямого вызова с фронтенда, но они должны быть реализованы на бэкенде).
GET /api/v1/internal/tools/search-accommodations?check_in=...&check_out=...GET /api/v1/internal/tools/search-tours?date_start=...&date_end=...GET /api/v1/internal/tools/search-instructors?dates=...
7. Последствия и риски¶
- Сложность промпта: Потребуется точная настройка System Prompt, чтобы агент не пытался угадывать цены, а строго опирался на данные из Tools.
- Latency (Задержка): Вызов LLM + выполнение 3-х внутренних запросов (жилье, туры, инструкторы) может занять 3-7 секунд. Потребуется реализовать Streaming UI (печатающийся текст) на фронтенде, пока грузятся карточки.
- Контекст сессии: Необходимо хранить историю чата в Redis или БД, чтобы агент помнил даты, если пользователь уточнит: "А теперь найди бани на эти же даты".
8. Связанные задачи¶
- [[docs/10_задачи/roadmap]] - добавить задачу на реализацию Function Calling в
hotel_api_v2. - [[docs/07_frontend/frontend]] - разработать компоненты виджетов для рендеринга
attachmentsв интерфейсе чата. - [[docs/05_архитектура/архитектура]] - обновить схему потоков данных для AI-модуля.