---
id: logic-rag-indexing
title: Индексация файлов в RAG
doc_type: logic_block
domain: rag
status: draft
owner: system-analyst
source_of_truth: code
related_docs:
  - arch-rag-package
  - entity-rag-session
  - entity-rag-index-job
  - api-rag-session-create
  - api-rag-session-changes
related_code:
  - src/app/modules/rag/indexing_service.py
  - src/app/modules/rag/services/rag_service.py
  - src/app/modules/rag/indexing/docs/pipeline.py
  - src/app/modules/rag/indexing/code/pipeline.py
  - src/app/modules/rag/persistence/document_repository.py
entities:
  - RagSession
  - IndexJob
  - RagDocument
tags:
  - rag
  - indexing
  - snapshot
  - changes
---
# Индексация файлов в RAG

## Summary
- Purpose: превратить входной список файлов в набор индексируемых `RagDocument` и сохранить их в persistence.
- Trigger: создание RAG-сессии, запрос изменений, internal snapshot/changes endpoints.
- Inputs: `rag_session_id`, файлы snapshot или changed_files, progress callback.
- Outputs: обновлённые записи в `rag_chunks`, `rag_session_chunk_map`, статистика indexed/failed/cache hit/cache miss.
- Main entities: `RagSession`, `IndexJob`, `RagDocument`.
- Main dependencies: `IndexingOrchestrator`, `RagService`, `DocsIndexingPipeline`, `CodeIndexingPipeline`, `GigaChatEmbedder`, `RagRepository`.
- Side effects: SQL delete/insert, cache write, SSE events, job status update.
- Source of truth: `src/app/modules/rag/indexing_service.py`, `src/app/modules/rag/services/rag_service.py`.

## Назначение

Блок обеспечивает управляемую индексацию файлов проекта в многослойный RAG-индекс. Он должен одинаково поддерживать полный snapshot и инкрементальные изменения, не допуская гонок внутри одной `rag_session_id`.

## Контекст

Индексация запускается через HTTP API модуля. `IndexingOrchestrator` отвечает за job lifecycle и progress events, а `RagService` за фактическую переработку файлов в документы. Для уменьшения стоимости embeddings используется cache по содержимому blob.

## Технический use case

### Основной сценарий

1. API создаёт `IndexJob` и передаёт управление в `IndexingOrchestrator`.
2. `IndexingOrchestrator` фильтрует входной набор, ставит статус `running`, публикует стартовое событие и захватывает lock по `rag_session_id`.
3. `RagService` определяет `repo_id`, фильтрует индексируемые файлы, проверяет cache по `blob_sha` и либо переиспользует документы, либо заново строит docs/code слои.
4. Для новых документов `RagService` добавляет file metadata, запрашивает embeddings батчами и сохраняет документы через `RagRepository`.
5. `IndexingOrchestrator` обновляет job counters, публикует финальный `index_status` и `terminal`.

### Альтернативные ветки

- Для `changes` операции с `op=delete` только удаляют документы по `path`, без повторной сборки.
- Если файл не поддержан ни docs-, ни code-pipeline, сервис делает fallback в docs pipeline.
- При временном сбое индексации `RetryExecutor` повторяет операцию; после исчерпания попыток job получает `error`.

## Функциональные требования

### Preconditions
- `rag_session_id` уже существует либо создаётся до запуска indexing job.
- Файлы передаются в виде словарей, совместимых со схемами `FileSnapshot` или `ChangedFile`.
- Для cache reuse у файла должен быть `content_hash` или доступный `content`.

### Processing rules
- Snapshot перед записью выполняет полную замену документов сессии через `replace_documents`.
- Incremental changes отделяет `delete_paths` от upsert-файлов и применяет изменения через `apply_document_changes`.
- `repo_id` выводится из `project_id` у сессии, а при отсутствии сессии fallback равен `rag_session_id`.
- Для поддерживаемого markdown строятся docs-слои `D1-D4`.
- Для поддерживаемого Python-кода строятся code-слои `C0-C4`.
- Каждый документ получает metadata файла: `blob_sha`, `repo_id`, `artifact_type`, `section`, `doc_id`, `owner`, `system_component`, `last_modified`, `staleness_score`.

### Validation rules
- До индексации snapshot/changes проходят фильтрацию через `filter_snapshot_files` и `filter_changes_for_indexing`.
- Пустые или неподходящие файлы исключаются из обрабатываемого набора.
- Вектор сохраняется только если размерность embedding совпадает с размерностью поля `vector` при retrieval.

### Output / result rules
- Результат операции всегда выражается четырьмя счётчиками: `indexed_files`, `failed_files`, `cache_hit_files`, `cache_miss_files`.
- Для snapshot весь набор документов сессии после операции должен соответствовать текущему переданному snapshot.
- Для changes в индексе должны остаться только документы по актуальному состоянию изменённых путей.

### Side effects
- Удаление и вставка строк в `rag_chunks`.
- Запись `rag_session_chunk_map` для документов, имеющих `repo_id` и `blob_sha`.
- Сохранение cache в `rag_blob_cache` и `rag_chunk_cache`.
- Публикация SSE-событий прогресса и завершения задачи.

## Ограничения и условия вызова

- Одновременно может выполняться только одна indexing operation на `rag_session_id`.
- Code indexing работает только для Python файлов, распознаваемых `PythonFileFilter`.
- Docs indexing рассчитывает на markdown с возможным YAML frontmatter.
- Метод `replace_documents` делает жёсткую замену индекса сессии и не подходит для конкурентного merge разных snapshot-источников.

## Нефункциональные требования

### Security
- Модуль не валидирует источник файлов и не выполняет контентную санацию сверх собственных парсеров.

### Observability
- Logs: фиксируются skipped files и режим обработки `cache` / `embed`.
- Metrics: отдельные счётчики не выделены, но статистика сохраняется в job.
- Traces: не реализованы.
- Audit: `rag_index_jobs` и `rag_session_chunk_map` образуют журнал выполнения и происхождения chunk.

### Reliability
- `asyncio.Lock` сериализует операции в рамках одной сессии.
- `RetryExecutor` покрывает временные ошибки `TimeoutError`, `ConnectionError`, `OSError`.

### Performance
- Embeddings обрабатываются батчами.
- Cache hit исключает повторный парсинг и повторный вызов embedder.

## Связанные API / UI / integration points

- `POST /api/rag/sessions`
- `POST /api/rag/sessions/{rag_session_id}/changes`
- `POST /internal/rag/index/snapshot`
- `POST /internal/rag/index/changes`

## Связанные сущности

- `RagSession`
- `IndexJob`
- `RagDocument`

## Связанный код

### Files
- `src/app/modules/rag/indexing_service.py`
- `src/app/modules/rag/services/rag_service.py`
- `src/app/modules/rag/indexing/docs/pipeline.py`
- `src/app/modules/rag/indexing/code/pipeline.py`
- `src/app/modules/rag/persistence/document_repository.py`

### Symbols
- `IndexingOrchestrator.enqueue_snapshot`
- `IndexingOrchestrator.enqueue_changes`
- `IndexingOrchestrator._run_with_project_lock`
- `RagService.index_snapshot`
- `RagService.index_changes`
- `RagService._index_files`

## Связанные документы

- `arch-rag-package`
- `entity-rag-session`
- `entity-rag-index-job`
- `api-rag-session-create`
- `api-rag-session-changes`

## История изменений

| Date | Source | Changes |
|------|--------|---------|
| 2026-03-13 | code | Описана фактическая логика snapshot и incremental indexing пакета `rag`. |
