# Текущая архитектура тестового пайплайна `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`
