Files
anti-plagiarism/docs/INGESTION.md
jze9 fc40793f4d
Some checks failed
Deploy / deploy (push) Has been cancelled
Deploy / test (push) Has been cancelled
docs: актуализировать документацию (Infisical, OpenRouter, bge-m3, PMC) + чистка
Документация сильно разошлась с кодом за последние недели работы — привёл в
соответствие ARCHITECTURE.md, README, DIAGRAM.md, INGESTION.md:
- LLM (L4) и эмбеддинги (L3) теперь переключаемые бэкенды (LLM_BACKEND,
  EMBED_BACKEND), а не жёстко Ollama/qwen2.5:7b — старая модель эмбеддингов
  (768d mpnet) заменена на bge-m3 (1024d); L4 может идти через OpenRouter
  (DeepSeek) с прокси singbox для обхода геоблокировки.
- .env на проде больше не редактируется руками — на каждом деплое
  генерируется из Infisical; старая инструкция "cp .env.example .env; nano
  .env" вводила в заблуждение (правки терялись бы на следующем деплое).
- README "Три docker-compose файла"/deploy разделы противоречили реальности:
  фронтенд+TLS реально раздаёт хостовой nginx на CT 102, не докеризованный
  nginx-сервис из compose (тот не запускается вообще).
  добавлен PMC-парсер, self-match исключение объяснено, число тестов (113)
  синхронизировано между файлами (было 82/122 в разных местах).
- INGESTION.md: снимок "42K доков, 0 русских" от 12.08 заменён актуальным
  (165K доков, ru теперь большинство) — иначе документ откровенно врёт.
- Diagram: узлы под текущую топологию (embedding-gpu, OpenRouter, Infisical).

Заодно, раз перепроверял код на соответствие докам:
- Удалён мёртвый и битый эндпоинт GET /reports/{task_id} — фильтровал по
  внутреннему Task.id вместо public_id (никогда не мог сработать через
  обычный клиентский поток), фронтенд его всё равно не вызывал —
  функциональность полностью дублирует рабочий GET /tasks/{public_id}.
- Убран мёртвый конфиг FAISS_NLIST/FAISS_NPROBE (worker-gpu/config.py) —
  индекс всегда IndexFlatIP, IVF нигде не строится, эти поля ничего не делали.
2026-08-27 16:51:31 +05:00

4.6 KiB
Raw Blame History

Наполнение корпуса — runbook

Текущее состояние (на 2026-08-27)

  • 165 480 документов, русский теперь большинство: ru 97 507, en 67 646, остальные языки — единицы/десятки. Проблема «не с чем сравнивать русские работы» из более ранней версии этого документа закрыта.
  • По источникам: CyberLeninka 97 506, OpenAlex 49 218, PMC 10 451, arXiv 8 304, user_submission (проверенные пользователями работы, не источник для сравнения сами с собой — см. ARCHITECTURE.md §7) 1.
  • Добавлен 4-й парсер — PMC (PubMed Central, scripts/parsers/pmc.py), англоязычные научные статьи открытого доступа.
  • Массовое расширение по дисциплинам теперь двумя сидерами: seed_ru_sources.py (русскоязычные, CyberLeninka/OpenAlex lang=ru) и scripts/seed_broad_corpus.py (англоязычные — OpenAlex/arXiv/PMC по широкому списку дисциплин, добавлен позже первой волны).
  • Известный операционный риск при массовой докачке: retry-бэкофф на 429 от OpenAlex не должен по сумме ожиданий превышать consumer_timeout RabbitMQ (по умолчанию 1800с) — иначе брокер рвёт канал до того, как таск успевает сдаться, и worker-indexer уходит в бесконечный краш-луп на редоставленном сообщении (см. scripts/parsers/openalex.py, MAX_RATE_LIMIT_RETRIES).

Что подготовлено

  • Парсер CyberLeninka починен (scripts/parsers/cyberleninka.py): раньше слал GET на /api/search → HTTP 405; теперь POST с JSON-телом (mode=articles), authors из списка, чистка <b>/HTML-сущностей. Проверено вживую (5/5 тем) + юнит-тесты (scripts/parsers/tests/), в гейте CI.
  • Прод-путь готов: index.run_parser(source_id) уже умеет cyberleninka и openalex c lang=ru.
  • Сидер источников: scripts/seed_ru_sources.py — 30 студенческих дисциплин.

Запуск русской заливки

# 1. (на app-хосте / в контейнере worker-indexer, где есть psycopg2 и прод-.env
#    — .env на проде теперь генерируется из Infisical на каждом деплое, см.
#    ARCHITECTURE.md §10, руками его не редактировать)
#    Посмотреть план:
python scripts/seed_ru_sources.py
#    Создать источники в parse_sources (лимит на дисциплину):
python scripts/seed_ru_sources.py --apply --limit 500

# 2. Проверить пару источников на темпе/качестве, затем запустить заливку:
#    • Админ-панель → «Источники» → «Запустить», ЛИБО
#    • Celery: index.run_parser.delay(source_id) по каждому id

Заливка сама: fetch (rate-limit 1 req/s) → add_document (дедуп по ext_id, fingerprints L1, MinHash L2) → батч-эмбеддинги gpu.embed_documents (L3). ~30 тем × 500 ≈ 15K русских документов на первый заход.

Проверка результата

SELECT lang, count(*) FROM documents GROUP BY lang ORDER BY 2 DESC;   -- должен появиться ru
SELECT source, count(*) FROM documents WHERE source='cyberleninka';   -- > 0

Масштаб (следующий уровень)

  • Больше тем + выше --limit; добавить OpenAlex lang=ru (качество ниже — англ. заголовки с меткой ru).
  • Для миллионов — bulk (снапшот OpenAlex на S3), а не постраничный API.
  • На масштабе обязателен VECTOR_BACKEND=qdrant (FAISS flat не тянет), а таблица fingerprints (уже ~88M строк на 165K доков — партиционирование стоит планировать заранее, не постфактум) потребует партиционирования. См. ARCHITECTURE.md и DR-HA.md.