Files
agent/_process/components/v2_intent_router_architecture.md
T

270 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# V2IntentRouter Architecture
## 1. Архитектура
Текущий `V2IntentRouter` состоит из следующих компонентов:
- `router.py`
Главная точка входа и оркестратор.
- `modules/normalizer.py`
Нормализация текста запроса в `normalized_query`.
- `modules/target_terms.py`
Извлечение `target_terms`, `endpoint_paths`, `matched_aliases`, `alias_docs`.
- `modules/anchors.py`
Извлечение `anchors` и вспомогательных marker-сигналов.
- `routers/docs_subintent_resolver.py`
Определение `subintent`.
- `routers/deterministic.py`
Детерминированное определение `routing_domain`, `intent`, `subintent`, `confidence`, `routing_mode`, `llm_router_used`, `reason_short`.
- `routers/llm.py`
LLM-based определение `routing_domain`, `intent`, `subintent`, `confidence`, `reason_short`.
- `routers/prompts.yml`
Prompt для LLM-router.
## 2. Контракт
### Вход
- `user_query: str`
### Выход
`V2RouteResult`:
- `routing_domain: str`
- `intent: str`
- `subintent: str`
- `user_query: str`
- `normalized_query: str`
- `target_terms: list[str]`
- `anchors: V2RouteAnchors`
- `confidence: float`
- `routing_mode: str`
- `llm_router_used: bool`
- `reason_short: str`
`V2RouteAnchors`:
- `entity_names: list[str]`
- `terms: list[str]`
- `file_names: list[str]`
- `endpoint_paths: list[str]`
- `target_doc_hints: list[str]`
- `matched_aliases: list[str]`
- `process_domain: str | None`
- `process_subdomain: str | None`
## 3. Поддерживаемые домены, интенты и сабинтенты
### Домены
- `DOCS`
- `GENERAL`
### Интенты
- `DOC_EXPLAIN`
- `GENERAL_QA`
### Сабинтенты
- `SUMMARY`
- `FIND_FILES`
### Поддерживаемые маршруты
- `GENERAL / GENERAL_QA / SUMMARY`
- `DOCS / DOC_EXPLAIN / SUMMARY`
- `DOCS / DOC_EXPLAIN / FIND_FILES`
## 4. Флоу обработки запроса
1. `router.py` принимает `user_query`.
2. `modules/normalizer.py` строит `normalized_query`.
3. `modules/target_terms.py` извлекает ключевые термы и alias-based сигналы.
4. `modules/anchors.py` строит `anchors` и marker-сигналы.
5. `router.py` собирает `QueryFeatures`.
6. `routers/deterministic.py` пытается определить маршрут детерминированно.
7. Если deterministic route найден, он сразу возвращается.
8. Если deterministic route не найден, `router.py` вызывает `routers/llm.py`.
9. Если LLM вернул валидный маршрут, собирается `V2RouteResult` с `routing_mode="llm_assisted"`.
10. Если LLM недоступен или не вернул валидный маршрут, используется fallback:
`GENERAL / GENERAL_QA / SUMMARY` с `routing_mode="llm_fallback"`.
## 5. Компоненты по флоу
### `router.py`
- Задача
Собрать весь процесс роутинга в одной входной точке.
- Как решает
Последовательно вызывает normalizer, target terms extractor, anchors extractor, deterministic router и при необходимости LLM router.
- Вход
`user_query: str`
- Выход
`V2RouteResult`
### `modules/normalizer.py`
- Задача
Привести запрос к стабильной форме для дальнейшего анализа.
- Как решает
Схлопывает лишние пробелы через `" ".join(...split())`.
- Вход
`user_query: str`
- Выход
`normalized_query: str`
### `modules/target_terms.py`
- Задача
Выделить ключевые термы и retrieval-сигналы из запроса.
- Как решает
Использует:
- regex для path/entity-like фрагментов
- список stop-words
- alias rules с фразами и каноническими термами
- эвристику для `/health`
- Вход
`normalized_query: str`
- Выход
`TargetTermsAnalysis`:
- `target_terms`
- `endpoint_paths`
- `matched_aliases`
- `alias_docs`
### `modules/anchors.py`
- Задача
Построить полный набор `anchors` и doc-oriented marker-сигналов.
- Как решает
Использует:
- regex для `entity_names` и `file_names`
- словари marker-фраз:
- file markers
- architecture markers
- logic markers
- domain markers
- endpoint markers
- map `endpoint -> target_doc_hint`
- alias docs из `TargetTermsAnalysis`
- Вход
- `normalized_query: str`
- `TargetTermsAnalysis`
- Выход
`AnchorAnalysis`:
- `anchors`
- `file_markers`
- `architecture_markers`
- `logic_markers`
- `domain_markers`
- `endpoint_markers`
### `routers/docs_subintent_resolver.py`
- Задача
Определить `subintent`.
- Как решает
Эвристика:
- если есть `file_markers` -> `FIND_FILES`
- если есть doc-signals (`endpoint_paths`, `endpoint_markers`, `architecture_markers`, `logic_markers`, `domain_markers`, `target_doc_hints`) -> `SUMMARY`
- иначе `None`
- Вход
`QueryFeatures`
- Выход
`subintent: str | None`
### `routers/deterministic.py`
- Задача
Детерминированно определить маршрут без LLM там, где это возможно.
- Как решает
Использует:
- `DocsSubintentResolver`
- проверку conflicting doc anchors
- список general markers
Правила:
- `FIND_FILES` -> `DOCS / DOC_EXPLAIN / FIND_FILES`
- `subintent != None` и нет конфликта doc-signals -> `DOCS / DOC_EXPLAIN / SUMMARY`
- general marker -> `GENERAL / GENERAL_QA / SUMMARY`
- Вход
- `user_query: str`
- `QueryFeatures`
- `anchors: V2RouteAnchors`
- Выход
`V2RouteResult | None`
### `routers/llm.py`
- Задача
Определить маршрут через LLM, если deterministic routing не дал результата.
- Как решает
Формирует JSON payload из:
- `user_query`
- `normalized_query`
- `target_terms`
- `anchors`
- списка допустимых маршрутов
Затем:
- вызывает LLM
- парсит JSON
- валидирует маршрут по whitelist
- нормализует `confidence`
- Вход
- `user_query: str`
- `normalized_query: str`
- `target_terms: list[str]`
- `anchors: dict`
- Выход
`dict | None`:
- `routing_domain`
- `intent`
- `subintent`
- `confidence`
- `reason_short`
### `routers/prompts.yml`
- Задача
Задать LLM-router формальный контракт ответа.
- Как решает
Описывает допустимые маршруты и требует вернуть только JSON.
- Вход
Payload от `routers/llm.py`
- Выход
Структурированный JSON-ответ LLM