docs(readme): секция «Тестирование и качество» + фикс устаревших фактов
Добавлена секция про CI-гейты (ruff+mypy, 73 юнит-теста, make-команды, таблица покрытия по слоям L1-L4/скоринг/фрагменты/ГОСТ/библиография). Заодно поправлены устаревшие технические утверждения, разошедшиеся с кодом: - FAISS-GPU (IVFFlat) → FAISS-CPU (IndexIDMap2 · IndexFlatIP) — реальный индекс; - Ollama llama3:8b → qwen2.5:7b; убран RTX 2060 (LLM на отдельном GPU-сервере); - уточнено описание 4 уровней проверки под фактическую реализацию. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
52
README.md
52
README.md
@@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
Инфраструктура:
|
Инфраструктура:
|
||||||
PostgreSQL 16 · Redis 7 · RabbitMQ 3 · Elasticsearch 8
|
PostgreSQL 16 · Redis 7 · RabbitMQ 3 · Elasticsearch 8
|
||||||
MinIO (4TB) · Ollama (llama3:8b) · NVIDIA RTX 2060
|
MinIO (S3) · Ollama (qwen2.5:7b) · отдельный GPU-сервер
|
||||||
```
|
```
|
||||||
|
|
||||||
## Быстрый старт
|
## Быстрый старт
|
||||||
@@ -74,8 +74,8 @@ make migrate # Применить Alembic миграции
|
|||||||
make logs # Логи всех сервисов
|
make logs # Логи всех сервисов
|
||||||
make shell-api # Shell в контейнере API
|
make shell-api # Shell в контейнере API
|
||||||
make shell-gpu # Shell в контейнере GPU воркера
|
make shell-gpu # Shell в контейнере GPU воркера
|
||||||
make lint # Запустить линтер
|
make lint # ruff + mypy в контейнере (тот же гейт, что в CI)
|
||||||
make test # Запустить тесты
|
make test # юнит-тесты всех сервисов в контейнерах
|
||||||
make clean # Удалить контейнеры и volumes
|
make clean # Удалить контейнеры и volumes
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -84,20 +84,20 @@ make clean # Удалить контейнеры и volumes
|
|||||||
| Компонент | Технологии |
|
| Компонент | Технологии |
|
||||||
|-----------|-----------|
|
|-----------|-----------|
|
||||||
| API Gateway | FastAPI 0.111, Python 3.11, SQLAlchemy 2.0, Alembic |
|
| API Gateway | FastAPI 0.111, Python 3.11, SQLAlchemy 2.0, Alembic |
|
||||||
| GPU Worker | sentence-transformers, FAISS-GPU (IVFFlat), Ollama (llama3:8b) |
|
| GPU Worker | sentence-transformers, FAISS-CPU (IndexIDMap2 · IndexFlatIP), Ollama (qwen2.5:7b) |
|
||||||
| Indexer | PyMuPDF, python-docx, Winnowing, MinHash LSH |
|
| Indexer | PyMuPDF, python-docx, Winnowing, MinHash LSH |
|
||||||
| Очереди | RabbitMQ (брокер) + Celery 5 (воркеры) + Redis (результаты) |
|
| Очереди | RabbitMQ (брокер) + Celery 5 (воркеры) + Redis (результаты) |
|
||||||
| База данных | PostgreSQL 16 |
|
| База данных | PostgreSQL 16 |
|
||||||
| Поиск | Elasticsearch 8 (BM25) + FAISS GPU (cosine) |
|
| Поиск | Elasticsearch 8 (BM25) + FAISS (cosine, IndexFlatIP) |
|
||||||
| Хранилище | MinIO (S3-совместимый) |
|
| Хранилище | MinIO (S3-совместимый) |
|
||||||
| Frontend | React 18, Vite, TypeScript, TailwindCSS, Zustand, React Query v5 |
|
| Frontend | React 18, Vite, TypeScript, TailwindCSS, Zustand, React Query v5 |
|
||||||
|
|
||||||
## Проверка плагиата (4 уровня)
|
## Проверка плагиата (4 уровня)
|
||||||
|
|
||||||
1. **Winnowing + MinHash** (~мс) — точное совпадение по fingerprints
|
1. **Winnowing** — точные/частичные совпадения по fingerprint'ам (xxHash + скользящее окно)
|
||||||
2. **n-граммы + Jaccard** (~сек) — нечёткое совпадение
|
2. **MinHash LSH** — нечёткие совпадения (шинглы + Jaccard, индекс в общем Redis)
|
||||||
3. **FAISS GPU cosine** (~мс) — семантическое сходство (порог 0.75)
|
3. **FAISS cosine** — семантическое сходство (порог 0.75; IndexFlatIP на нормированных эмбеддингах)
|
||||||
4. **Ollama Llama3** (~2сек) — LLM анализ парафраза (confidence > 0.7)
|
4. **Ollama qwen2.5:7b** — LLM-анализ парафраза (порог confidence 0.7)
|
||||||
|
|
||||||
## Тарифные планы
|
## Тарифные планы
|
||||||
|
|
||||||
@@ -159,6 +159,40 @@ make migrate
|
|||||||
|
|
||||||
Nginx работает внутри контейнера (`docker-compose.prod.yml`, сервис `nginx`, Dockerfile в `infra/nginx/Dockerfile`) — собирает `services/frontend` в статику и отдаёт её вместе с проксированием `/api/`, `/ws/` на `api:8000` по конфигу `infra/nginx/nginx.conf`. Контейнер монтирует `/etc/letsencrypt` с хоста как read-only — сертификат обновляется на хосте (`certbot renew`), контейнер просто читает его.
|
Nginx работает внутри контейнера (`docker-compose.prod.yml`, сервис `nginx`, Dockerfile в `infra/nginx/Dockerfile`) — собирает `services/frontend` в статику и отдаёт её вместе с проксированием `/api/`, `/ws/` на `api:8000` по конфигу `infra/nginx/nginx.conf`. Контейнер монтирует `/etc/letsencrypt` с хоста как read-only — сертификат обновляется на хосте (`certbot renew`), контейнер просто читает его.
|
||||||
|
|
||||||
|
## Тестирование и качество кода
|
||||||
|
|
||||||
|
Перед деплоем CI (`.gitea/workflows/deploy.yml`, job `test`) прогоняет два гейта,
|
||||||
|
и `deploy` стартует, только если оба зелёные — кривой код в прод не уезжает:
|
||||||
|
|
||||||
|
1. **Линт** — `ruff` (весь Python) + `mypy` (чистая доменная логика).
|
||||||
|
Конфиги: [`ruff.toml`](ruff.toml), [`mypy.ini`](mypy.ini).
|
||||||
|
2. **Юнит-тесты** — `pytest` по сервисам: 73 теста на ядро детекции и форматирования,
|
||||||
|
без внешней инфры (БД/Redis/GPU/Ollama замоканы либо не нужны).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make lint # ruff + mypy в изолированном контейнере
|
||||||
|
make lint-fix # авто-исправления ruff
|
||||||
|
make test # все юнит-тесты в контейнерах
|
||||||
|
make test-one SVC=worker-gost # тесты одного сервиса
|
||||||
|
```
|
||||||
|
|
||||||
|
Всё гоняется в `python:3.11-slim` (не засоряя хост) через
|
||||||
|
[`scripts/run_lint.sh`](scripts/run_lint.sh) и [`scripts/run_tests.sh`](scripts/run_tests.sh).
|
||||||
|
|
||||||
|
**Что покрыто.** Чистая логика вынесена из Celery-задач в отдельные тестируемые
|
||||||
|
модули (доменная логика отдельно от оркестрации):
|
||||||
|
|
||||||
|
| Слой | Модуль | Тестов |
|
||||||
|
|------|--------|:------:|
|
||||||
|
| L1 — точные совпадения | `worker-indexer/app/algorithms/winnowing.py` | 13 |
|
||||||
|
| L2 — нечёткие (MinHash LSH) | `worker-indexer/app/algorithms/minhash.py` | 6 |
|
||||||
|
| Разбиение на фрагменты | `worker-indexer/app/fragments.py` | 5 |
|
||||||
|
| L3 — семантический индекс | `worker-gpu/app/faiss_manager.py` | 5 |
|
||||||
|
| L4 — LLM-парафраз | `worker-gpu/app/ollama_client.py` | 12 |
|
||||||
|
| Итоговый % плагиата | `worker-gpu/app/scoring.py` | 8 |
|
||||||
|
| ГОСТ 7.1 / 7.0.5 | `worker-gost/app/formatters/` | 17 |
|
||||||
|
| Список литературы | `worker-gost/app/bibliography.py` | 7 |
|
||||||
|
|
||||||
## Лицензия
|
## Лицензия
|
||||||
|
|
||||||
MIT
|
MIT
|
||||||
|
|||||||
Reference in New Issue
Block a user