This commit is contained in:
2026-03-27 15:51:10 +03:00
parent 15586f9a8c
commit 0bff171936
1245 changed files with 99621 additions and 543076 deletions
@@ -0,0 +1,546 @@
# Текущая архитектура тестового пайплайна `pipeline_setup_v3`
Документ предназначен как краткое, но точное описание текущего устройства `pipeline_setup_v3` для внешней модели вроде ChatGPT.
Важно: текущий `pipeline_setup_v3` уже использует реальные runtime-компоненты агента, но по сути остается в первую очередь `code-first` пайплайном. Это особенно заметно в `evidence gate` и в наборе prompt'ов для LLM.
## 1. Общая схема пайплайна
`pipeline_setup_v3` запускает один из трех режимов:
- `router_only`
- `router_rag`
- `full_chain`
Во всех режимах используется `AgentRuntimeAdapter`, который является тестовым адаптером поверх реальных компонентов рантайма.
Общий поток для `full_chain`:
1. Пользовательский запрос
2. `IntentRouterV2`
3. Построение `RetrievalRequest`
4. `RuntimeRetrievalAdapter`
5. Построение нормализованного `RetrievalResult`
6. Сборка `EvidenceBundle`
7. `pre-evidence gate`
8. `RuntimeAnswerPolicy`
9. Вызов LLM через `AgentLlmService`
10. `post-evidence gate`
11. При необходимости `repair`
12. Сборка итогового результата, диагностики и артефактов теста
Ключевая идея: `pipeline_setup_v3` не эмулирует локальный тестовый сценарий вручную, а прогоняет реальные компоненты: роутер, retrieval, runtime executor и LLM.
## 2. Из каких компонентов состоит `pipeline_setup_v3`
### 2.1. Harness уровня тестов
Основные части:
- `tests/pipeline_setup_v3/run.py` — CLI-вход для запуска набора кейсов
- `tests/pipeline_setup_v3/core/runner.py` — оркестратор прогона кейсов
- `tests/pipeline_setup_v3/core/case_loader.py` — загрузка YAML-кейсов
- `tests/pipeline_setup_v3/core/validators.py` — проверка ожиданий
- `tests/pipeline_setup_v3/core/artifacts.py` — запись JSON/Markdown-результатов
- `tests/pipeline_setup_v3/runtime/agent_runtime_adapter.py` — мост к runtime-компонентам приложения
### 2.2. Runtime-компоненты, которые реально вызываются
- `IntentRouterV2`
- `RuntimeRepoContextFactory`
- `RuntimeRetrievalAdapter`
- `AgentRuntimeExecutor`
- `AgentLlmService`
- `PromptLoader`
### 2.3. Два варианта исполнения
#### `router_only`
Проверяет только результат роутера:
- `intent`
- `sub_intent`
- `graph_id`
- `conversation_mode`
RAG и LLM не вызываются.
#### `router_rag`
Проверяет:
- роутер
- retrieval plan
- реальный retrieval
- нормализованный `RetrievalResult`
LLM не вызывается.
#### `full_chain`
Проверяет полный runtime-контур:
- роутер
- retrieval
- evidence bundle
- pre-gate
- answer policy
- LLM
- post-gate
- repair
- итоговый answer/diagnostics
## 3. Компонент: Intent Router
### 3.1. Что это такое
`IntentRouterV2` классифицирует запрос и возвращает структурированный план для retrieval и дальнейшего рантайма.
Он не просто выбирает `intent`, а сразу строит:
- `conversation_mode`
- `query_plan`
- `retrieval_spec`
- `retrieval_constraints`
- `symbol_resolution`
- `evidence_policy`
- `graph_id`
### 3.2. Какие интенты есть сейчас
Сейчас в коде поддерживаются:
- `CODE_QA`
- `DOCUMENTATION_EXPLAIN`
- `GENERATE_DOCS_FROM_CODE`
- `FALLBACK`
### 3.3. Какие саб-интенты есть сейчас
#### Для `CODE_QA`
- `OPEN_FILE`
- `EXPLAIN`
- `EXPLAIN_LOCAL`
- `FIND_TESTS`
- `FIND_ENTRYPOINTS`
- `TRACE_FLOW`
- `ARCHITECTURE`
- `NEXT_STEPS` может появляться как follow-up режим на уровне query planning
#### Для `DOCUMENTATION_EXPLAIN`
- `SYSTEM_FLOW_EXPLAIN`
- `COMPONENT_EXPLAIN`
- `API_METHOD_EXPLAIN`
- `ENTITY_EXPLAIN`
#### Для `FALLBACK`
- `GENERIC_FALLBACK`
### 3.4. Что роутер возвращает на выходе
Результат роутера — это `IntentRouterResult`.
Ключевые поля:
- `intent`
- `retrieval_profile`
- `graph_id`
- `conversation_mode`
- `query_plan`
- `retrieval_spec`
- `retrieval_constraints`
- `symbol_resolution`
- `evidence_policy`
### 3.5. Что входит в `query_plan`
`query_plan` содержит:
- `raw`
- `normalized`
- `sub_intent`
- `negations`
- `expansions`
- `keyword_hints`
- `path_hints`
- `doc_scope_hints`
- `symbol_candidates`
- `symbol_kind_hint`
- `anchors`
Это основной bridge между классификацией запроса и retrieval.
### 3.6. Что входит в `retrieval_spec`
`retrieval_spec` содержит:
- `domains`
- `layer_queries`
- `filters`
- `rerank_profile`
Именно этот объект задает, какие слои RAG должны быть запрошены.
### 3.7. Что важно про текущее состояние
Текущий роутер уже умеет выделять docs-интенты и docs-сабинтенты, но downstream runtime ниже по пайплайну все еще во многом оптимизирован под `CODE_QA`.
Это означает:
- docs routing уже есть
- docs layer selection уже есть
- но `pre/post evidence gate` и prompt selection пока ориентированы в первую очередь на code sub-intents
## 4. Структура RAG
### 4.1. Общая идея
RAG устроен как многослойный индекс. Retrieval работает не по одному единственному типу чанков, а по наборам специализированных слоев.
### 4.2. Code-слои
- `C0_SOURCE_CHUNKS` — сырой код / чанки исходников
- `C1_SYMBOL_CATALOG` — каталог символов
- `C2_DEPENDENCY_GRAPH` — зависимости и связи
- `C3_ENTRYPOINTS` — точки входа, маршруты, handler'ы
- `C4_SEMANTIC_ROLES` — семантические роли и behavioral hints
### 4.3. Docs-слои
- `D0_DOC_CHUNKS` — чанки документов
- `D1_DOCUMENT_CATALOG` — каталог документов
- `D2_FACT_INDEX` — атомарные факты
- `D3_ENTITY_CATALOG` — сущности
- `D4_WORKFLOW_INDEX` — сценарии и workflow
- `D5_RELATION_GRAPH` — связи между документами
### 4.4. Как retrieval связывается с роутером
Роутер возвращает:
- `domains`
- `layer_queries`
- `filters`
- `retrieval_constraints`
Дальше `build_retrieval_request(...)` превращает это в `RetrievalRequest`, который содержит:
- `rag_session_id`
- `query`
- `sub_intent`
- `path_scope`
- `keyword_hints`
- `symbol_candidates`
- `requested_layers`
- `retrieval_spec`
- `retrieval_constraints`
- `query_plan`
### 4.5. Что возвращает retrieval
Сырые строки RAG затем нормализуются в `RetrievalResult`, который содержит:
- `target_symbol_candidates`
- `resolved_symbol`
- `symbol_resolution_status`
- `file_candidates`
- `code_chunks`
- `relations`
- `semantic_hints`
- `entrypoints`
- `test_candidates`
- `layer_outcomes`
- `missing_layers`
- `raw_rows`
- `retrieval_report`
### 4.6. Как из retrieval строится evidence
`build_evidence_bundle(...)` собирает `EvidenceBundle`.
Ключевые поля:
- `resolved_intent`
- `resolved_sub_intent`
- `resolved_target`
- `target_type`
- `target_symbol_candidates`
- `file_candidates`
- `code_chunks`
- `relations`
- `entrypoints`
- `test_evidence`
- `evidence_count`
- `sufficient`
- `failure_reasons`
- `retrieval_summary`
Важно: `evidence_count` сейчас считается по количеству `code_chunks`. Это еще одно подтверждение, что runtime сегодня code-first.
## 5. Evidence Gate
В пайплайне есть два gate'а.
## 5.1. Pre-evidence gate
Расположение:
- `src/app/modules/agent/runtime/steps/gates/pre/evidence_gate.py`
Когда срабатывает:
- после retrieval
- после сборки `EvidenceBundle`
- до вызова LLM
Задача:
- понять, достаточно ли evidence для уверенного ответа
- выдать `passed/failure_reasons/degraded_message`
Как работает сейчас:
- для `OPEN_FILE` требует найденный path/file и хотя бы один `C0` chunk
- для `EXPLAIN` требует target symbol и минимум 2 evidence chunk'а
- для `FIND_TESTS` требует target и хотя бы один test candidate
- для `FIND_ENTRYPOINTS` требует хотя бы один entrypoint
- для остальных сценариев требует минимум 1 evidence
Что возвращает:
- `passed`
- `failure_reasons`
- `degraded_message`
Ограничение:
- логика pre-gate пока написана в терминах code sub-intents
- docs-сценарии там явно не моделированы
## 5.2. Post-evidence gate
Расположение:
- `src/app/modules/agent/runtime/steps/gates/post/post_gate.py`
Когда срабатывает:
- после генерации draft answer
- до возврата финального ответа
Задача:
- проверить groundedness черновика
- убедиться, что ответ действительно опирается на evidence
- решить, нужен ли `repair`
Что проверяет:
- что ответ не пустой
- что degraded/not_found/ambiguous-ответы содержат обязательные guardrail-фразы
- что normal answer не слишком общий
- что упоминаются обязательные факты из curated evidence
- что нет явной semantic leakage или contradictions
Отдельные проверки есть для:
- `FIND_ENTRYPOINTS`
- `EXPLAIN`
- `ARCHITECTURE`
- `TRACE_FLOW`
Если gate не проходит, он возвращает:
- `passed=False`
- `action="repair"`
- список `reasons`
После этого runtime может сделать дополнительный шаг `repair` через LLM.
Ограничение:
- post-gate тоже пока ориентирован на code-oriented sub-intents
- docs-сабинтенты для него еще не описаны отдельными правилами
## 6. Обращение к LLM
### 6.1. Где вызывается LLM
В `pipeline_setup_v3` есть два места использования LLM:
1. В классификации интента внутри `IntentClassifierV2`
2. В финальной генерации ответа внутри `AgentRuntimeExecutor`
### 6.2. Prompt для классификации интента
Используется prompt:
- `rag_intent_router_v2`
Назначение:
- если deterministic rules не дали результата, LLM выбирает интент
Текущий prompt исторически описывает старые имена интентов, поэтому его еще нужно синхронизировать с новым docs/fallback контрактом.
### 6.3. Prompt'ы для генерации ответа
Prompt selector сейчас выбирает:
- `code_qa_architecture_answer`
- `code_qa_explain_answer`
- `code_qa_explain_local_answer`
- `code_qa_find_entrypoints_answer`
- `code_qa_find_tests_answer`
- `code_qa_general_answer`
- `code_qa_open_file_answer`
- `code_qa_trace_flow_answer`
- `code_qa_degraded_answer`
Дополнительно для repair используется:
- `code_qa_repair_answer`
### 6.4. Как строится payload для LLM
Перед вызовом LLM runtime собирает:
- `AnswerSynthesisInput`
- `EvidenceBundle`
- `prompt_payload`
В payload передаются:
- `user_question`
- `resolved_target`
- `answer_mode`
- `evidence_summary`
- `retrieval_summary`
- curated facts
- обязательные для упоминания сущности, методы, связи, шаги и т.д.
То есть LLM не получает просто "вопрос и куски текста", а получает уже структурированный grounded payload.
### 6.5. Что важно про текущее состояние prompt'ов
Сейчас runtime prompt selection и prompt contracts явно заточены под code QA.
Это значит:
- для `CODE_QA` full chain оформлен хорошо
- для `DOCUMENTATION_EXPLAIN` routing и retrieval есть, но отдельного docs answer-prompt слоя пока нет
- для docs full-chain пока не хватает собственных prompt names, prompt payload contract и post-gate правил
## 7. Что именно сейчас проверяет `pipeline_setup_v3`
YAML-кейс может проверять четыре группы ожиданий:
- `router`
- `retrieval`
- `llm`
- `pipeline`
Примеры ожиданий:
- ожидаемый `intent`
- ожидаемый `sub_intent`
- нужные слои в `layers_include`
- что retrieval не пустой
- что в answer есть нужные фразы
- какой `answer_mode` получился
## 8. Ключевые выводы о текущей архитектуре
### 8.1. Что уже сделано хорошо
- `pipeline_setup_v3` работает поверх реальных runtime-компонентов
- есть явный контракт между router → retrieval → evidence → answer
- есть два evidence gate
- есть structured diagnostics
- есть нормализованные типы `RetrievalRequest`, `RetrievalResult`, `EvidenceBundle`
### 8.2. Что остается code-first
- pre-evidence gate
- post-evidence gate
- prompt selector
- набор answer prompts
- часть логики нормализации evidence
### 8.3. Что это значит для docs use case
Сейчас docs use case уже частично внедрен:
- есть docs intent
- есть docs sub-intents
- есть docs layer mapping
- есть docs retrieval profile
Но для полноценного `full_chain` по документации еще не хватает:
- docs-oriented pre-gate правил
- docs-oriented post-gate правил
- docs-specific answer prompts
- docs-specific synthesis contract
- отдельных full-chain test cases для `DOCUMENTATION_EXPLAIN` и `FALLBACK`
## 9. Краткое резюме по компонентам
### Intent Router
Назначение:
- классифицировать запрос
- построить retrieval plan
- задать evidence policy
Выход:
- `IntentRouterResult`
### RAG
Назначение:
- вернуть evidence из многослойного индекса
Выход:
- `RetrievalResult`
- затем `EvidenceBundle`
### Pre-evidence gate
Назначение:
- решить, можно ли вообще уверенно отвечать
Выход:
- `passed/failure_reasons/degraded_message`
### Post-evidence gate
Назначение:
- проверить, grounded ли уже сгенерированный ответ
Выход:
- `return` или `repair`
### LLM
Назначение:
- классификация сложных интентов
- генерация финального ответа
- repair ответа при провале post-gate
Текущий фокус:
- в первую очередь `CODE_QA`