# Наполнение корпуса — 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 из списка, чистка ``/HTML-сущностей. Проверено вживую (5/5 тем) + юнит-тесты (`scripts/parsers/tests/`), в гейте CI. - **Прод-путь готов**: `index.run_parser(source_id)` уже умеет `cyberleninka` и `openalex` c `lang=ru`. - **Сидер источников**: `scripts/seed_ru_sources.py` — 30 студенческих дисциплин. ## Запуск русской заливки ```bash # 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 русских документов на первый заход. ## Проверка результата ```sql 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](ARCHITECTURE.md) и [DR-HA.md](DR-HA.md).