Роутер работает нормально в process v2
This commit is contained in:
@@ -0,0 +1,220 @@
|
||||
# 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**, синхронизированная с текущей реализацией.
|
||||
Reference in New Issue
Block a user