# MVP: процесс v2 ## 1. Общее описание Процесс v2 в текущем MVP ориентирован в первую очередь на **документацию проекта**, но роутер также поддерживает `GENERAL / GENERAL_QA / SUMMARY` для общих обзорных вопросов. Для документных веток нужна активная RAG-сессия с проиндексированными документами. Это **узкий MVP**, а не полная target architecture. Поддерживаются три маршрута: - `GENERAL` - `GENERAL_QA` - `SUMMARY` - `DOCS` - `DOC_EXPLAIN` - `SUMMARY` - `FIND_FILES` Запрос проходит следующие смысловые этапы: 1. проверка готовности сессии; 2. intent routing; 3. формирование retrieval-параметров; 4. retrieval из `DOCS RAG`; 5. минимальная сборка evidence; 6. запуск task-focused workflow нужной ветки; 7. формирование ответа. ```mermaid flowchart TB subgraph api [API] RS[RequestService] end subgraph runtime [Agent runtime] AR[AgentRuntime] PR[ProcessRunner] end subgraph v2 [Процесс v2] P2[V2Process] IR[V2IntentRouter] POL[V2RetrievalPolicyResolver] AD[V2RagRetrievalAdapter] RSR[RagSessionRetriever] ASM[DocsEvidenceAssembler] end subgraph rag [Пакет rag] RR[RagRepository] end subgraph wf [Workflow] SUM[DocsExplainSummaryGraph] FF[DocsExplainFindFilesGraph] end LLM[AgentLlmService] RS --> AR --> PR --> P2 P2 --> IR --> POL --> AD --> RSR --> RR AD --> ASM ASM --> SUM ASM --> FF SUM --> LLM ``` Клиент указывает `process_version: v2`. Без `active_rag_session_id` в сессии процесс возвращает сообщение об ошибке. Иначе выполняется цепочка: маршрутизация → `RetrievalPlan` → retrieval строк из `DOCS RAG` → минимальная сборка evidence → ветвление по `subintent` → запуск workflow. ### Реализованные домены, интенты и сабинтенты В коде заданы константы `V2Domain`, `V2Intent`, `V2Subintent`. Сейчас процесс intentionally ограничен одной рабочей областью. | Уровень | Значение (строка) | Реализация | |--------|-------------------|------------| | **Домен (routing_domain)** | `DOCS` | Единственный поддерживаемый домен: документация проекта. | | **Интент** | `DOC_EXPLAIN` | Единственный интент: объяснение по документации. | | **Сабинтент** | `SUMMARY` | Объяснение темы по SUMMARY-блокам документации. | | **Сабинтент** | `FIND_FILES` | Поиск путей к документам, где описана нужная сущность или тема. | Итого в текущем MVP реализована **одна** рабочая тройка домен×интент: `DOCS` + `DOC_EXPLAIN`, с **двумя** ветками по сабинтенту. --- ## 2. Этапы вне workflow (внутри `V2Process.run`) ### 2.1. `V2IntentRouter.route` | | | |--|--| | **Название** | Маршрутизация запроса (v2) | | **Задача** | Определить домен, интент, subintent и извлечь якоря из текста. | | **Вход** | `user_query: str` (текст сообщения пользователя). | | **Выход** | `V2RouteResult`: `routing_domain`, `intent`, `subintent`, `user_query`, `normalized_query`, `target_terms`, `anchors` (`V2RouteAnchors`), `confidence`. | | **Как работает** | Router реализован по схеме **LLM-first**: `normalization` → `target_terms`/`anchors extraction` → `LLM router` → `deterministic validator` → `fallback`. LLM является **основным селектором маршрута**. Deterministic-слой больше не выбирает маршрут по умолчанию: он отвечает только за extraction, валидацию enum/комбинаций и fallback при сломанном или невалидном ответе LLM. В trace пишется событие `intent_routed`. | Код: `src/app/core/agent/processes/v2/intent_router/router.py`, `modules/normalizer.py`, `modules/target_terms.py`, `modules/anchors.py`, `routers/llm.py`, `routers/validator.py`, `routers/fallback.py`. --- ### 2.2. `V2RetrievalPolicyResolver.resolve` | | | |--|--| | **Название** | Политика retrieval для v2 | | **Задача** | По результату роутинга выбрать профиль, список слоёв RAG и лимит строк выдачи. | | **Вход** | `V2RouteResult`. | | **Выход** | `RetrievalPlan`: `profile`, `layers`, `limit`, опционально `filters`. | | **Как работает** | Это отдельный смысловой шаг между routing и retrieval. Он не ходит в БД и не извлекает данные, а только подготавливает параметры поиска. Для `FIND_FILES` выбирается один профиль слоёв и лимит, для `SUMMARY` — другой. Лог: `retrieval_plan_resolved`. | Код: `src/app/core/agent/processes/v2/retrieval/policy_resolver.py`. --- ### 2.3. `V2RagRetrievalAdapter` → `RagSessionRetriever.retrieve` | | | |--|--| | **Название** | Загрузка сырых строк из RAG по плану | | **Задача** | Делегировать поиск в единственную реализацию retrieval в пакете `rag`. | | **Вход** | `rag_session_id`, `query_text` (нормализованный запрос), `RetrievalPlan`. | | **Выход** | `list[dict]` — строки чанков в формате `RagRepository.retrieve` (поля `path`, `layer`, `metadata`, и т.д.). | | **Как работает** | Выполняется retrieval по уже сформированному плану: профиль, список слоёв и лимит. На этом шаге происходит только извлечение сырых строк из `DOCS RAG`. Лог: `rag_rows_fetched`. | Код адаптера: `src/app/core/agent/processes/v2/retrieval/v2_rag_adapter.py`. Код API: `src/app/core/rag/retrieval/session_retriever.py`. --- ### 2.4. `DocsEvidenceAssembler` | | | |--|--| | **Название** | Сборка evidence для задачи | | **Задача** | Превратить сырые строки retrieval в списки summary или кандидатов файлов с дедупом и скорингом. | | **Вход** | Список строк `rows`, `V2RouteResult` (для `target_terms`). | | **Выход** | `list[RetrievedSummary]` или `list[RetrievedFile]`. | | **Как работает** | Это **минимальная evidence-проверка**, достаточная для MVP. Для `SUMMARY` отбрасываются записи без summary-текста и summary-like секции, затем применяется дедуп и простой скоринг по терминам. Для `FIND_FILES` остаются только релевантные пути документов, также с дедупом и простым скорингом. Здесь нет сложной многоступенчатой валидации: задача шага — отфильтровать очевидный шум и передать в workflow компактное evidence. Лог: `evidence_assembled`. | Код: `src/app/core/agent/processes/v2/evidence/assembler.py`. --- ## 3. Шаги workflow Текущие workflow являются **task-focused**: каждая ветка решает одну узкую прикладную задачу и не содержит общей универсальной логики для всех типов вопросов. ### 3.1. Ветка `SUMMARY`: `GenerateSummaryAnswerStep` | | | |--|--| | **Название** | Сборка ответа по summary | | **Задача** | Сформировать ответ пользователю по найденным SUMMARY-блокам или сообщить об отсутствии. | | **Вход** | `DocsExplainSummaryContext`: `runtime`, `route`, `rag_session_id`, `prompt_name`, `documents` (список `RetrievedSummary`). | | **Выход** | Контекст с `answer: str`, `prompt_input` при успешном вызове LLM. | | **Как работает** | Workflow получает уже отобранные summary-документы. Если документов нет — возвращает честный fallback-ответ. Иначе собирает prompt input из запроса пользователя и найденных summary-блоков и вызывает LLM. Workflow не занимается retrieval и не строит retrieval-план: он решает только задачу генерации ответа по уже подготовленному evidence. | Код: `src/app/core/agent/processes/v2/workflows/docs_explain_summary/steps/generate_summary_answer_step.py`. Граф: `DocsExplainSummaryGraph` (`V2WorkflowGraph`). --- ### 3.2. Ветка `FIND_FILES`: `FinalizeFindFilesAnswerStep` | | | |--|--| | **Название** | Сборка списка файлов | | **Задача** | Вывести пользователю markdown-список путей к файлам документации. | | **Вход** | `DocsExplainFindFilesContext`: `runtime`, `route`, `rag_session_id`, `files` (`RetrievedFile`). | | **Выход** | Контекст с `answer: str`. | | **Как работает** | Workflow получает уже собранный список файлов и формирует финальный ответ. Если файлов нет — возвращает fallback. Если файлы есть — отдает детерминированный список путей. Эта ветка intentionally не использует LLM, потому что задача сводится к выдаче путей, а не к генерации объяснения. | Код: `src/app/core/agent/processes/v2/workflows/docs_explain_find_files/steps/finalize_find_files_answer_step.py`. Граф: `DocsExplainFindFilesGraph` (`V2WorkflowGraph`). --- ### 3.3. Транспорт: `V2WorkflowGraph` | | | |--|--| | **Название** | Workflow v2 с буфером trace | | **Задача** | Выполнить шаги без пошаговых `step_started`/`step_completed` в trace; один раз сбросить сводку. | | **Вход** | Контекст workflow (`DocsExplainSummaryContext` или `DocsExplainFindFilesContext`). | | **Выход** | Обновлённый контекст. | | **Как работает** | Для каждого шага: `trace_input` до `run`, затем `run`, затем `trace_output`; записи копятся в список. В trace уходят `workflow_started`, затем `workflow_trace_flushed` с массивом шагов, затем `workflow_completed`. Статусы пользователю публикуются через `publisher` как и раньше. | Код: `src/app/core/agent/processes/v2/workflows/v2_workflow_graph.py`. --- ## 4. Сборка в приложении В `ModularApplication` создаются `RagSessionRetriever`, `V2RagRetrievalAdapter`, `V2RetrievalPolicyResolver`, `DocsEvidenceAssembler` и передаются в `V2Process` (см. `src/app/core/application.py`). --- ## 5. Итоговая концептуальная схема текущего MVP В концептуальном виде текущий `v2` работает так: 1. **Session check** Проверка, что есть активная RAG-сессия проекта. 2. **LLM-first intent routing** Нормализация, extraction (`target_terms`, `anchors`), затем основной выбор маршрута через LLM. 3. **Deterministic validation + fallback** Проверка enum/комбинации маршрута и fallback только если LLM не ответил или вернул невалидный маршрут. 4. **Retrieval parameter planning** Формирование профиля поиска, слоёв и лимитов. 5. **RAG retrieval** Загрузка сырых строк из `DOCS RAG`. 6. **Minimal evidence assembly** Дедуп, базовый скоринг, отбор полезных summary или файлов. 7. **Task-focused workflow** Узкая ветка `SUMMARY` или `FIND_FILES`. 8. **Final response** Либо explanation через LLM, либо детерминированный список файлов. Это и есть актуальная архитектура **узкого MVP**, синхронизированная с текущей реализацией.