Розробка AI-системи персоналізації освітньої траєкторії
Студент записався на курс з машинного навчання, але замість 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. Для швидкої оцінки вашого сценарію просто опишіть платформу та проблеми. Ми проаналізуємо та запропонуємо оптимальну архітектуру — безкоштовно та без зобов'язань. Замовте дзвінок або напишіть на пошту.







