ГлавнаяБлогКак создать ИИ-репетитора с проверкой ответов на Python
AI / Нейросети

Как создать ИИ-репетитора с проверкой ответов на Python

Пошаговое руководство по созданию ИИ-репетитора с верификацией ответов на Python. Узнайте, как использовать 50+ академических движков и RAG.

Al
Редакция Algolitalgolit.ru
12 мин чтения25 августа 2026 г.

Почему ваш ИИ-репетитор должен проверять ответы

Представьте: студент задает вопрос ChatGPT, получает красивый ответ, но на экзамене проваливается. Почему? Потому что языковые модели угадывают, а не вычисляют. Они не проверяют свои ответы, не знают вашу учебную программу и могут уверенно выдать ложь. В этой статье я покажу, как построить ИИ-репетитора, который не просто генерирует, а верифицирует каждый ответ с помощью академических движков — от SymPy до ChemPy. Вы узнаете, как реализовать каскадный поиск, подключить 50+ проверочных движков и создать офлайн-приложение, которое реально помогает студентам.

Архитектура проверенного ИИ-репетитора

Система состоит из нескольких ключевых компонентов: FastAPI для бэкенда, LLM для генерации, векторная база Qdrant для семантического поиска, Meilisearch для ключевых слов, и главное — движок верификации, который пересчитывает ответы. Студент задает вопрос, система ищет релевантный контекст, генерирует ответ, а затем проверяет его через математические, физические, химические и инженерные библиотеки. Если ответ неверен — исправляет и объясняет ошибку.

Технологический стек

  • API: FastAPI (Python)
  • LLM: Groq (основной), OpenRouter (резервный)
  • Верификация: 50+ движков (SymPy, ChemPy, PyNiteFEA и др.)
  • Векторная БД: Qdrant Cloud
  • Ключевой поиск: Meilisearch
  • База данных: Neon (PostgreSQL)
  • Кэш: Redis
  • Фронтенд: Next.js 14 + Tailwind
  • Офлайн: PWA + Service Worker + IndexedDB
  • Хостинг: Hetzner VPS

Поток данных

Пользовательский вопрос проходит через 5 этапов поиска: сначала ищем в конспектах (векторный поиск), затем в учебной программе (ключевой поиск), потом в академических источниках (гибридный), далее в интернете, и в последнюю очередь — прямой вызов LLM. На каждом этапе контекст добавляется в запрос, а финальный ответ проверяется движками.

Движок верификации — 50+ академических валидаторов

Секретное оружие UniUI — это перекрестная проверка каждого сгенерированного ответа. LLM генерирует ответ, затем определяется предметная область, и ответ передается в соответствующие библиотеки: SymPy для математики, ChemPy для химии, PyNiteFEA для инженерии. Если результат расходится — система возвращает исправленный ответ с объяснением.

Пример верификации математического ответа

Допустим, студент просит вычислить интеграл от x². LLM может дать неправильный ответ, но SymPy вычислит точно:

import sympy as sp
import numpy as np
from typing import Dict, Any, Optional

def verify_math_answer(question: str, llm_answer: str) -> Dict[str, Any]:
    """
    Проверяет ответ по математике с помощью SymPy.
    Возвращает: {"verified": bool, "correct_answer": str, "derivation": str, "confidence": float}
    """
    try:
        # Шаг 1: Парсим вопрос и извлекаем выражение
        # Шаг 2: Преобразуем в выражение SymPy
        # Шаг 3: Вычисляем правильный ответ
        # Шаг 4: Сравниваем с ответом LLM
        # Шаг 5: Возвращаем результат
        x = sp.Symbol('x')
        expression = sp.integrate(x**2, x)  # Результат: x**3/3
        return {
            "verified": True,
            "correct_answer": str(expression),
            "derivation": "∫x²dx = x³/3",
            "confidence": 1.0
        }
    except Exception as e:
        return {
            "verified": False,
            "correct_answer": None,
            "error": str(e),
            "confidence": 0.0
        }

Этот код — лишь иллюстрация. В реальной системе вы парсите вопрос, извлекаете математическое выражение, вычисляете его и сравниваете с ответом LLM. Если расхождение — исправляете.

RAG-конвейер: 5-этапный каскадный поиск

Перед генерацией ответа система ищет контекст. Это критично для точности. Вот как реализован каждый этап.

Этап 1: Конспекты (векторный поиск)

def vector_search(query: str, faculty: Optional[str] = None) -> List[Dict]:
    """Поиск семантически похожего контента в Qdrant."""
    embedding = get_embedding(query)
    filter_condition = None
    if faculty:
        filter_condition = {"must": [{"key": "faculty", "match": {"value": faculty}}]}
    results = qdrant_client.search(
        collection_name="uniui_documents",
        query_vector=embedding,
        query_filter=filter_condition,
        limit=10,
        score_threshold=0.7
    )
    return results

Этап 2: Учебная программа (ключевой поиск)

def keyword_search(query: str) -> List[Dict]:
    """Поиск по ключевым словам в Meilisearch."""
    results = meilisearch_client.index("curriculum").search(
        query,
        {"attributesToRetrieve": ["title", "content", "course_code"], "limit": 10}
    )
    return results["hits"]

Этап 3: Академические источники (гибридный поиск)

def hybrid_search(query: str) -> List[Dict]:
    """Комбинация векторного и ключевого поиска через RRF."""
    vector_results = vector_search(query)
    keyword_results = keyword_search(query)
    fused = reciprocal_rank_fusion(vector_results, keyword_results, alpha=60)
    return fused[:10]

Этап 4: Интернет (резервный)

def internet_search(query: str) -> List[Dict]:
    """Поиск в интернете через Exa или SerpAPI."""
    try:
        results = exa_client.search(query, type="neural", num_results=5)
        return results["results"]
    except Exception:
        return jina_search(query)

Этап 5: Прямой вызов LLM (крайний случай)

def direct_llm(query: str) -> str:
    """Генерация ответа напрямую из LLM без контекста."""
    response = groq_client.chat.completions.create(
        model="llama-3.3-70b-versatile",
        messages=[
            {"role": "system", "content": "Вы строгий академический репетитор. Отвечайте точно."},
            {"role": "user", "content": query}
        ]
    )
    return response.choices[0].message.content

Полная реализация: API на FastAPI

Теперь объединим все в единый эндпоинт. Маршрутизатор принимает вопрос, выполняет каскадный поиск, генерирует ответ и верифицирует его.

from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel
from typing import List, Optional
from academic_pipeline.backend.verifiers import verify_answer
from academic_pipeline.backend.retrieval import hybrid_search
from academic_pipeline.backend.llm import call_llm

router = APIRouter()

class AskRequest(BaseModel):
    question: str
    faculty: Optional[str] = None
    course_code: Optional[str] = None

class AskResponse(BaseModel):
    answer: str
    verified: bool
    verified_answer: Optional[str] = None
    sources: List[Dict[str, str]]
    engine_used: str
    confidence: float

@router.post("/ask", response_model=AskResponse)
async def ask_question(request: AskRequest):
    """
    Главный эндпоинт для вопросов.
    1. Поиск контекста (5-этапный каскад)
    2. Генерация ответа LLM с контекстом
    3. Верификация ответа академическими движками
    4. Возврат проверенного результата
    """
    # Шаг 1: Поиск контекста
    contexts = hybrid_search(request.question)
    if not contexts:
        # Этап 5: Прямой вызов LLM
        llm_answer = await direct_llm(request.question)
        sources = []
    else:
        # Этапы 1-4: LLM с контекстом
        llm_answer, sources = await generate_with_context(request.question, contexts)

    # Шаг 2: Верификация ответа
    verification_result = await verify_answer(
        question=request.question,
        answer=llm_answer,
        faculty=request.faculty
    )

    # Шаг 3: Формирование ответа
    return AskResponse(
        answer=verification_result.get("answer", llm_answer),
        verified=verification_result.get("verified", False),
        verified_answer=verification_result.get("correct_answer"),
        sources=sources,
        engine_used=verification_result.get("engine_used", "groq"),
        confidence=verification_result.get("confidence", 0.0)
    )

Интеграция верификаторов

Реестр верификаторов позволяет легко добавлять новые предметные движки. Используйте декоратор для регистрации функций.

from typing import Dict, Any, Optional
import importlib
import inspect

VERIFIERS = {}

def register_verifier(subject: str):
    def decorator(func):
        VERIFIERS[subject] = func
        return func
    return decorator

async def verify_answer(question: str, answer: str, faculty: Optional[str] = None) -> Dict[str, Any]:
    """Верифицирует ответ, используя подходящий движок."""
    subject = detect_subject(question, faculty)
    verifier = VERIFIERS.get(subject)
    if not verifier:
        return {"verified": False, "answer": answer, "engine_used": "none", "confidence": 0.0}
    try:
        result = await verifier(question, answer)
        result["engine_used"] = subject
        return result
    except Exception as e:
        return {"verified": False, "answer": answer, "engine_used": subject, "confidence": 0.0, "error": str(e)}

Определение предмета

Для маршрутизации к правильному движку используйте ключевые слова.

KEYWORDS = {
    "math": ["интеграл", "производная", "математика", "матрица", "уравнение"],
    "physics": ["сила", "скорость", "энергия", "импульс", "гравитация"],
    "chemistry": ["моль", "реакция", "кислота", "щелочь", "стехиометрия"],
    # ... другие предметы
}

def detect_subject(question: str, faculty: Optional[str] = None) -> str:
    # Простой анализ ключевых слов
    for subject, keywords in KEYWORDS.items():
        if any(kw in question.lower() for kw in keywords):
            return subject
    return "general"

Практические выводы: что делать прямо сейчас

Вы можете начать с малого: возьмите один предмет, например математику, и подключите SymPy для верификации. Создайте FastAPI-эндпоинт, который принимает вопрос, генерирует ответ через Groq и проверяет его. Затем добавьте поиск по учебным материалам через Qdrant. Постепенно расширяйте до 50+ движков. Главное — не давайте студентам непроверенные ответы. Начните с простого прототипа, протестируйте его на реальных вопросах и улучшайте. Уже через неделю у вас будет работающий ИИ-репетитор, которому можно доверять.

#ИИ-репетитор#верификация ответов#FastAPI#RAG#SymPy
Al
Редакция Algolit

Пишем про алгоритмы, подготовку к собеседованиям и карьеру в IT — так, чтобы было понятно и полезно.

Хочешь закрепить знания на практике?

Решай задачи на Algolit — интерактивная платформа для обучения

Начать бесплатно →