Идея и мотивация
Длительное время работа в качестве бекенд‑инженера совмещалась с активным использованием системы интервального повторения Anki. Привычка регулярно обновлять набор карточек и поддерживать их актуальность оказалась трудоёмкой: генерация новых вопросов требовала усилий, а дисциплина в ежедневных повторениях часто сдавалась под натиском работы. Когда в экосистеме стали доступны автономные AI‑агенты, возникла возможность автоматизировать процесс создания и доставки обучающих материалов. Цель проекта — построить сервис, который генерирует качественные флеш‑карты, доставляет их пользователю по расписанию и предлагает интерактивный AI‑тренер для уточнения тем.
Архитектура решения
Система построена на микросервисной основе, где каждый компонент отвечает за отдельный этап конвейера:
- API‑gateway (Node.js + Fastify) принимает запросы от клиентских приложений (веб‑интерфейс, Telegram‑бот) и распределяет их между сервисами.
- Сервис генерации карточек реализован на Python, использует LLM‑модель (например, GPT‑4) через OpenAI API. Входные данные — тема, уровень сложности, формат вопросов. Выход — набор пар «вопрос‑ответ», дополненный метаданными (теги, уровень сложности, ссылка на источник).
- Хранилище — PostgreSQL для структурированных данных (пользователи, карточки, расписания) и Redis для кэширования часто запрашиваемых наборов.
- Планировщик задач (Celery + RabbitMQ) отвечает за отправку карточек в указанные пользователем интервалы. Задачи формируются на основе алгоритма интервального повторения (SM‑2), адаптированного под особенности AI‑генерируемого контента.
- Telegram‑бот (Python‑aiogram) реализует пользовательский интерфейс: подписка, настройка расписания, запросы к AI‑тренеру. Бот получает готовые карточки из планировщика и отправляет их в виде интерактивных сообщений с кнопками «Узнать ответ», «Отложить», «Сложно».
- AI‑тренер — отдельный микросервис, использующий тот же LLM, но в режиме диалога. Пользователь может задать уточняющий вопрос по карточке, а сервис генерирует развернутый ответ, примеры и ссылки.
Все сервисы упакованы в Docker‑контейнеры, оркестрация осуществляется Kubernetes. CI/CD настроен через GitHub Actions: автоматические тесты, статический анализ кода (flake8, eslint), сборка образов и деплой в staging‑окружение.
Роль AI‑агентов в генерации карточек
Ключевой элемент — модель языкового генератора, обученная на больших корпусах учебных материалов. Для получения релевантных вопросов применяется цепочка запросов:
- Контекстуализация: пользователь указывает тему (например, «асинхронное программирование в Python») и желаемый уровень (начальный, средний, продвинутый). Система формирует промпт, включающий примеры карточек из аналогичных тем.
- Фильтрация: полученный набор вопросов проходит через вспомогательный скрипт, проверяющий уникальность, отсутствие фактических ошибок и соответствие формату (короткий вопрос, однозначный ответ).
- Обогащение: к каждому ответу добавляются пояснения, ссылки на официальную документацию и примеры кода. Это повышает ценность карточки и облегчает последующее повторение.
Для снижения стоимости запросов к LLM используется кэширование уже сгенерированных наборов в Redis и периодическое переиспользование при схожих темах.
Интеграция с Telegram и планировщик
Telegram выбран в качестве канала доставки из‑за широкой пользовательской базы и удобных средств интерактивного общения. Бот реализует два основных режима:
- Режим «карточка дня»: в заданное время пользователь получает одну карточку с кнопкой «Показать ответ». После раскрытия ответа бот автоматически записывает результат в базу (правильно/неправильно) и корректирует интервал повторения.
- Режим «тренажёр»: пользователь может запросить набор карточек за выбранный период (например, «все карточки за последнюю неделю») и пройти их в произвольном порядке. При затруднении бот предлагает вызвать AI‑тренера.
Планировщик формирует задачи на основе алгоритма SM‑2, который учитывает историю ответов и адаптирует интервалы. Задачи ставятся в очередь Celery, где воркеры распределяют их по времени отправки, гарантируя точность расписания даже при больших нагрузках.
Переход от прототипа к SaaS
Первоначальный прототип представлял собой простого Telegram‑бота, генерирующего карточки по запросу. При масштабировании возникли требования к:
- Мульти‑тенантности: каждая организация (компания, учебное заведение) получает отдельный namespace в базе, что позволяет изолировать данные и задавать индивидуальные тарифы.
- Биллинг‑модели: интегрирован Stripe для подписки, где базовый план включает ограниченное количество генераций карточек в месяц, а премиум‑уровень открывает неограниченный доступ и приоритетную очередь генерации.
- Мониторинг и логирование: Prometheus собирает метрики нагрузки, а Grafana визуализирует их в реальном времени. Логи отправляются в ELK‑стек для быстрого обнаружения аномалий.
Для обеспечения высокой доступности сервис развернут в двух облачных регионах с автоматическим переключением трафика через глобальный балансировщик. Репликация PostgreSQL и резервные копии Redis позволяют восстанавливать состояние при сбоях.
Трудности и решения
Качество генерируемого контента
AI‑модели иногда создавали «правильные» ответы, но с ошибками в деталях. Было решено внедрить пост‑обработку с использованием проверочных скриптов, сравнивающих ответы с официальными источниками (например, документацией Python). При обнаружении несоответствия карточка помечается как «на доработку» и отображается в отдельной очереди для ручного контроля.
Стоимость запросов к LLM
При росте числа пользователей расходы на API OpenAI резко возросли. Для оптимизации был разработан гибридный подход: базовые карточки генерируются локальной открытой моделью (LLaMA 7B), а сложные запросы (требующие глубокой экспертизы) направляются к платному сервису. Это позволило сократить затраты без заметного ухудшения качества.
Управление расписанием
Интервальный алгоритм требовал точного тайминга, но в реальном мире задачи могут задерживаться из‑за сетевых сбоев. Внедрена система «отложенных повторений», где при недоставке сообщения бот автоматически переназначает задачу на ближайший доступный слот, сохраняя логику интервала.
Пользовательский опыт
Первоначальный UI в Telegram оказался перегруженным. Было проведено A/B‑тестирование разных наборов кнопок и форматов сообщений. Оптимальным оказался компактный шаблон карточки с одной кнопкой «Ответ», а дополнительный контекст предоставлялся в виде раскрывающегося блока.
Проект демонстрирует, как современные AI‑агенты могут стать ядром SaaS‑продукта, автоматизируя создание обучающего контента и повышая эффективность персонального обучения. Тщательная проработка архитектуры, гибкая система биллинга и постоянный контроль качества позволяют превратить экспериментальный прототип в надёжный сервис, готовый к масштабированию.