Проблема, которую никто не замечает
Представьте: 150 студентов сдают лабораторную работу по Python. Каждая работа - 200-300 строк кода. Преподаватель должен проверить синтаксис, логику, стиль, безопасность. И сделать это за неделю.
Теперь умножьте на 5 групп. И на 10 заданий за семестр.
Результат? Преподаватель работает по 80 часов в неделю. Студенты ждут проверки месяц. Качество обратной связи стремится к нулю. В итоге все довольны: студенты получают оценки, преподаватель - зарплату. А программировать нормально не научился никто.
В МАИ столкнулись с классической проблемой: преподавателей не хватает, а студентов слишком много. Ручная проверка превращалась в ад. Нужно было или нанимать еще 10 преподавателей, или автоматизировать процесс. Выбрали второе.
Frieren: не просто бот, а система
Назвали систему Frieren - в честь персонажа-эльфа, который живет вечно и постоянно учится. Идея простая: если студенты все равно используют ChatGPT для решения задач, давайте сделаем это легально и под контролем.
Но Frieren - это не просто ChatGPT-обертка. Это полноценная образовательная платформа с:
- Автоматической проверкой кода
- Анализом стиля и архитектуры
- Построением индивидуальных траекторий обучения
- Интеграцией с Telegram для мгновенной обратной связи
- Аналитикой по всем студентам и группам
Архитектура: почему микросервисы, а не монолит
Первая ошибка, которую совершают 90% разработчиков образовательных систем: делают монолит. "У нас же маленький проект", "Зачем усложнять", "Быстрее написать". Через полгода монолит превращается в кошмар.
В Frieren сразу пошли по пути микросервисов. Не потому что модно, а потому что:
- Каждый сервис можно обновлять независимо
- Падение одного сервиса не ломает всю систему
- Легче масштабировать именно те части, которые нагружены
- Разные команды могут работать параллельно
| Сервис | Технологии | За что отвечает |
|---|---|---|
| API Gateway | FastAPI | Единая точка входа, аутентификация, маршрутизация |
| Code Analyzer | Python, AST, pylint | Статический анализ кода, проверка стиля |
| AI Assistant | OpenAI API, prompt engineering | Общение со студентами, объяснение ошибок |
| Telegram Bot | python-telegram-bot, Redis | Уведомления студентов, быстрые ответы |
| Dashboard | Next.js, TypeScript | Интерфейс преподавателя, аналитика |
| Message Broker | RabbitMQ | Асинхронная коммуникация между сервисами |
1 Начинаем с API Gateway на FastAPI
FastAPI выбрали не случайно. Django слишком тяжелый для API, Flask слишком простой. FastAPI - золотая середина: автоматическая документация, асинхронность, встроенная валидация.
Основной эндпоинт для загрузки работ выглядит так:
from fastapi import FastAPI, UploadFile, HTTPException
from pydantic import BaseModel
from typing import List
app = FastAPI(title="Frieren API")
class CodeSubmission(BaseModel):
student_id: str
task_id: str
code: str
language: str = "python"
@app.post("/submit")
async def submit_code(submission: CodeSubmission):
"""Принимает код от студента и запускает процесс проверки"""
# Валидируем базовые требования
if len(submission.code.strip()) == 0:
raise HTTPException(status_code=400, detail="Код не может быть пустым")
# Отправляем в RabbitMQ для асинхронной обработки
await rabbit_client.publish(
exchange="submissions",
routing_key="python.code",
body=submission.json()
)
return {
"message": "Код принят в обработку",
"submission_id": generate_uuid(),
"estimated_time": "2-3 минуты"
}
2 Code Analyzer: больше чем просто линтер
Большинство систем проверки кода ограничиваются запуском тестов. Это ошибка. Студент может написать ужасный код, который проходит все тесты.
Наш Code Analyzer проверяет:
- Синтаксические ошибки (очевидно)
- Стиль кода (PEP 8 для Python)
- Сложность функций (цикломатическая сложность)
- Потенциальные баги (использование mutable default arguments)
- Плагиат (похожесть на другие работы)
- Использование "запрещенных" конструкций (eval, exec для новичков)
import ast
import astroid
from pylint import checkers
from pylint.lint import PyLinter
class AdvancedCodeAnalyzer:
def __init__(self):
self.linter = PyLinter()
def analyze(self, code: str, task_requirements: dict) -> dict:
"""Полный анализ кода"""
results = {
"syntax_errors": [],
"style_issues": [],
"complexity_warnings": [],
"security_issues": [],
"plagiarism_score": 0.0,
"ai_generated_probability": 0.0
}
# Проверка синтаксиса
try:
tree = ast.parse(code)
except SyntaxError as e:
results["syntax_errors"].append({
"line": e.lineno,
"message": str(e),
"severity": "error"
})
return results
# Анализ AST на сложные паттерны
self._analyze_ast(tree, results)
# Проверка на сгенерированный ИИ код
results["ai_generated_probability"] = self._detect_ai_code(code)
return results
def _detect_ai_code(self, code: str) -> float:
"""Определяет, был ли код сгенерирован ИИ
Использует эвристики:
- Слишком "идеальный" стиль
- Отсутствие типичных ошибок новичков
- Использование продвинутых конструкций в простых задачах
"""
# Упрощенная версия алгоритма
score = 0.0
if "# Generated by" in code:
score += 0.3
# Проверяем комментарии - ИИ редко пишет осмысленные комментарии
comment_lines = [l for l in code.split('\n') if l.strip().startswith('#')]
if len(comment_lines) == 0:
score += 0.2
return min(score, 1.0)
3 AI Assistant: не заменять преподавателя, а усиливать
Самая сложная часть. ChatGPT отлично объясняет ошибки, но у него есть проблемы:
- Может "галлюцинировать" и придумывать несуществующие ошибки
- Не знает контекста конкретного задания
- Может дать слишком сложное решение для новичка
Решение - промпт-инжиниринг с контекстом задания:
AI_ASSISTANT_PROMPT = """
Ты - ассистент преподавателя программирования. Твоя задача - помогать студентам исправлять ошибки в коде.
КОНТЕКСТ ЗАДАНИЯ:
{task_description}
ТРЕБОВАНИЯ:
{task_requirements}
ОШИБКИ В КОДЕ СТУДЕНТА:
{student_errors}
Код студента:
python
{student_code}
ИНСТРУКЦИИ:
1. Объясни каждую ошибку простым языком
2. Покажи, как исправить, но не давай полное решение
3. Учитывай, что студент только учится
4. Не используй сложные термины без объяснения
5. Предложи дополнительные упражнения для закрепления
Начни с общей оценки кода, затем разбери ошибки по порядку.
"""
Ключевой инсайт: не запрещайте студентам использовать ChatGPT, а научите их использовать его правильно. Frieren показывает, как задавать вопросы ИИ, как проверять его ответы, как не доверять слепо.
4 Telegram Bot: там, где студенты
Студенты живут в Telegram. Не в Moodle, не в почте, а в Telegram. Поэтому интеграция с Telegram - не "фича", а необходимость.
Бот делает три вещи:
- Уведомляет о результатах проверки
- Позволяет задать быстрый вопрос
- Отправляет напоминания о дедлайнах
from telegram import Update
from telegram.ext import Application, CommandHandler, MessageHandler, filters
import asyncio
class FrierenTelegramBot:
def __init__(self, token: str, redis_client):
self.app = Application.builder().token(token).build()
self.redis = redis_client
# Регистрируем обработчики
self.app.add_handler(CommandHandler("start", self.start))
self.app.add_handler(CommandHandler("status", self.check_status))
self.app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, self.handle_message))
async def start(self, update: Update, context):
"""Приветственное сообщение"""
user = update.effective_user
await update.message.reply_text(
f"Привет, {user.first_name}! Я Frieren - твой помощник в программировании.\n"
"Отправь мне код, и я помогу его проверить."
)
async def notify_student(self, student_id: str, result: dict):
"""Отправляет результат проверки студенту"""
chat_id = await self.redis.get(f"student:{student_id}:chat_id")
if not chat_id:
return
message = self._format_result_message(result)
await self.app.bot.send_message(
chat_id=int(chat_id),
text=message,
parse_mode="Markdown"
)
def _format_result_message(self, result: dict) -> str:
"""Форматирует результат проверки для Telegram"""
if result["passed"]:
return f"✅ *Задание проверено!*\n\n{result['feedback']}"
else:
errors = "\n".join([f"• {e}" for e in result["errors"]][:3])
return f"⚠️ *Найдены ошибки*\n\n{errors}\n\n{result['hint']}"
Что получилось в МАИ
Через 6 месяцев после внедрения Frieren:
- Время проверки работ сократилось с 7 дней до 10 минут
- Преподаватели тратят на рутинную проверку на 70% меньше времени
- Студенты получают обратную связь сразу, а не через неделю
- Качество кода у студентов выросло (по метрикам Code Analyzer)
- Снизилось количество списываний - система лучше детектирует плагиат
Но главное - изменилось отношение студентов к ChatGPT. Они перестали слепо копировать код, начали задавать осмысленные вопросы, анализировать ответы ИИ. Это именно то, что нужно: не запретить технологию, а научить использовать ее правильно.
Типичные ошибки при внедрении подобных систем
Ошибка 1: Слишком сложные требования с первого дня. Начните с проверки синтаксиса и базовых тестов. Не пытайтесь сразу анализировать архитектуру.
Ошибка 2: Плохие промпты для ИИ. Без четких инструкций ChatGPT будет давать бесполезные или вредные советы. Потратьте неделю на написание и тестирование промптов.
Ошибка 3: Игнорирование человеческого фактора. Некоторые студенты боятся ИИ, некоторые преподаватели видят в нем угрозу. Проводите обучение, показывайте преимущества.
Что дальше? Будущее автоматизированного образования
Frieren - только начало. Следующие шаги:
- Индивидуальные траектории обучения: AI анализирует ошибки студента и предлагает конкретные темы для изучения
- Парное программирование с ИИ: Режим, где ИИ выступает в роли напарника, а не проверяющего
- Автоматическая генерация заданий: Под каждый студента - своя уникальная задача
- Прогнозирование отстающих: AI предсказывает, кто не сдаст сессию, за месяц до начала
Если интересно, как работают AI-кодинг агенты изнутри, почитайте про архитектуру AI-кодинг агентов. Там много пересечений с нашей системой.
И помните: автоматизация в образовании - это не про то, чтобы заменить преподавателей. Это про то, чтобы освободить их время от рутины и позволить делать то, что машина никогда не сможет: вдохновлять, мотивировать, понимать человеческие эмоции.
ИИ не заменит учителя. Но учитель, который использует ИИ, заменит того, кто его не использует.