AI Agent for Online Course Platforms: Student Onboarding, Progress Tracking, and Support
Create an AI agent for online learning platforms that handles student onboarding, monitors progress, detects when learners are stuck, and provides targeted help resources.
The Online Learning Retention Problem
Online course platforms face a brutal completion rate problem — typically 5-15% of enrolled students finish a course. The primary reasons are not content quality but lack of personalized support: students get stuck, lose motivation, or do not know where to find help. An AI agent can dramatically improve retention by providing proactive, personalized support at the moments that matter most.
Learning Platform Data Model
from dataclasses import dataclass, field
from enum import Enum
from datetime import datetime, timedelta
from typing import Optional
class ModuleStatus(Enum):
NOT_STARTED = "not_started"
IN_PROGRESS = "in_progress"
COMPLETED = "completed"
SKIPPED = "skipped"
class LearnerRisk(Enum):
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
CHURNED = "churned"
@dataclass
class CourseModule:
module_id: str
title: str
order: int
estimated_minutes: int
content_type: str # video, reading, exercise, quiz, project
prerequisites: list[str] = field(default_factory=list)
help_resources: list[dict] = field(default_factory=list)
@dataclass
class ModuleProgress:
module_id: str
status: ModuleStatus = ModuleStatus.NOT_STARTED
started_at: Optional[datetime] = None
completed_at: Optional[datetime] = None
time_spent_minutes: int = 0
attempts: int = 0
score: Optional[float] = None
last_activity: Optional[datetime] = None
@dataclass
class LearnerProfile:
learner_id: str
name: str
email: str
enrolled_courses: list[str] = field(default_factory=list)
experience_level: str = "beginner"
learning_goals: list[str] = field(default_factory=list)
preferred_pace: str = "self_paced"
timezone: str = "UTC"
@dataclass
class CourseEnrollment:
learner_id: str
course_id: str
enrolled_at: datetime
module_progress: dict[str, ModuleProgress] = field(
default_factory=dict
)
last_active: Optional[datetime] = None
completion_percentage: float = 0.0
@dataclass
class Course:
course_id: str
title: str
description: str
modules: list[CourseModule] = field(default_factory=list)
estimated_hours: float = 0.0
difficulty: str = "beginner"
category: str = ""
Stuck Detection and Risk Scoring
The most valuable feature of a learning platform agent is detecting when students are struggling before they drop out.
COURSES: dict[str, Course] = {}
ENROLLMENTS: dict[str, CourseEnrollment] = {}
LEARNERS: dict[str, LearnerProfile] = {}
def detect_stuck_learners(course_id: str) -> list[dict]:
stuck_learners = []
now = datetime.now()
for key, enrollment in ENROLLMENTS.items():
if enrollment.course_id != course_id:
continue
learner = LEARNERS.get(enrollment.learner_id)
if not learner:
continue
# Check for inactivity
days_inactive = 0
if enrollment.last_active:
days_inactive = (now - enrollment.last_active).days
# Check for repeated failures
struggling_modules = []
for mod_id, progress in enrollment.module_progress.items():
if progress.attempts >= 3 and progress.status != ModuleStatus.COMPLETED:
struggling_modules.append(mod_id)
if (progress.status == ModuleStatus.IN_PROGRESS
and progress.time_spent_minutes > 120
and progress.score is not None
and progress.score < 60):
struggling_modules.append(mod_id)
# Calculate risk level
risk = LearnerRisk.LOW
if days_inactive > 14 or len(struggling_modules) >= 2:
risk = LearnerRisk.HIGH
elif days_inactive > 7 or len(struggling_modules) >= 1:
risk = LearnerRisk.MEDIUM
if days_inactive > 30:
risk = LearnerRisk.CHURNED
if risk in (LearnerRisk.MEDIUM, LearnerRisk.HIGH, LearnerRisk.CHURNED):
stuck_learners.append({
"learner_id": enrollment.learner_id,
"learner_name": learner.name,
"risk_level": risk.value,
"days_inactive": days_inactive,
"completion": enrollment.completion_percentage,
"struggling_modules": struggling_modules,
"intervention": _suggest_intervention(
risk, days_inactive, struggling_modules
),
})
return stuck_learners
def _suggest_intervention(
risk: LearnerRisk,
days_inactive: int,
struggling_modules: list[str],
) -> str:
if risk == LearnerRisk.CHURNED:
return "Send re-engagement email with course highlights."
if risk == LearnerRisk.HIGH:
if struggling_modules:
return "Offer 1-on-1 tutoring or alternative resources."
return "Send personalized check-in and progress summary."
if risk == LearnerRisk.MEDIUM:
return "Send encouragement with next milestone preview."
return "No intervention needed."
Agent Tools
from agents import Agent, function_tool, Runner
import json
@function_tool
def get_learner_progress(
learner_id: str, course_id: str
) -> str:
"""Get detailed progress for a learner in a course."""
enrollment_key = f"{learner_id}_{course_id}"
enrollment = ENROLLMENTS.get(enrollment_key)
if not enrollment:
return "Enrollment not found."
course = COURSES.get(course_id)
if not course:
return "Course not found."
module_details = []
for module in course.modules:
progress = enrollment.module_progress.get(module.module_id)
module_details.append({
"module": module.title,
"status": (
progress.status.value if progress
else "not_started"
),
"time_spent": (
progress.time_spent_minutes if progress else 0
),
"score": progress.score if progress else None,
"content_type": module.content_type,
})
return json.dumps({
"learner_id": learner_id,
"course": course.title,
"completion": enrollment.completion_percentage,
"modules": module_details,
"last_active": (
enrollment.last_active.isoformat()
if enrollment.last_active else None
),
})
@function_tool
def get_help_for_module(
course_id: str, module_id: str
) -> str:
"""Get help resources for a specific module."""
course = COURSES.get(course_id)
if not course:
return "Course not found."
for module in course.modules:
if module.module_id == module_id:
return json.dumps({
"module": module.title,
"estimated_time": module.estimated_minutes,
"prerequisites": module.prerequisites,
"help_resources": module.help_resources,
"content_type": module.content_type,
})
return "Module not found."
@function_tool
def get_at_risk_learners(course_id: str) -> str:
"""Identify learners who are stuck or at risk of dropping out."""
stuck = detect_stuck_learners(course_id)
return json.dumps(stuck) if stuck else "No at-risk learners."
platform_agent = Agent(
name="Learning Platform Assistant",
instructions="""You are an online learning platform assistant.
Help students track their progress, find help when stuck, and
stay motivated. When a student seems frustrated, be empathetic
and offer specific help resources for their current module.
For course staff, identify at-risk learners and suggest
interventions. Celebrate milestones and progress, not just
completion.""",
tools=[
get_learner_progress,
get_help_for_module,
get_at_risk_learners,
],
)
FAQ
How does the stuck detection avoid false positives?
The system considers multiple signals: inactivity duration, number of attempts, time spent versus module estimate, and score trends. A student who is simply on vacation (inactive but was performing well) gets a lower risk score than one who failed multiple attempts and then went inactive. Configurable thresholds per course type reduce noise.
See AI Voice Agents Handle Real Calls
Book a free demo or calculate how much you can save with AI voice automation.
Can the agent personalize content recommendations?
Yes. By analyzing which module types (video, reading, exercise) the student completes fastest and scores highest on, the agent can recommend alternative content formats. If a student struggles with video lectures but excels at reading materials, it can suggest the text-based alternatives for upcoming modules.
How does this integrate with existing LMS platforms like Canvas or Moodle?
Canvas and Moodle expose REST APIs for enrollment, grades, and module completion data. The agent tools become API wrappers that translate LMS data into the internal model. This approach means the agent works as an overlay on the existing platform without requiring students to use a different interface.
#AIAgents #EdTech #OnlineLearning #Python #LMS #AgenticAI #LearnAI #AIEngineering
CallSphere Team
Expert insights on AI voice agents and customer communication automation.
Try CallSphere AI Voice Agents
See how AI voice agents work for your industry. Live demo available -- no signup required.