Skip to content
MarkIvorPublic

About

Автономный детектор ИИ-контента и академической честности. Двухсигнальная математическая модель + AI-Судья, проверяющий смыслы и логику.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

36 Commits

Folders and files

Repository files navigation

AI Radar

Python FastAPI License Language Status

Детектор, который проверяет не текст, а смыслы.

Спойлер: обычные антиплагиат-детекторы ловят синтаксис («таким образом, подводя итог...»). Современные модели этот синтаксис уже научились маскировать — копируют стиль, добавляют «личный опыт», перефразируют штампы. Статистика одна, а смысл другой. AI Radar не спорит с текстом — он спрашивает у самих LLM: «это написал ты?». AI Radar определяет академическую честность, считая, что ИИ - современный инструмент, и само по себе его применение не является нарушением.


Откуда задача

Студенческие работы, рефераты, дипломы и эссе массово пишутся через ChatGPT, Claude, DeepSeek, Gemini, Grok, Kimi. Встроенные детекторы вроде Turnitin и GPTZero часто ошибаются в обе стороны: ложно срабатывают на живых текстах с богатой лексикой и пропускают явно сгенерированные — особенно после ручного перефразирования (paraphrase attack).

Преподаватели и научные руководители остаются один на один с текстом, без инструмента, которому можно доверять — и уж тем более без возможности обосновать вердикт студенту, который придёт оспаривать оценку.

AI Radar собран под принцип «не доверяй одному сигналу»: статистика считает математику, ансамбль LLM проверяет «свой почерк», а метасудья выносит финальный вердикт с правом заблокировать работу независимо от процента.


Почему не Turnitin / GPTZero / Originality.ai

Инструмент На чём основан Где ломается
Turnitin AI Detector Статистика + perplexity Ложные срабатывания на носителях языка с богатой лексикой
GPTZero Burstiness + perplexity Обходится простым перефразированием (paraphrase attack)
Originality.ai Классификатор-бинарник Чёрный ящик, нет обоснования вердикта, нет апелляции
ZeroGPT Эвристики + ML-модель Не различает «похоже на ИИ по стилю» и «реально написано ИИ»
AI Radar 20 метрик + ансамбль LLM + метасудья с ВЕТО Проверяет логику и «почерк» модели, а не только синтаксис. Каждый вердикт — с обоснованием для апелляции

Ключевое отличие: остальные детекторы ищут следы генерации в тексте. AI Radar ищет следы отсутствия человека — личного опыта, конкретики, сомнений, авторской позиции. А заодно спрашивает у 6 разных LLM: «похоже ли это на то, что написал бы ты сам?» — модели узнают собственный почерк лучше любой статистики.


В чём особенность

1. Двухуровневый AI-судья

Уровень 1 — Ансамбль детекторов. Любое число OpenAI-compatible моделей (ChatGPT, Claude, Gemini, DeepSeek, Grok, Kimi) параллельно анализируют текст. Каждая модель проводит саморефлексивный анализ: представляет, что могла бы написать этот текст сама, и оценивает, насколько это похоже на её собственный стиль аргументации.

Что ищут детекторы:

  • Следы генерации LLM — механическая однородность глубины абзацев, повторяющиеся клише, сверхправильная структура.
  • Чья логика — сбалансированные «про и контра», нейтральность, уход от позиции, «правильные», но поверхностные выводы, галлюцинации.
  • Человеческие особенности (их отсутствие = сигнал ИИ) — личный опыт, конкретные истории, имена, даты, креативность, юмор, ирония, авторская позиция, «шероховатости» и сомнения.

Уровень 2 — Метасудья. ОДНА сильная модель (рекомендация: Claude Sonnet/Opus, Gemini Pro), которая не видит исходный текст. Ей передаются: сводка 20 статистических метрик, вердикты всех детекторов ансамбля (ai_score, veto, фрагменты, признаки человека/ИИ) и промпт для оценки. Метасудья выявляет ошибки отдельных детекторов, оценивает согласованность ансамбля и выносит финальный вердикт.

2. Блокирующее ВЕТО

Судья может выставить academic_integrity = "НАРУШЕНА" независимо от итогового процента, если выявил критические логико-структурные аномалии генерации. Обоснование (veto_reason) сохраняется в отчёте и доступно для апелляции студента.

3. Три режима работы

Статус Что работает Финальный вердикт VETO
OFFLINE Только Сигнал 1 (статистика) stat_score не активируется
ENSEMBLE_ONLY Ансамбль без судьи медиана ансамбля активируется
FULL Ансамбль + метасудья вердикт судьи активируется

Как это работает

┌─────────────────────────────────────────────────────────────┐
│                    AI Radar Pipeline                         │
│                                                               │
│  Текст работы                                                │
│      │                                                       │
│      ▼                                                       │
│  ┌────────────┐   20 статистических метрик                  │
│  │ Сигнал 1   │   burstiness, TTR, Yule's K, Honore's R,     │
│  │ (стат)     │   perplexity proxy, cliche density,          │
│  └─────┬──────┘   n-gram repetition, rhythm entropy и др.    │
│        │           stat_score [0..100]                       │
│        ▼                                                     │
│  ┌────────────────────────────────────────────────────┐     │
│  │ Сигнал 2, Уровень 1: Ансамбль детекторов            │     │
│  │  ChatGPT ─┐                                          │     │
│  │  Claude  ─┼─▶ каждый анализирует текст + метрики     │     │
│  │  Gemini ─┤   и проверяет: «не я ли это написал?»    │     │
│  │  DeepSeek┤   возвращает ai_score, veto, фрагменты,   │     │
│  │  Grok   ─┤   human_signals[], llm_signals[]          │     │
│  │  Kimi   ─┘                                           │     │
│  │  Агрегация: медиана ai_score, голосование по VETO    │     │
│  └─────────────────┬────────────────────────────────────┘    │
│                    ▼                                          │
│  ┌────────────────────────────────────────────────────┐     │
│  │ Сигнал 2, Уровень 2: Метасудья (Claude/Gemini Pro)  │     │
│  │  НЕ видит текст работы — только сводку метрик       │     │
│  │  и вердикты ансамбля. Право БЛОКИРУЮЩЕГО ВЕТО.       │     │
│  └─────────────────┬────────────────────────────────────┘    │
│                    ▼                                          │
│  Финальный отчёт + страница детализации с подсветкой         │
└─────────────────────────────────────────────────────────────┘

ai_score = 0.7·judge + 0.3·stat в режиме FULL, либо чистый stat_score в OFFLINE. Если veto_triggered=True или ai_score ≥ VETO_THRESHOLD → academic_integrity = "НАРУШЕНА".


Что видит преподаватель

Отдельная страница отчёта с:

  • Круговой диаграммой итогового ai_score с цветовой индикацией (зелёный / жёлтый / красный).
  • Бейджем ВЕТО — «АКТИВИРОВАНО» / «НЕ АКТИВИРОВАНО».
  • Статусом академической честности — «ПОДТВЕРЖДЕНА» / «НАРУШЕНА».
  • Полной матрицей 20 метрик Сигнала 1 с тултипами-пояснениями.
  • Вердиктами ансамбля — какой детектор что поставил, какие признаки человека/ИИ нашёл.
  • Вердиктом метасудьи — финальный скор и обоснование.
  • Текстом работы с подсветкой в три уровня: жёлтый (подозрение), оранжевый (высокая уверенность), красный (критично).
  • Кнопками «Распечатать / PDF» и «Скачать JSON».

Прогресс-бар показывает пошаговые статусы в реальном времени: «Считаю метрики…» → «Опрашиваю ансамбль из 6 детекторов…» → «Метасудья оценивает вердикты…» → «Готово!» — с ETA в секундах.


Сигнал 1: 20 статистических метрик

Без локальных нейросетей — чистая математика на Python. Сводный stat_score [0..100] считается взвешенной эвристикой: метрики, на которых современные LLM «прогораются» сильнее всего (burstiness, TTR, cliche density, n-gram repetition), получают большие веса.

# Метрика Что показывает
1 Burstiness SD/Mean длин предложений. ИИ → 0.1–0.4, человек → 0.6–1.2
2 Lexical Diversity (TTR) Уникальные леммы / всего слов
3 Sentence Length Variance Дисперсия длин предложений
4 Perplexity Proxy Shannon-энтропия биграмм
5 Synthetic Cliche Density Плотность клише на 1000 слов
6 Punctuation Entropy Разнообразие пунктуации
7 Sentence Starter Entropy Энтропия первых слов предложений
8 Yule's K Характеристика богатства словаря
9 Honore's R Лексическое богатство
10 Sichel's S Доля hapax legomena
11 Hapax Ratio Слова, встретившиеся 1 раз / всего
12 Connective Density Логические маркеры / 1000 слов
13 N-gram Repetition Rate Доля повторяющихся 3-грамм
14 Sentence Rhythm Entropy Энтропия распределения длин
15 Comma-per-Sentence Запятых на предложение
16 Avg Syllables per Word Среднее число слогов
17 Function-Word Ratio Доля служебных слов
18 Lexical Density Content-words / всего слов
19 TTR Windowed Скользящий TTR (MATTR-подобный)
20 Determiner Density Определители / 1000 слов

Каждая метрика в интерфейсе имеет тултип с пояснением — преподавателю не нужно гуглить, что такое Yule's K, чтобы обосновать вердикт студенту.


Что показывает практика

Несколько паттернов, которые видны после прогонов на реальных студенческих работах:

Замаскированный текст не проходит ансамбль. Perplexity легко обойти ручным перефразированием — но саморефлексивный анализ («похоже ли это на мой стиль?») ловит именно логику аргументации, а не поверхностный синтаксис. Модель узнаёт свой почерк даже под чужим стилем.

Один детектор — ненадёжно, шесть — устойчиво. Разные семейства LLM (GPT, Claude, Gemini, DeepSeek, Grok, Kimi) по-разному «прогораются» на собственных паттернах. Голосование большинством и медиана ai_score гасят единичные ложные срабатывания.

ВЕТО ловит то, что пропускает процент. Работа может набрать скромные 40-50% по ai_score, но иметь критическую логико-структурную аномалию (например, полное отсутствие личной позиции при формальной «правильности» аргументации) — и именно для этого нужно право блокирующего решения, а не только порог.


Роли и доступ

Роль Что видит
admin Все папки, настройки системы, LLM-провайдеры, API-ключи, управление пользователями
teacher Только свои папки + общие, смена своего пароля

Вход по логину и паролю. Администратор создаёт преподавателей и может сбросить любой пароль. Дефолтный администратор: admin / airadar (рекомендуется сменить в Админ-панели сразу после первого входа).


Доступ через API

AI Radar можно использовать как через UI, так и программно — через API-ключи air_.... Создаются в админ-панели, показываются один раз, поддерживают ротацию и отзыв.

# Логин мастер-паролем
curl -X POST http://localhost:8000/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"login":"admin","password":"airadar"}'

# Создать API-ключ
curl -X POST http://localhost:8000/api/admin/api-keys \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{"name":"CI"}'
# => {"key":"air_xxxx..."}  # сохранить, показывается один раз

# Скан текста через API-ключ
curl -X POST http://localhost:8000/api/scan/quick/json \
  -H "Authorization: Bearer air_xxxx..." \
  -H "Content-Type: application/json" \
  -d '{"text":"В современном мире важно отметить...","title":"work.txt"}'

Интерактивная документация в стиле системы: http://localhost:8000/docs-page OpenAPI-схема: http://localhost:8000/docs


Быстрый старт

Docker (рекомендуется)

git clone <your-repo-url> ai-radar
cd ai-radar
docker-compose up -d
# UI: http://localhost:8000
# Docs: http://localhost:8000/docs-page

Локально

python -m venv .venv
.venv\Scripts\activate       # Windows
# source .venv/bin/activate  # Linux/macOS
pip install -e ".[dev]"
cp .env.example .env         # отредактируйте .env
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

Тесты

pytest -v

Первый вход

  1. Логин: admin | Пароль: airadar
  2. Откройте Админ-панель → Ансамбль детекторов и добавьте модели. Рекомендуемые семейства: ChatGPT, Claude, Gemini, DeepSeek, Grok, Kimi.
  3. Назначьте Метасудью (Claude Sonnet/Opus или Gemini Pro).
  4. Бейдж в шапке покажет ENSEMBLE+JUDGE (6+1) — система готова.

Поддерживаемые модели ансамбля

Любые OpenAI-compatible. Тестировалось на:

Модель Идентификатор
ChatGPT 5.1 openai/gpt-5.1
Claude Sonnet 5 anthropic/claude-sonnet-5
Gemini 3.6 Flash google/gemini-3.6-flash
DeepSeek V4 Pro deepseek/deepseek-v4-pro
Grok 4.3 x-ai/grok-4.3
Kimi K3 moonshotai/kimi-k3

В режиме ensemble все активные модели опрашиваются параллельно. Чем больше разных семейств — тем устойчивее вердикт.


API-эндпоинты

Метод Путь Описание
POST /api/auth/login Логин → access + refresh токены
POST /api/auth/refresh Обновить access-токен
POST /api/auth/logout Выход
GET /api/auth/whoami Тип текущего субъекта доступа
POST /api/scan/quick Quick scan (multipart file / form text)
POST /api/scan/quick/json Quick scan (JSON, для скриптов)
POST /api/scan/deep/{file_id} Глубокая проверка файла из хранилища
GET /api/scan/reports/recent Последние N проверок
GET /api/folders Список папок
POST /api/folders Создать папку/подпапку
DELETE /api/folders/{id} Удалить папку
GET /api/folders/{id}/files Список файлов в папке
POST /api/folders/{id}/files Загрузить файл в папку
DELETE /api/folders/files/{id} Удалить файл
GET /api/admin/settings Текущие настройки
PUT /api/admin/settings Обновить настройки
GET / POST / PUT / DELETE /api/admin/llm-providers CRUD LLM-провайдеров ансамбля
POST /api/admin/llm-providers/{id}/toggle Вкл/выкл провайдера
GET / POST / DELETE /api/admin/api-keys CRUD API-ключей
POST /api/admin/api-keys/{id}/rotate Ротация ключа
GET /api/admin/judge-status Готовность судьи (ONLINE/OFFLINE)

Переменные окружения

Переменная По умолчанию Описание
MASTER_PASSWORD airadar Пароль админа по умолчанию
JWT_SECRET change-me Секрет JWT. В prod обязательно сменить.
ACCESS_TOKEN_TTL_MIN 30 Жизнь access-токена в минутах
REFRESH_TOKEN_TTL_DAYS 7 Жизнь refresh-токена в днях
DATABASE_PATH storage/airadar.db Путь к SQLite
JUDGE_MODE ensemble ensemble или single
JUDGE_HTTP_TIMEOUT_SEC 60 Таймаут HTTP-вызова к LLM
VETO_THRESHOLD 75 Порог авто-ВЕТО в %
JUDGE_MAX_RETRIES 2 Retry при невалидном JSON
DOCS_ENABLED true Включить /docs и /redoc

Научная база

  • Burstiness — вариативность длин предложений. Естественный текст имеет SD/Mean ~ 0.6–1.2, LLM-генерация стремится к 0.1–0.4.
  • Perplexity — классическая метрика сложности текста, аппроксимируется прокси-формулой на Shannon-энтропии биграмм.
  • TTR / Yule's K / Honore's R / Sichel's S — метрики лексического богатства из корпусной лингвистики (1940-е — настоящее время).
  • Саморефлексивный анализ LLM — каждая модель-детектор проверяет, не она ли могла написать текст. Это её «почерк»: типичные паттерны аргументации, нейтральность, сбалансированность.
  • Блокирующее ВЕТО — концепция «семантического вето-голоса»: в задачах детекции критических аномалий статистический процент недостаточен, поэтому судья наделяется правом блокирующего решения.

FAQ

Какие модели поддерживаются? Любые OpenAI-compatible. По умолчанию тестировалось на GPT 5.1, Claude Sonnet 5, Gemini 3.6 Flash, DeepSeek V4 Pro, Grok 4.3, Kimi K3. Можно подключать локальные vLLM и Ollama.

Что если нет API-ключа к LLM? Включается OFFLINE-режим — отчёт строится только на Сигнале 1, VETO не активируется. Полезно для быстрой проверки без внешних вызовов.

Может ли одна модель доминировать в ансамбле? Нет. В ENSEMBLE_ONLY/FULL все активные модели опрашиваются параллельно, ai_score — медиана, veto — большинством голосов.

Не утекут ли тексты студентов в сторонние LLM? Текст передаётся только в подключённые вами LLM-провайдеры. AI Radar не отправляет данные никуда, кроме явно настроенных base_url. Для конфиденциальных данных используйте локальный vLLM/Ollama.

Что такое ВЕТО и почему это не просто высокий процент? Это блокирующее право судьи. Работа может формально набрать невысокий ai_score, но содержать критическую логико-структурную аномалию — судья принудительно выставит academic_integrity = "НАРУШЕНА" с обоснованием в veto_reason, доступным для апелляции.

Поддерживается ли multi-tenancy кроме admin/teacher? В текущей версии — две роли.


Структура проекта

ai-radar/
├── app/
│   ├── main.py              # FastAPI, lifespan, роуты /report/{id}, /docs-page
│   ├── config.py            # Pydantic-Settings (.env bootstrap)
│   ├── api/
│   │   ├── auth.py          # login/refresh/logout/whoami
│   │   ├── scan.py          # quick, quick/json, quick/stream (SSE), deep
│   │   ├── folders.py       # CRUD папок и файлов с ролями
│   │   └── admin.py         # settings, LLM, API-keys, users, judge-status
│   ├── services/
│   │   ├── storage.py       # aiosqlite + users + folders с owner_id
│   │   ├── auth_service.py  # JWT + API keys + role-based Principal
│   │   ├── signal1_stat.py  # 20 метрик Сигнала 1
│   │   ├── signal2_judge.py # Ансамбль + метасудья, саморефлексия
│   │   ├── file_parser.py   # txt/docx/pdf
│   │   └── pipeline.py      # Оркестратор + progress-callback для SSE
│   └── templates/
│       ├── index.html       # SPA
│       ├── report.html      # Страница отчёта с подсветкой
│       └── docs.html        # Документация API в стиле системы
├── static/
│   ├── css/
│   │   ├── style.css        # Tektur + JetBrains Mono + роли + прогресс
│   │   ├── report.css       # Отчётная страница + print-color-adjust
│   │   └── docs.css
│   └── js/
│       ├── app.js           # SPA + SSE прогресс + роли
│       └── report.js        # Отчёт + градация подсветки
├── tests/
│   ├── test_stat.py         # Тесты метрик
│   └── test_api.py          # Тесты API + роли + users
├── .env.example
├── Dockerfile
├── docker-compose.yml
├── pyproject.toml
├── LICENSE (MIT)
└── README.md

Технологии

Слой Технология
Backend Python 3.11, FastAPI, Pydantic v2, Uvicorn
Auth JWT (HMAC-SHA256) + role-based (admin/teacher)
Storage SQLite (aiosqlite)
Files python-docx, pypdf
NLP regex tokenizer (spacy-ru — опционально)
LLM httpx + OpenAI-compatible API, ансамбль
Frontend HTML5, CSS3, Vanilla JS, SSE, Lucide, Google Fonts
Packaging Docker, docker-compose, pyproject.toml

Ограничения и честность

  • Судья тоже LLM — у него есть свои предпочтения и слепые пятна. Выбор модели-судьи влияет на результат. Рекомендуется Claude Sonnet/Opus или Gemini Pro как наиболее нейтральные.
  • 20 метрик Сигнала 1 калиброваны на русскоязычных текстах — для других языков нужна проверка и переподбор весов.
  • ВЕТО — не приговор, а сигнал для человека. Финальное решение об академической честности остаётся за преподавателем; отчёт даёт обоснование, а не автоматическое наказание.

License

MIT — используйте, модифицируйте, форкайте. Ссылка на репозиторий приветствуется.

About

Автономный детектор ИИ-контента и академической честности. Двухсигнальная математическая модель + AI-Судья, проверяющий смыслы и логику.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages