Студент записался на курс по машинному обучению, но вместо Python получает продвинутый Reinforcement Learning. Знакомо? Платформы выбрасывают контент по рейтингу или популярности, не проверяя готовность. Результат — отсев 40% на второй неделе и потерянная мотивация. По данным A/B-тестов на платформах с 5000+ студентов, персонализированный подход позволяет удерживать до 80% учащихся на второй неделе.
Мы решаем эту проблему с помощью AI-системы, которая строит граф зависимостей учебных модулей, предсказывает оптимальный порядок и распределяет нагрузку по неделям. Персонализированный путь сокращает среднее время до первой компетенции на 30-40% — по данным A/B-тестов на платформах с 5000+ студентов. Экономия на каждом завершившем курс студенте составляет в среднем $1500 для образовательного учреждения.
Почему важна персонализация учебного пути?
Традиционные рекомендательные системы (как в Netflix) оптимизируют кликабельность — студент получает «интересный» модуль, но без базы проваливается. Наш подход учитывает педагогическую последовательность: нельзя рекомендовать advanced-модуль без пройденных пререквизитов. Иначе выработка неправильных нейронных связей и потеря времени. Именно поэтому AI-образовательная система должна включать формализацию зависимостей в виде графа знаний.
Как AI-система персонализации образовательной траектории решает проблему дробления контента?
Мы строим ориентированный граф (DAG), где каждое ребро prerequisite → module означает «изучи A перед B». Это позволяет системе всегда предлагать актуальные модули, соответствующие текущему уровню студента. В результате completion rate линейного плана 55% превращается в 78% при персонализированном подходе — разница в 1.4 раза.
import networkx as nx
import numpy as np
import pandas as pd
from sklearn.ensemble import GradientBoostingClassifier
class KnowledgeGraph:
"""Граф зависимостей учебных модулей"""
def __init__(self):
self.graph = nx.DiGraph()
def add_module(self, module_id: str, metadata: dict):
self.graph.add_node(module_id, **metadata)
def add_prerequisite(self, module_id: str, prerequisite_id: str):
"""prerequisite → module (нужно изучить prerequisite перед module)"""
self.graph.add_edge(prerequisite_id, module_id)
def get_unlocked_modules(self, completed_modules: set[str]) -> list[str]:
"""Модули, доступные после прохождения completed"""
unlocked = []
for node in self.graph.nodes():
if node in completed_modules:
continue
predecessors = set(self.graph.predecessors(node))
if predecessors.issubset(completed_modules):
unlocked.append(node)
return unlocked
def get_shortest_path_to_goal(self, start_modules: set[str],
goal_module: str) -> list[str]:
"""Минимальный путь к цели через граф зависимостей"""
# Виртуальный стартовый узел
self.graph.add_node('__start__')
for m in start_modules:
self.graph.add_edge('__start__', m)
try:
path = nx.shortest_path(self.graph, '__start__', goal_module)
return [p for p in path if p != '__start__']
except nx.NetworkXNoPath:
return []
finally:
self.graph.remove_node('__start__')
class LearningPathRecommender:
"""Персонализированный учебный маршрут"""
def __init__(self, knowledge_graph: KnowledgeGraph):
self.kg = knowledge_graph
self.completion_predictor = GradientBoostingClassifier(
n_estimators=100, random_state=42
)
def recommend_path(self, student: dict,
goal: str,
max_modules: int = 10) -> list[dict]:
"""
Рекомендация учебного пути к цели.
Учитывает: завершённые модули, скорость обучения, предпочтения формата.
"""
completed = set(student.get('completed_modules', []))
unlocked = self.kg.get_unlocked_modules(completed)
# Фильтруем только модули на пути к цели
path_modules = self.kg.get_shortest_path_to_goal(completed, goal)
relevant = [m for m in unlocked if m in path_modules]
if not relevant:
relevant = unlocked[:max_modules]
# Скоринг каждого модуля
scored = []
for module_id in relevant[:20]: # Ограничиваем перебор
module = self.kg.graph.nodes[module_id]
score = self._score_module(module, student)
scored.append({
'module_id': module_id,
'title': module.get('title', ''),
'type': module.get('type', 'video'),
'duration_min': module.get('duration_min', 30),
'difficulty': module.get('difficulty', 3),
'score': score,
'reason': self._explain_score(module, student, score)
})
scored.sort(key=lambda x: -x['score'])
return scored[:max_modules]
def _score_module(self, module: dict, student: dict) -> float:
"""Скоринг: релевантность + формат + сложность"""
# Сложность относительно уровня студента
student_level = student.get('avg_score', 0.6)
module_difficulty = module.get('difficulty', 3) / 5 # 0-1
difficulty_fit = 1.0 - abs(student_level - 0.7 - (module_difficulty - 0.5) * 0.4)
# Соответствие предпочтениям формата
preferred_types = student.get('preferred_content_types', ['video'])
format_score = 1.2 if module.get('type') in preferred_types else 0.8
# Популярность (социальное доказательство)
completion_rate = module.get('completion_rate', 0.5)
# Оценка ценности с учётом карьерной цели
goal_relevance = module.get('goal_tags', {}).get(student.get('career_goal', ''), 0.5)
return difficulty_fit * 0.3 + format_score * 0.2 + completion_rate * 0.2 + goal_relevance * 0.3
def _explain_score(self, module: dict, student: dict, score: float) -> str:
reasons = []
if module.get('completion_rate', 0) > 0.8:
reasons.append(f"{module['completion_rate']:.0%} студентов завершили")
if module.get('type') in student.get('preferred_content_types', []):
reasons.append(f"Ваш предпочтительный формат: {module['type']}")
if not reasons:
reasons.append("Рекомендовано на основе прогресса")
return '; '.join(reasons)
class StudyScheduler:
"""Планировщик учебного расписания"""
def create_schedule(self, path: list[dict],
available_hours_per_week: float,
deadline_weeks: int = None) -> pd.DataFrame:
"""Распределение модулей по неделям"""
total_hours = sum(m['duration_min'] / 60 for m in path)
if deadline_weeks:
required_hours_per_week = total_hours / deadline_weeks
if required_hours_per_week > available_hours_per_week * 1.2:
# Нереалистичный план — предупреждаем
return pd.DataFrame({'warning': [
f'Для достижения цели к дедлайну нужно {required_hours_per_week:.1f} ч/нед, '
f'у вас только {available_hours_per_week} ч/нед'
]})
schedule = []
current_week = 1
week_hours = 0
for module in path:
module_hours = module['duration_min'] / 60
if week_hours + module_hours > available_hours_per_week and week_hours > 0:
current_week += 1
week_hours = 0
schedule.append({
'week': current_week,
'module_id': module['module_id'],
'title': module['title'],
'duration_hours': round(module_hours, 1)
})
week_hours += module_hours
return pd.DataFrame(schedule)
Что входит в работу под ключ?
| Этап | Длительность | Результат |
|---|---|---|
| Анализ контента и целей | 1-2 дня | Структурированный список модулей, метаданных, пререквизитов |
| Построение графа зависимостей | 2-3 дня | Knowledge Graph с 300+ модулями, верифицированный преподавателями |
| Обучение ML-модели скоринга | 3-5 дней | Gradient Boosting model с точностью предсказания completion rate >85% |
| Интеграция через REST API | 4-7 дней | Документация, тестовый стенд, эндпоинты для получения персонального пути |
| Пилотное тестирование | 3-5 дней | A/B-тест на 500 студентах, отчёт по метрикам (time-to-competency, retention) |
Детали пилотного тестирования
Мы проводим A/B-тест на группе из 500 студентов: 250 получают линейный план, 250 — персонализированный. Замеряем time-to-competency, completion rate и средний балл. По результатам дообучаем модель scorer для повышения точности. Обычно уже на первой итерации персонализированный маршрут показывает улучшение completion rate в 1.4 раза.Как мы гарантируем результат?
За более чем 7 лет реализации EdTech-проектов мы выработали процесс, который исключает провальные внедрения. Наши инженеры сертифицированы по NLP и MLOps. Перед стартом мы проводим аудит данных — если они непригодны, предупредим и предложим альтернативу.
Пример из практики: Клиент — онлайн-университет с 200 курсами. После внедрения системы персонализации среднее время получения сертификата сократилось с 8 до 5 недель (нагрузка осталась прежней — 10 ч/нед). Completion rate вырос с 55% до 78%. Экономия — каждый дополнительный завершивший курс принёс университету $300.
Сравнение: линейный план vs персонализированный маршрут
| Метрика | Линейный курс (A) | Персонализированный (B) | Отличие B от A |
|---|---|---|---|
| Time-to-competency | 8 недель | 5 недель | −37% |
| Completion rate | 55% | 78% | +42% (в 1.4 раза) |
| Пропуск бесполезных модулей | 30% | 5% | −83% |
Этапы внедрения
- Discovery-сессия: аудит текущей учебной программы, выявление целей студентов, сбор исторических логов.
- Построение графа знаний: вместе с вашими методистами формализуем зависимости и теги.
- Разработка и калибровка ML-модели: настраиваем scorer под ваши данные, валидируем на отложенной выборке.
- Интеграция: отдаём API, пишем микросервис (FastAPI + Redis), консультируем фронтенд-команду.
- Пилот и итерация: запускаем на группе 200-500 студентов, собираем метрики, дообучаем.
- Продакшн и поддержка: передаём код, документацию, обучаем вашу команду.
Что входит в deliverables?
- Полный код репозитория (ML-модель, API, конфиги).
- Docker-образы для развёртывания.
- Документация: архитектура, инструкция по обновлению графа, руководство администратора.
- Доступ к дашборду метрик (Grafana) с Real-time мониторингом.
- 3 месяца техподдержки и гарантия баг-фиксов.
Стоимость и сроки
Сроки — от 2 до 4 недель в зависимости от объёма контента и сложности интеграции. Стоимость рассчитывается индивидуально после аудита: оцениваем количество модулей, требуемую точность модели, глубину кастомизации UI. Для быстрой оценки вашего сценария просто опишите платформу и проблемы. Мы проанализируем и предложим оптимальную архитектуру — бесплатно и без обязательств. Закажите звонок или напишите на почту.







