Files
anti-plagiarism/docs/DIAGRAM.md
jze9 e4ca4a7150
All checks were successful
Deploy / test (push) Successful in 2m59s
Deploy / deploy (push) Successful in 3s
docs: сервер эмбеддингов переехал на .1.40 + честные итоги проверок
Прод переключён на новый сервер эмбеддингов (VM 210 «embedding-cpu»,
192.168.1.40, хост pve2). Ключевое, чего не было в исходном плане переключения:
OLLAMA_URL живёт в Infisical, и deploy.sh генерирует .env из него на каждом
запуске — правка .env на сервере откатилась бы первым же деплоем.

Совместимость векторов проверена прямым сравнением, а не на слово: косинус
0.9999997, расхождение 1e-4 (округление AVX2 против AVX-512) — переиндексация
93 тыс. векторов не понадобилась.

Документация приведена в соответствие с фактами:
- ARCHITECTURE/DIAGRAM/README/CREDENTIALS: новый сервер, старый помечен как
  выведенный; убрано упоминание CUDA — GPU в проекте нет;
- DR-HA: эмбеддинги больше не висят на хосте .254, чьё падение 28.08 разом
  унесло брокер, прокси и секреты;
- INGESTION: исправлено собственное враньё про КиберЛенинку — «48 часов на
  100 тысяч» опровергнуто практикой, сайт блокирует выкачку после ~130 статей;
  снапшот OpenAlex вычеркнут как путь к миллионам (там только метаданные).

bulk_ingest_pmc.py: снята пометка «не закончен» — бага не было, первый прогон
упал уже после успешной вставки, а второй корректно пропустил дубли. Проверено:
100 статей, 183 090 отпечатков. Реальный темп 0.3 ст/с записан честно.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 17:06:41 +05:00

114 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Схема системы
Визуальная схема к [ARCHITECTURE.md](ARCHITECTURE.md) (там — полное текстовое описание).
## Компоненты и потоки данных
```mermaid
flowchart TB
subgraph client["Клиент"]
FE["Frontend (React SPA)<br/>CT 102, nginx"]
end
subgraph app["App-хост 1.32"]
API["API (FastAPI)<br/>JWT · rate-limit · /metrics"]
MQ[("RabbitMQ .82<br/>брокер Celery")]
subgraph workers["Celery-воркеры"]
IDX["worker-indexer<br/>L1 Winnowing · L2 MinHash<br/>PDF/DOCX · парсеры"]
GPU["worker-gpu<br/>L3 семантика · L4 LLM<br/>эмбеддинги"]
GOST["worker-gost<br/>ГОСТ 7.1 / 7.0.5"]
NOTIFY["worker-notifier<br/>SMTP email"]
end
ES[("Elasticsearch<br/>BM25, local")]
VEC{{"Векторный бэкенд<br/>VECTOR_BACKEND"}}
FAISS["FAISS<br/>(файл, дефолт)"]
QDR["Qdrant<br/>(опционально)"]
end
subgraph shared["Общая инфраструктура"]
PG[("PostgreSQL 1.38<br/>users/tasks/documents/<br/>fingerprints/...")]
REDIS[("Redis 1.35<br/>кэш · rate-limit · LSH-индекс")]
MINIO[("MinIO 1.21<br/>документы · full-text · бэкапы")]
OLLAMA["Ollama 1.40 embedding-cpu<br/>bge-m3, эмбеддинги (L3)"]
OPENROUTER["OpenRouter/DeepSeek<br/>LLM L4 (опц., через singbox-proxy)"]
INFISICAL["Infisical .111<br/>секреты → .env на каждом деплое"]
end
subgraph obs["Опционально (профили compose)"]
PROM["Prometheus"]
GRAF["Grafana"]
end
FE -->|"HTTPS /api, /ws"| API
API -->|"send_task"| MQ
API <-->|"users/tasks"| PG
API <-->|"session/rate-limit"| REDIS
MQ -->|"queue.index"| IDX
MQ -->|"queue.gpu"| GPU
MQ -->|"queue.gost"| GOST
MQ -->|"queue.notify"| NOTIFY
IDX <-->|"documents/fingerprints"| PG
IDX <-->|"MinHash LSH (antiplag_lsh)"| REDIS
IDX <-->|"PDF/full-text"| MINIO
IDX --> ES
IDX -->|"gpu.embed_documents"| MQ
GPU <-->|"documents"| PG
GPU -->|"L3 эмбеддинги"| OLLAMA
GPU --> VEC
VEC --> FAISS
VEC -.->|"переключение флагом"| QDR
GPU -.->|"L4 парафраз (LLM_BACKEND)"| OLLAMA
GPU -.->|"L4 парафраз, опц."| OPENROUTER
GPU --> ES
GOST <-->|"documents"| PG
NOTIFY <-->|"tasks"| PG
NOTIFY -->|"email"| SMTP(["jze9mail.ru"])
API -->|"/metrics"| PROM
PROM --> GRAF
style VEC fill:#00000000,stroke-dasharray: 4 3
style obs fill:#00000000,stroke-dasharray: 4 3
```
## Конвейер проверки плагиата (4 уровня)
```mermaid
sequenceDiagram
participant U as Студент
participant API as API
participant IDX as worker-indexer
participant GPU as worker-gpu
participant LLM as Ollama/OpenRouter<br/>(LLM_BACKEND)
U->>API: upload файла
API->>API: сохранить в MinIO, создать Task, commit
API->>IDX: index.extract_and_check
IDX->>IDX: извлечь текст → фрагменты
IDX->>IDX: L1 Winnowing (fingerprints)
IDX->>IDX: L2 MinHash LSH (Redis)
IDX->>GPU: gpu.check_plagiarism (частичные совпадения)
loop по подозрительным фрагментам
GPU->>GPU: L3 семантический поиск (FAISS/Qdrant)
GPU->>LLM: L4 check_paraphrase
LLM-->>GPU: is_paraphrase, confidence
end
GPU->>GPU: app.scoring.aggregate_results (итоговый %)
GPU->>API: результат → Task.result
GPU-->>U: notify.send_task_done → email/WebSocket
```
## Легенда
- Сплошные стрелки — прямые вызовы/запросы; пунктир у `VEC` — переключение бэкенда
по настройке `VECTOR_BACKEND`, не одновременная работа обоих. Пунктир у L4
(`OLLAMA`/`OPENROUTER`) — то же самое для `LLM_BACKEND`.
- `obs` (Prometheus/Grafana) и `Qdrant` — опциональны, поднимаются под
`docker compose --profile qdrant|observability`, по умолчанию выключены.