Files
llm/docs/runbooks/1c-rag.md
T

287 lines
10 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.
# 1C RAG
Цель: подготовить локальный корпус знаний по 1С для поиска и ответов без дообучения модели.
## Principles
- Сначала RAG и инструменты, потом fine-tuning.
- Не загружать в репозиторий базы, выгрузки, приватные документы, персональные данные и секреты.
- Не выдумывать метаданные конкретной базы 1С. Если нужны реквизиты или объекты, использовать tool boundary.
## Add Sources
Кладем материалы в:
```text
plugins/1c/rag/sources
```
Поддерживаемые форматы:
- `.md`
- `.txt`
- `.bsl`
- `.os`
## Prepare Corpus
```powershell
python scripts/validate_1c_rag_sources.py --print
python scripts/prepare_1c_rag_corpus.py
```
Результат:
```text
plugins/1c/datasets/prepared/rag_corpus.jsonl
plugins/1c/datasets/prepared/rag_manifest.json
```
Этот файл не коммитится.
## Test With Example
```powershell
python scripts/prepare_1c_rag_corpus.py --source-dir plugins/1c/rag/examples --output plugins/1c/datasets/prepared/rag_corpus.example.jsonl
```
## Build Search Index
```powershell
python scripts/build_1c_rag_index.py
```
Для синтетического примера:
```powershell
python scripts/build_1c_rag_index.py --corpus plugins/1c/datasets/prepared/rag_corpus.example.jsonl --output plugins/1c/datasets/prepared/rag_index.example.json
```
## Build Vector Index
```powershell
python scripts/build_1c_rag_vector_index.py
```
Результат:
```text
plugins/1c/datasets/prepared/rag_vector_index.sqlite
```
Индекс хранит `corpus_hash`, `embedding_model`, размерность, дату сборки и метаданные чанков.
Текущий provider `local-hashing-v1` - это локальный deterministic vector baseline, а не нейросемантическая embedding-модель. Он нужен, чтобы отладить формат, freshness и hybrid retrieval без скачивания модели. Нейросемантический provider подключается следующим слоем без смены SQLite-схемы.
OpenAI-compatible embedding endpoint:
```powershell
$env:EMBEDDING_API_KEY = "<token-if-needed>"
python scripts/build_1c_rag_vector_index.py `
--embedding-provider openai-compatible `
--embedding-model "<embedding-model-name>" `
--embedding-base-url "http://docker-gpu.cin.su:8000" `
--embedding-api-key-env EMBEDDING_API_KEY
```
Для поиска по такому индексу query embedding должен считаться тем же provider/model:
```powershell
python scripts/search_1c_rag_hybrid.py "реквизиты справочника номенклатура" `
--profile metadata `
--embedding-base-url "http://docker-gpu.cin.su:8000" `
--embedding-api-key-env EMBEDDING_API_KEY
```
Ключ не пишется в индекс и читается только из переменной окружения.
Полная сборка knowledge base теперь строит corpus, lexical index и vector index:
```powershell
python scripts/build_1c_knowledge_base.py --include-example-bsl
```
Если vector index временно не нужен:
```powershell
python scripts/build_1c_knowledge_base.py --skip-vector-index
```
## Search
```powershell
python scripts/search_1c_rag.py "метаданные справочника" --index plugins/1c/datasets/prepared/rag_index.example.json
```
Поиск использует локальный lexical BM25-подобный индекс с нормализацией 1С-терминов и алиасами вроде `1с/bsl`, `справочник/catalog`, `метаданные/metadata`.
Профили RAG лежат в:
```text
plugins/1c/rag/profiles.yaml
```
Основные профили:
- `auto`
- `general`
- `metadata`
- `bsl`
- `query`
- `safe-change`
`auto` выбирает профиль по тексту вопроса. Например, вопросы про реквизиты уходят в `metadata`, вопросы про процедуры и ошибки BSL - в `bsl`, вопросы с `ВЫБРАТЬ` - в `query`.
При подготовке корпуса источники получают смысловой `source_type`:
- `metadata`
- `bsl`
- `query`
- `safety`
- `docs`
Полезные параметры:
```powershell
python scripts/search_1c_rag.py "реквизиты справочника номенклатура" `
--index plugins/1c/datasets/prepared/rag_index.example.json `
--profile metadata `
--limit 5 `
--candidate-limit 30 `
--dedupe-by-document
```
Vector search:
```powershell
python scripts/search_1c_rag_vector.py "реквизиты справочника номенклатура" --profile metadata --limit 5
```
Hybrid search объединяет lexical и vector результаты через reciprocal-rank fusion:
```powershell
python scripts/search_1c_rag_hybrid.py "реквизиты справочника номенклатура" --profile metadata --limit 5
```
Если `vector_freshness.status = stale`, нужно пересобрать vector index после обновления corpus.
## Ask With Context
Без вызова модели, только сборка prompt:
```powershell
python scripts/ask_1c_rag.py "Какие реквизиты есть у справочника Номенклатура?" --index plugins/1c/datasets/prepared/rag_index.example.json --print-prompt
```
С явным профилем:
```powershell
python scripts/ask_1c_rag.py "Проверь BSL-код процедуры ПередЗаписью" --profile bsl --print-prompt
```
Проверка обязательных правил в prompt:
```powershell
python scripts/check_1c_rag_prompt.py
```
Проверка качества поиска по smoke-набору:
```powershell
python scripts/check_1c_rag_quality.py --print
```
Проверка auto-routing профилей:
```powershell
python scripts/check_1c_rag_profiles.py --print
```
С запущенной моделью:
```powershell
python scripts/ask_1c_rag.py "Какие реквизиты есть у справочника Номенклатура?" --index plugins/1c/datasets/prepared/rag_index.example.json --base-url http://docker-gpu.cin.su:8000 --model qwen3-4b-instruct
```
## Tool Contract
Контракт инструментов:
```text
plugins/1c/tools/tool-contract.yaml
```
Главное правило: модель не должна придумывать структуру базы 1С. Если ответ зависит от метаданных, сначала нужен вызов инструмента.
## Metadata Snapshot Flow
Для проверки RAG на структуре 1С можно сгенерировать source из metadata snapshot:
```powershell
python scripts/validate_1c_metadata_snapshot.py plugins/1c/metadata/examples/metadata.example.json
python scripts/convert_1c_metadata_to_rag.py --input plugins/1c/metadata/examples/metadata.example.json --output plugins/1c/rag/sources/metadata.example.generated.md
python scripts/build_1c_knowledge_base.py --include-example-bsl
python scripts/ask_1c_rag.py "Какие реквизиты есть у справочника Номенклатура?" --print-prompt
```
`build_1c_knowledge_base.py` выполняет валидацию snapshot, конвертацию источников, сборку corpus и индекса за один проход.
Перед сборкой corpus он также запускает `validate_1c_rag_sources.py`, чтобы заблокировать неподдерживаемые расширения, пустые файлы и вероятные секреты.
Manifest содержит source path, source type, file type, content hash и число чанков. Его удобно использовать для аудита и будущего инкрементального обновления индекса.
Проверить, не устарел ли manifest относительно `plugins/1c/rag/sources`:
```powershell
python scripts/check_1c_rag_freshness.py --print
```
Статус `stale` означает, что появились новые файлы, изменился hash, был удален источник или изменился `source_type`. После этого нужно пересобрать knowledge base.
Проверить, не устарел ли vector index относительно corpus:
```powershell
python scripts/check_1c_rag_vector_freshness.py --print
```
## Semantic Cache Embedding Worker
Для live 1C-адаптера semantic cache заполняется отдельно от RAG corpus. Адаптер отдает pending документы с `document_id` и `content_sha1`; worker считает embedding и вызывает `semantic.cache.embedding.upsert`. Если документ изменился, адаптер отвергнет embedding по `content_sha1`.
Dry-run:
```powershell
python scripts/embed_1c_semantic_cache.py --base-id upo_test --kind Template --limit 20 --dry-run --json
```
Запись baseline-векторов:
```powershell
python scripts/embed_1c_semantic_cache.py --base-id upo_test --kind Template --limit 20
```
Поиск по semantic cache с автоматически рассчитанным query embedding:
```powershell
python scripts/search_1c_semantic_cache.py "ОбластьШапка" --base-id upo_test --kind Template --limit 5 --validate-candidates
```
Если нужно перед поиском автоматически дозаполнить pending embeddings:
```powershell
python scripts/search_1c_semantic_cache.py "ОбластьШапка" --base-id upo_test --kind Template --embed-pending --validate-candidates
```
С OpenAI-compatible embedding endpoint:
```powershell
$env:EMBEDDING_API_KEY = "<token-if-needed>"
python scripts/embed_1c_semantic_cache.py `
--base-id upo_test `
--kind Template `
--embedding-provider openai-compatible `
--embedding-model "<embedding-model-name>" `
--embedding-base-url "http://docker-gpu.cin.su:8000" `
--embedding-api-key-env EMBEDDING_API_KEY
```
Semantic cache остается candidate-only: перед программными изменениями использовать `validate_candidates=true` или live read-selector из результата.