Фикс состояния
This commit is contained in:
323
rag_structure_report.md
Normal file
323
rag_structure_report.md
Normal file
@@ -0,0 +1,323 @@
|
||||
# 0) TL;DR (10–15 строк)
|
||||
|
||||
- В `intent_router_v2` графы задаются как строковые `graph_id`: `CodeQAGraph` и `DocsQAGraph` (`app/modules/rag/intent_router_v2/intent/graph_id_resolver.py:4`, класс `GraphIdResolver.resolve`).
|
||||
- Точка входа роутера: `IntentRouterV2.route(...)` (`app/modules/rag/intent_router_v2/router.py:35`, класс `IntentRouterV2`).
|
||||
- Отдельные классы/функции с именами `CodeQAGraph` и `DocsQAGraph` в `app/` не найдены (поиск по коду).
|
||||
- В тестовом CLI-пайплайне выполнение идет через `IntentRouterRagPipelineRunner.run_case(...)` (`tests/pipeline_intent_rag/helpers/pipeline_runner.py:45`) и `PipelineRuntime.run_*` (`tests/pipeline_intent_rag/helpers/runtime.py:31`).
|
||||
- Контракт роутера возвращается моделью `IntentRouterResult` (`app/modules/rag/intent_router_v2/models.py:139`) и включает `intent`, `retrieval_profile`, `query_plan`, `retrieval_spec`, `retrieval_constraints`, `symbol_resolution`, `evidence_policy`.
|
||||
- `sub_intent`, `symbol_kind_hint`, `symbol_candidates`, `path_hints`, `doc_scope_hints` находятся внутри `query_plan` (`app/modules/rag/intent_router_v2/models.py:43`).
|
||||
- Топ-слои retrieval задаются фабрикой `RetrievalSpecFactory` (`app/modules/rag/intent_router_v2/retrieval/retrieval_spec_factory.py:9`).
|
||||
- Реально индексируемые/используемые слои: `C0..C3`, `D1..D4` (`app/modules/rag/indexing/code/pipeline.py:37`, `app/modules/rag/indexing/docs/pipeline.py:24`, `app/modules/rag/intent_router_v2/retrieval/retrieval_spec_factory.py:10`).
|
||||
- В enum есть `C4..C6`, но build/retrieval-код для них в `app/modules/rag` (кроме `README` и `enums.py`) не найден (`app/modules/rag/contracts/enums.py:13`).
|
||||
- Слой `F0` в `app/` и `tests/` не найден (поиск по коду).
|
||||
- Ранжирование retrieval: `lexical_rank -> test_penalty -> layer_rank -> distance` (`app/modules/rag/persistence/retrieval_statement_builder.py:59`).
|
||||
- В `pipeline_intent_rag` evidence gate отсутствует; в `chat` есть `CodeExplainEvidenceGate(min_excerpts=2)` (`app/modules/chat/evidence_gate.py:15`).
|
||||
|
||||
## 1) High-level pipeline (диаграмма текстом)
|
||||
|
||||
### CodeQAGraph
|
||||
|
||||
`Router -> Plan -> Retrieval per layer -> Merge/Rank -> Evidence gate -> LLM prompt builder`
|
||||
|
||||
- Router: `IntentRouterV2.route` (`app/modules/rag/intent_router_v2/router.py:35`, класс `IntentRouterV2`).
|
||||
Определяет `intent`, `graph_id`, `query_plan`, `retrieval_spec`, `retrieval_constraints`, `symbol_resolution`.
|
||||
- Plan: `QueryPlanBuilder.build` (`app/modules/rag/intent_router_v2/analysis/query_plan_builder.py:50`, класс `QueryPlanBuilder`).
|
||||
Извлекает anchors, `sub_intent`, symbol/path/doc hints.
|
||||
- Retrieval per layer: `RetrievalSpecFactory.build` (`app/modules/rag/intent_router_v2/retrieval/retrieval_spec_factory.py:74`) + `RagDbAdapter.retrieve` (`tests/pipeline_intent_rag/helpers/rag_db_adapter.py:41`).
|
||||
Для `CODE_QA` выбираются `C*` слои; выполняется запрос в БД с фильтрами.
|
||||
- Merge/Rank: `RetrievalStatementBuilder.build_retrieve` (`app/modules/rag/persistence/retrieval_statement_builder.py:9`).
|
||||
Все выбранные слои читаются одним SQL и сортируются по `lexical_rank`, `test_penalty`, `layer_rank`, `distance`.
|
||||
- Evidence gate: в цепочке `tests/pipeline_intent_rag` не найден.
|
||||
Для отдельного code-explain чата есть `CodeExplainEvidenceGate.evaluate` (`app/modules/chat/evidence_gate.py:19`).
|
||||
- LLM prompt builder: в режиме `full_chain` — `GigaChatAnswerer.answer`/`_format_context` (`tests/pipeline_intent_rag/helpers/llm_answerer.py:15`, `:27`).
|
||||
Формируется prompt из вопроса и первых RAG-строк.
|
||||
|
||||
### DocsQAGraph
|
||||
|
||||
`Router -> Plan -> Retrieval per layer -> Merge/Rank -> Evidence gate -> LLM prompt builder`
|
||||
|
||||
- Router: `IntentRouterV2.route` (`app/modules/rag/intent_router_v2/router.py:35`).
|
||||
Для `DOCS_QA` ставит `retrieval_profile="docs"` (`app/modules/rag/intent_router_v2/router.py:112`).
|
||||
- Plan: `QueryPlanBuilder.build` (`app/modules/rag/intent_router_v2/analysis/query_plan_builder.py:50`).
|
||||
Для `DOCS_QA` принудительно `sub_intent="EXPLAIN"` (`app/modules/rag/intent_router_v2/analysis/query_plan_builder.py:78`).
|
||||
- Retrieval per layer: `RetrievalSpecFactory.build` (`app/modules/rag/intent_router_v2/retrieval/retrieval_spec_factory.py:74`) + `RagDbAdapter.retrieve` (`tests/pipeline_intent_rag/helpers/rag_db_adapter.py:41`).
|
||||
Для docs выбираются `D*` слои; при `path_scope` используется docs-scoped набор (`app/modules/rag/intent_router_v2/retrieval/retrieval_spec_factory.py:97`).
|
||||
- Merge/Rank: `RetrievalStatementBuilder.build_retrieve` (`app/modules/rag/persistence/retrieval_statement_builder.py:9`).
|
||||
Механизм ранжирования тот же, что и для code.
|
||||
- Evidence gate: для docs в `pipeline_intent_rag` не найден.
|
||||
- LLM prompt builder: в `full_chain` тот же `GigaChatAnswerer` (`tests/pipeline_intent_rag/helpers/llm_answerer.py:15`).
|
||||
|
||||
## 2) Router contract (фактическое API)
|
||||
|
||||
### Пример JSON (code)
|
||||
|
||||
```json
|
||||
{
|
||||
"intent": "CODE_QA",
|
||||
"sub_intent": "EXPLAIN",
|
||||
"retrieval_profile": "code",
|
||||
"symbol_kind_hint": "class",
|
||||
"symbol_candidates": ["Context"],
|
||||
"path_hints": [],
|
||||
"path_scope": [],
|
||||
"doc_scope_hints": [],
|
||||
"layers": ["C1_SYMBOL_CATALOG", "C0_SOURCE_CHUNKS", "C2_DEPENDENCY_GRAPH"],
|
||||
"retrieval_constraints": {
|
||||
"include_globs": ["src/**"],
|
||||
"exclude_globs": ["tests/**", "**/test_*.py", "**/*_test.py"],
|
||||
"prefer_globs": [],
|
||||
"test_file_globs": [],
|
||||
"test_symbol_patterns": [],
|
||||
"max_candidates": 20,
|
||||
"fuzzy_symbol_search": {"enabled": true, "max_distance": 2, "top_k": 5}
|
||||
},
|
||||
"symbol_resolution": {
|
||||
"status": "pending",
|
||||
"resolved_symbol": null,
|
||||
"alternatives": ["Context"],
|
||||
"confidence": 0.0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Пример JSON (docs)
|
||||
|
||||
```json
|
||||
{
|
||||
"intent": "DOCS_QA",
|
||||
"sub_intent": "EXPLAIN",
|
||||
"retrieval_profile": "docs",
|
||||
"symbol_kind_hint": "unknown",
|
||||
"symbol_candidates": [],
|
||||
"path_hints": ["README_DEPLOY.md"],
|
||||
"path_scope": ["README_DEPLOY.md"],
|
||||
"doc_scope_hints": ["README_DEPLOY.md", "README*", "docs/**", "**/*.md"],
|
||||
"layers": ["D3_SECTION_INDEX", "D2_FACT_INDEX"],
|
||||
"retrieval_constraints": {
|
||||
"include_globs": ["README_DEPLOY.md", "docs/**", "README*", "**/*.md"],
|
||||
"exclude_globs": [".venv/**", "node_modules/**", "**/*.bin", "**/*.png", "**/*.jpg"],
|
||||
"prefer_globs": [],
|
||||
"test_file_globs": [],
|
||||
"test_symbol_patterns": [],
|
||||
"max_candidates": 20,
|
||||
"fuzzy_symbol_search": {"enabled": true, "max_distance": 2, "top_k": 5}
|
||||
},
|
||||
"symbol_resolution": {
|
||||
"status": "not_requested",
|
||||
"resolved_symbol": null,
|
||||
"alternatives": [],
|
||||
"confidence": 0.0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Поля контракта
|
||||
|
||||
- `intent`, `retrieval_profile`: формируются в `IntentRouterV2.route` (`app/modules/rag/intent_router_v2/router.py:35`).
|
||||
- `sub_intent`, `symbol_kind_hint`, `symbol_candidates`, `path_hints`, `doc_scope_hints`: внутри `QueryPlan` (`app/modules/rag/intent_router_v2/models.py:43`), заполняются в `QueryPlanBuilder.build` (`app/modules/rag/intent_router_v2/analysis/query_plan_builder.py:50`).
|
||||
- `path_scope`: находится в `retrieval_spec.filters.path_scope`; строится `RetrievalFilterBuilder._path_scope` (`app/modules/rag/intent_router_v2/retrieval/retrieval_filter_builder.py:63`).
|
||||
- `layers`: отдельного top-level поля в `IntentRouterResult` нет; фактический источник — `retrieval_spec.layer_queries[].layer_id` (`app/modules/rag/intent_router_v2/models.py:121`, `:125`).
|
||||
- `retrieval_constraints`: модель `RetrievalConstraints` (`app/modules/rag/intent_router_v2/models.py:67`), заполняется в `RetrievalConstraintsFactory.build` (`app/modules/rag/intent_router_v2/retrieval/retrieval_constraints_factory.py:22`).
|
||||
- `symbol_resolution`: модель `SymbolResolution` (`app/modules/rag/intent_router_v2/models.py:79`), первичный статус задает `_initial_symbol_resolution` (`app/modules/rag/intent_router_v2/router.py:93`).
|
||||
|
||||
### `symbol_resolution` статусы и переходы
|
||||
|
||||
- Допустимые статусы: `not_requested`, `pending`, `resolved`, `ambiguous`, `not_found` (`app/modules/rag/intent_router_v2/models.py:15`).
|
||||
- Начальное состояние: `IntentRouterV2._initial_symbol_resolution` (`app/modules/rag/intent_router_v2/router.py:93`).
|
||||
- Изменение статуса в тестовом router+rag пайплайне: `_resolve_symbol` (`tests/pipeline_intent_rag/helpers/pipeline_runner.py:69`), где `pending` переходит в `resolved`/`ambiguous`/`not_found`.
|
||||
|
||||
### Где определены типы/схемы и где валидация
|
||||
|
||||
- Типы/схемы: `QueryPlan`, `RetrievalConstraints`, `SymbolResolution`, `RetrievalSpec`, `IntentRouterResult` в `app/modules/rag/intent_router_v2/models.py:43`, `:67`, `:79`, `:121`, `:139`.
|
||||
- Валидация: pydantic-модели с `ConfigDict(extra="forbid")` (например `app/modules/rag/intent_router_v2/models.py:44`, `:68`, `:80`, `:122`, `:140`), плюс валидаторы confidence (`app/modules/rag/intent_router_v2/models.py:37`, `:208`).
|
||||
|
||||
## 3) Layer inventory (что реально индексируется и как)
|
||||
|
||||
### 3.1 Code layers
|
||||
|
||||
#### C0_SOURCE_CHUNKS
|
||||
|
||||
- Назначение: фрагменты исходного кода для цитирования и lexical fallback.
|
||||
- Единица индексации: chunk.
|
||||
- Источник данных: AST-разбор (`ast.parse`) с fallback на оконную нарезку (`app/modules/rag/indexing/code/code_text/chunker.py:17`).
|
||||
- Схема записи:
|
||||
- Базовые поля документа: `layer`, `repo_id`, `commit_sha`, `path`, `title`, `text`, `span_start/end`, `metadata`, `embedding` (`app/modules/rag/contracts/documents.py:62`).
|
||||
- C0 metadata: `chunk_index`, `chunk_type`, `module_or_unit`, `is_test`, `artifact_type` (`app/modules/rag/indexing/code/code_text/document_builder.py:17`).
|
||||
- Колонки БД: `rag_chunks` + `layer/lang/repo_id/commit_sha/title/metadata_json/span_*...` (`app/modules/rag/persistence/schema_repository.py:47`, `:112`).
|
||||
- Где строится индекс: `CodeIndexingPipeline.index_file` (`app/modules/rag/indexing/code/pipeline.py:37`) + `CodeTextDocumentBuilder.build` (`app/modules/rag/indexing/code/code_text/document_builder.py:9`).
|
||||
- Где retrieval: `RagDbAdapter.retrieve` (`tests/pipeline_intent_rag/helpers/rag_db_adapter.py:41`) -> `RagRepository.retrieve|retrieve_lexical_code` (`app/modules/rag/persistence/repository.py:62`, `:87`).
|
||||
- Как ранжируется: `build_retrieve` и `build_lexical_code` (`app/modules/rag/persistence/retrieval_statement_builder.py:9`, `:64`).
|
||||
|
||||
#### C1_SYMBOL_CATALOG
|
||||
|
||||
- Назначение: каталог символов (class/function/method/import aliases).
|
||||
- Единица индексации: symbol.
|
||||
- Источник данных: Python AST visitor (`app/modules/rag/indexing/code/symbols/extractor.py:32`).
|
||||
- Схема записи:
|
||||
- C1 metadata: `symbol_id`, `qname`, `kind`, `signature`, `decorators_or_annotations`, `docstring_or_javadoc`, `parent_symbol_id`, `package_or_module`, `is_entry_candidate`, `is_test`, `lang_payload`, `artifact_type` (`app/modules/rag/indexing/code/symbols/document_builder.py:20`).
|
||||
- Где строится индекс: `SymbolExtractor.extract` (`app/modules/rag/indexing/code/symbols/extractor.py:24`) + `SymbolDocumentBuilder.build` (`app/modules/rag/indexing/code/symbols/document_builder.py:9`).
|
||||
- Где retrieval: тот же общий путь SQL retrieval (`app/modules/rag/persistence/retrieval_statement_builder.py:9`).
|
||||
- Как ранжируется: общий ranking SQL (`app/modules/rag/persistence/retrieval_statement_builder.py:31`, `:39`, `:59`).
|
||||
|
||||
#### C2_DEPENDENCY_GRAPH
|
||||
|
||||
- Назначение: связи между символами.
|
||||
- Единица индексации: edge.
|
||||
- Источник данных: AST visitor по классам/функциям/import/call (`app/modules/rag/indexing/code/edges/extractor.py:33`).
|
||||
- Схема записи:
|
||||
- C2 metadata: `edge_id`, `edge_type`, `src_symbol_id`, `src_qname`, `dst_symbol_id`, `dst_ref`, `resolution`, `is_test`, `lang_payload`, `artifact_type` (`app/modules/rag/indexing/code/edges/document_builder.py:18`).
|
||||
- Где строится индекс: `EdgeExtractor.extract` (`app/modules/rag/indexing/code/edges/extractor.py:24`) + `EdgeDocumentBuilder.build` (`app/modules/rag/indexing/code/edges/document_builder.py:9`).
|
||||
- Где retrieval: общий SQL retrieval (`app/modules/rag/persistence/retrieval_statement_builder.py:9`).
|
||||
- Как ранжируется: общий ranking SQL (`app/modules/rag/persistence/retrieval_statement_builder.py:59`).
|
||||
|
||||
Отдельно по `C2_DEPENDENCY_GRAPH`:
|
||||
|
||||
- Поддерживаемые `edge_type`: `inherits`, `imports`, `calls` (`app/modules/rag/indexing/code/edges/extractor.py:43`, `:58`, `:72`).
|
||||
- `dst_ref`: собирается из AST-узла имени/атрибута (`app/modules/rag/indexing/code/edges/extractor.py:107`).
|
||||
- `dst_symbol_id`: ищется в `qname_map` (`app/modules/rag/indexing/code/edges/extractor.py:89`).
|
||||
- `resolution`: `"resolved"` если `dst_symbol_id` найден, иначе `"partial"` (`app/modules/rag/indexing/code/edges/extractor.py:102`).
|
||||
|
||||
#### C3_ENTRYPOINTS
|
||||
|
||||
- Назначение: точки входа (HTTP/CLI).
|
||||
- Единица индексации: entrypoint.
|
||||
- Источник данных: эвристики по decorators символов (`FastAPI`, `Flask`, `Typer/Click`) (`app/modules/rag/indexing/code/entrypoints/registry.py:23`).
|
||||
- Схема записи:
|
||||
- C3 metadata: `entry_id`, `entry_type`, `framework`, `route_or_command`, `handler_symbol_id`, `is_test`, `lang_payload`, `artifact_type` (`app/modules/rag/indexing/code/entrypoints/document_builder.py:17`).
|
||||
- Где строится индекс: detectors `FastApiEntrypointDetector.detect`, `FlaskEntrypointDetector.detect`, `TyperClickEntrypointDetector.detect` (`app/modules/rag/indexing/code/entrypoints/fastapi_detector.py:11`, `flask_detector.py:9`, `typer_click_detector.py:9`).
|
||||
- Где retrieval: общий SQL retrieval (`app/modules/rag/persistence/retrieval_statement_builder.py:9`).
|
||||
- Как ранжируется: общий ranking SQL (`app/modules/rag/persistence/retrieval_statement_builder.py:59`), приоритет слоя `C3` в `layer_rank` = 0 (`app/modules/rag/persistence/retrieval_statement_builder.py:41`).
|
||||
|
||||
### 3.2 Docs layers
|
||||
|
||||
#### D1_MODULE_CATALOG
|
||||
|
||||
- Назначение: карточка модуля документации.
|
||||
- Единица: документ на файл (если есть `id/type/domain` во frontmatter).
|
||||
- Схема: `module_id`, `type`, `domain`, `status`, `version`, `tags`, `owners`, `links`, `source_path`, `summary_text`, `doc_kind` и поля связей (`calls_api`, `called_by`, ... ) (`app/modules/rag/indexing/docs/document_builder.py:10`).
|
||||
- Build: `DocsIndexingPipeline.index_file` (`app/modules/rag/indexing/docs/pipeline.py:24`) -> `DocsDocumentBuilder.build_module_catalog` (`app/modules/rag/indexing/docs/document_builder.py:10`).
|
||||
- Retrieval: общий SQL retrieval (`app/modules/rag/persistence/retrieval_statement_builder.py:9`).
|
||||
|
||||
#### D2_FACT_INDEX
|
||||
|
||||
- Назначение: атомарные факты.
|
||||
- Единица: fact.
|
||||
- Схема: `fact_id`, `subject_id`, `predicate`, `object`, `object_ref`, `anchor`, `tags`, `source_path` (`app/modules/rag/indexing/docs/document_builder.py:86`).
|
||||
- Build: `DocsIndexingPipeline._extract_facts/_facts_from_table/_facts_from_lists` (`app/modules/rag/indexing/docs/pipeline.py:55`, `:76`, `:118`) -> `build_fact` (`app/modules/rag/indexing/docs/document_builder.py:86`).
|
||||
- Retrieval: общий SQL retrieval (`app/modules/rag/persistence/retrieval_statement_builder.py:9`).
|
||||
|
||||
#### D3_SECTION_INDEX
|
||||
|
||||
- Назначение: секции документа.
|
||||
- Единица: section chunk.
|
||||
- Схема: `module_id`, `type`, `domain`, `tags`, `section_path`, `section_title`, `order`, `doc_kind`, `source_path`, `artifact_type` (`app/modules/rag/indexing/docs/document_builder.py:42`).
|
||||
- Build: `MarkdownDocChunker.chunk` (`app/modules/rag/indexing/docs/chunkers/markdown_chunker.py:20`) -> `DocsDocumentBuilder.build_section` (`app/modules/rag/indexing/docs/document_builder.py:42`).
|
||||
- Retrieval: общий SQL retrieval (`app/modules/rag/persistence/retrieval_statement_builder.py:9`).
|
||||
|
||||
#### D4_POLICY_INDEX
|
||||
|
||||
- Назначение: policy-документы.
|
||||
- Единица: policy doc.
|
||||
- Схема: `policy_id`, `applies_to`, `rules`, `default_behaviors`, `doc_kind`, `section_path`, `source_path` (`app/modules/rag/indexing/docs/document_builder.py:64`).
|
||||
- Build: только если `frontmatter.type == "policy"` (`app/modules/rag/indexing/docs/pipeline.py:36`) -> `build_policy` (`app/modules/rag/indexing/docs/document_builder.py:64`).
|
||||
- Retrieval: общий SQL retrieval (`app/modules/rag/persistence/retrieval_statement_builder.py:9`).
|
||||
|
||||
## 4) Scoping & filtering (самое важное)
|
||||
|
||||
- `repo_id`/workspace scope при индексации:
|
||||
- `RagService._resolve_repo_id` берет `project_id` из `rag_session`; fallback — сам `rag_session_id` (`app/modules/rag/services/rag_service.py:161`).
|
||||
- `repo_id` пишется в документы/metadata (`app/modules/rag/services/rag_service.py:147`).
|
||||
- Retrieval scope: SQL всегда фильтрует по `rag_session_id = :sid` (`app/modules/rag/persistence/retrieval_statement_builder.py:23`).
|
||||
- `include_globs`, `exclude_globs`, `prefer_globs`:
|
||||
- Формируются роутером в `RetrievalConstraintsFactory.build` (`app/modules/rag/intent_router_v2/retrieval/retrieval_constraints_factory.py:22`).
|
||||
- В `RagDbAdapter.retrieve` применяются `include_globs`/`exclude_globs` через перевод в prefixes/LIKE (`tests/pipeline_intent_rag/helpers/rag_db_adapter.py:46`).
|
||||
- Использование `prefer_globs` в retrieval-коде не найдено; найдено только формирование/тесты.
|
||||
- `path_scope`:
|
||||
- Формируется в `RetrievalFilterBuilder._path_scope` (`app/modules/rag/intent_router_v2/retrieval/retrieval_filter_builder.py:63`).
|
||||
- В retrieval используется как prefixes: сначала точный scope, затем parent prefix, затем без scope (`tests/pipeline_intent_rag/helpers/rag_db_adapter.py:98`).
|
||||
- До/после ранжирования:
|
||||
- Path/layer/test exclude фильтры попадают в `WHERE` до `ORDER BY` (`app/modules/rag/persistence/retrieval_statement_builder.py:23`, `:58`, `:59`).
|
||||
- `tests/**` penalty:
|
||||
- Penalty вычисляется как `CASE WHEN lower(path) LIKE ... THEN 1 ELSE 0 END` при `prefer_non_tests=True` (`app/modules/rag/persistence/retrieval_statement_builder.py:176`).
|
||||
- В `RagDbAdapter` `prefer_non_tests` зависит от `test_policy` (`tests/pipeline_intent_rag/helpers/rag_db_adapter.py:72`).
|
||||
|
||||
## 5) Merge policy (как собираются rag_rows)
|
||||
|
||||
- Top-K на слой задается в `retrieval_spec.layer_queries` (`app/modules/rag/intent_router_v2/models.py:125`) и заполняется `RetrievalSpecFactory` (`app/modules/rag/intent_router_v2/retrieval/retrieval_spec_factory.py:10`).
|
||||
- Фактический SQL limit в `pipeline_intent_rag`: `limit = max(top_k)` по всем слоям, не отдельный budget на слой (`tests/pipeline_intent_rag/helpers/rag_db_adapter.py:56`).
|
||||
- Смешивание слоев: один SQL по списку слоев `layer = ANY(:layers)` + общий `ORDER BY` (`app/modules/rag/persistence/retrieval_statement_builder.py:29`, `:59`).
|
||||
- Политика merge: interleave/concat как отдельные алгоритмы не найдены; порядок задает SQL sorting.
|
||||
- Дедупликация по `blob_sha`/`symbol_id` для `rag_rows` в `pipeline_intent_rag` не найдена.
|
||||
- Общий budget:
|
||||
- retrieval rows ограничены `LIMIT :lim` (`app/modules/rag/persistence/retrieval_statement_builder.py:60`);
|
||||
- в `full_chain` в prompt уходит максимум 6 `rag_rows`, каждый `content` режется до 1200 символов (`tests/pipeline_intent_rag/helpers/llm_answerer.py:31`, `:34`).
|
||||
|
||||
## 6) Prompt builder / evidence packaging
|
||||
|
||||
- Формат передачи `rag_rows` в LLM (`pipeline_intent_rag/full_chain`):
|
||||
- `GigaChatAnswerer._format_context` делает блоки `- path | title\\ncontent` (`tests/pipeline_intent_rag/helpers/llm_answerer.py:35`),
|
||||
- затем `answer` добавляет вопрос+контекст в `user_prompt` (`tests/pipeline_intent_rag/helpers/llm_answerer.py:17`).
|
||||
- Evidence gate:
|
||||
- в `pipeline_intent_rag` gate не найден;
|
||||
- в direct code-explain есть `CodeExplainEvidenceGate(min_excerpts=2)` (`app/modules/chat/evidence_gate.py:16`), применяется в `CodeExplainChatService.handle_message` (`app/modules/chat/direct_service.py:46`).
|
||||
- Шаблоны промптов:
|
||||
- code explain: `app/modules/agent/prompts/code_explain_answer_v2.txt:1` (используется в `app/modules/chat/direct_service.py:50`, `app/modules/agent/engine/graphs/project_qa_step_graphs.py:169`);
|
||||
- project/docs QA: `app/modules/agent/prompts/project_answer.txt:1` (используется в `app/modules/agent/engine/graphs/project_qa_graph.py:36`);
|
||||
- general: `app/modules/agent/prompts/general_answer.txt:1` (используется в `app/modules/agent/engine/graphs/base_graph.py:62`).
|
||||
|
||||
## 7) Repro commands
|
||||
|
||||
- Построить новый индекс (новая `rag_session`) для локального репозитория:
|
||||
|
||||
```bash
|
||||
python3 -m tests.pipeline_intent_rag reindex --repo-path /abs/path/to/repo
|
||||
# optional:
|
||||
python3 -m tests.pipeline_intent_rag reindex --repo-path /abs/path/to/repo --project-id my-project
|
||||
```
|
||||
|
||||
Источник: `tests/pipeline_intent_rag/cli.py:143`, `:123`; README `tests/pipeline_intent_rag/README.md:54`.
|
||||
|
||||
- Прогнать тесткейсы:
|
||||
|
||||
```bash
|
||||
python3 -m tests.pipeline_intent_rag run --mode router_only
|
||||
python3 -m tests.pipeline_intent_rag run --mode router_rag --rag-session-id <uuid>
|
||||
python3 -m tests.pipeline_intent_rag run --mode full_chain --rag-session-id <uuid>
|
||||
```
|
||||
|
||||
Источник: `tests/pipeline_intent_rag/cli.py:135`, `:138`; README `tests/pipeline_intent_rag/README.md:49`.
|
||||
|
||||
- Получить `rag_rows` как в логах артефактов:
|
||||
|
||||
```bash
|
||||
python3 -m tests.pipeline_intent_rag run --mode router_rag --rag-session-id <uuid> --test-name rag_probe
|
||||
ls -t tests/artifacts/rag_probe_*.jsonl | head -n 1
|
||||
tail -n 50 "$(ls -t tests/artifacts/rag_probe_*.jsonl | head -n 1)"
|
||||
```
|
||||
|
||||
`rag_rows` сериализуются в JSONL через `PipelineResult.to_record` (`tests/pipeline_intent_rag/helpers/models.py:31`) и `ArtifactWriter` (`tests/pipeline_intent_rag/helpers/artifact_writer.py:20`), имя файла `<test_name>_<YYYYMMDD_HHMMSS>.jsonl` (`tests/pipeline_intent_rag/helpers/artifact_writer.py:16`).
|
||||
|
||||
## 8) Appendix: Code pointers
|
||||
|
||||
- Entrypoints:
|
||||
- Router API: `app/modules/rag/intent_router_v2/router.py:35` (`IntentRouterV2.route`).
|
||||
- Graph-id map: `app/modules/rag/intent_router_v2/intent/graph_id_resolver.py:4` (`GraphIdResolver`).
|
||||
- CLI: `tests/pipeline_intent_rag/__main__.py:1`, `tests/pipeline_intent_rag/cli.py:178` (`main`).
|
||||
- Ключевые классы:
|
||||
- `IntentRouterV2`: `app/modules/rag/intent_router_v2/router.py:14`.
|
||||
- `RagService`: `app/modules/rag/services/rag_service.py:20`.
|
||||
- `CodeIndexingPipeline`: `app/modules/rag/indexing/code/pipeline.py:19`.
|
||||
- `DocsIndexingPipeline`: `app/modules/rag/indexing/docs/pipeline.py:14`.
|
||||
- `RagDbAdapter`: `tests/pipeline_intent_rag/helpers/rag_db_adapter.py:36`.
|
||||
- `RetrievalStatementBuilder`: `app/modules/rag/persistence/retrieval_statement_builder.py:8`.
|
||||
- Конфиги/переменные окружения:
|
||||
- Test env: `tests/pipeline_intent_rag/.env.test:3`.
|
||||
- Env loader: `tests/pipeline_intent_rag/helpers/env_bootstrap.py:13`.
|
||||
- Run config keys: `tests/pipeline_intent_rag/helpers/pipeline_config.py:30`.
|
||||
- Форматы данных (pydantic/dataclasses):
|
||||
- Router schema: `app/modules/rag/intent_router_v2/models.py:43`, `:139`.
|
||||
- RAG document dataclass: `app/modules/rag/contracts/documents.py:29`.
|
||||
- Pipeline result JSONL model: `tests/pipeline_intent_rag/helpers/models.py:18`.
|
||||
- Not found:
|
||||
- Классы/функции `CodeQAGraph`, `DocsQAGraph` как реальные graph-реализации в `app/` не найдены (строки встречаются как `graph_id` map).
|
||||
- `F0` layer не найден в `app/` и `tests/`.
|
||||
Reference in New Issue
Block a user