Files
agent/_process/components/v2_intent_router_architecture.md

9.9 KiB
Raw Permalink Blame History

V2IntentRouter Architecture

1. Архитектура

Текущий V2IntentRouter реализован как LLM-first router. Deterministic-слой не выбирает маршрут по умолчанию и используется только для:

  • preprocessing
  • validation ответа LLM
  • fallback, если LLM не ответил или вернул невалидный маршрут

Актуальные компоненты:

  • router.py Главная точка входа и оркестратор пайплайна.

  • modules/normalizer.py Нормализация текста запроса в normalized_query.

  • modules/target_terms.py Извлечение retrieval-oriented target_terms, endpoint_paths, matched_aliases, alias_docs.

  • modules/anchors.py Извлечение anchors и marker-сигналов для fallback и downstream retrieval.

  • routers/route_catalog.py Каталог допустимых маршрутов (allowed_routes).

  • routers/llm.py Основной LLM-router. Получает нормализованный запрос, target_terms, anchors и список допустимых маршрутов.

  • routers/validator.py Deterministic validator для enum-значений, комбинации маршрута и базовой нормализации confidence.

  • routers/confidence.py Пост-обработка confidence после ответа LLM.

  • routers/fallback.py Fallback-маршрутизация, если LLM не ответил или ответ не прошёл validator.

  • 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]
  • 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

Эти маршруты централизованно заданы в routers/route_catalog.py.

4. Актуальный флоу

Пайплайн обработки запроса:

  1. router.py принимает user_query.
  2. modules/normalizer.py строит normalized_query.
  3. modules/target_terms.py извлекает:
    • target_terms
    • endpoint_paths
    • matched_aliases
    • alias_docs
  4. modules/anchors.py строит:
    • anchors
    • file_markers
    • architecture_markers
    • logic_markers
    • domain_markers
    • endpoint_markers
  5. router.py собирает QueryFeatures.
  6. routers/llm.py вызывается как основной селектор маршрута.
  7. routers/validator.py проверяет:
    • что значения входят в допустимые enum
    • что комбинация маршрута разрешена
    • что confidence можно привести к float
  8. routers/confidence.py корректирует confidence на основе силы сигналов.
  9. Если ответ LLM валиден, возвращается V2RouteResult с routing_mode="llm_default".
  10. Если LLM не ответил, вернул сломанный JSON или невалидный маршрут, routers/fallback.py строит fallback route:
    • FIND_FILES, если есть file_markers
    • DOCS / DOC_EXPLAIN / SUMMARY, если есть docs-oriented anchors
    • иначе GENERAL / GENERAL_QA / SUMMARY

5. Компоненты по флоу

router.py

  • Задача Оркестрировать полный routing pipeline.

  • Как решает Последовательно вызывает:

    • normalizer
    • target terms extractor
    • anchor extractor
    • LLM router
    • validator
    • confidence adjuster
    • fallback router
  • Вход user_query: str

  • Выход V2RouteResult

modules/normalizer.py

  • Задача Привести запрос к стабильной форме для анализа.

  • Как решает Схлопывает лишние пробелы через " ".join(...split()).

  • Вход user_query: str

  • Выход normalized_query: str

modules/target_terms.py

  • Задача Построить чистое retrieval-поле target_terms.

  • Как решает Использует позитивную модель отбора и включает в target_terms только:

    • endpoint paths
    • identifier-like tokens
    • alias canonical terms
    • domain terms

    Исключаются:

    • question words
    • intent words
    • filler/noisy words
    • marker words
    • короткие токены < 3, если это не endpoint или alias
    • битые path-like токены

    Дополнительно:

    • lowercase
    • trim punctuation по краям
    • dedupe
    • ограничение до 7 элементов
    • приоритет: endpoints → identifiers → aliases → domain terms
  • Вход normalized_query: str

  • Выход TargetTermsAnalysis:

    • target_terms
    • endpoint_paths
    • matched_aliases
    • alias_docs

modules/anchors.py

  • Задача Построить anchors и marker-сигналы, не смешивая их с target_terms.

  • Как решает Извлекает:

    • entity_names из PascalCase-like токенов
    • file_names только по жёстким правилам:
      • *.md, *.yaml, *.yml, *.json
      • docs/..., doc/..., documentation/...
    • endpoint_paths из TargetTermsAnalysis
    • target_doc_hints из alias docs, endpoint map и marker-сигналов

    Marker-сигналы живут отдельно:

    • file_markers
    • architecture_markers
    • logic_markers
    • domain_markers
    • endpoint_markers
  • Вход

    • normalized_query: str
    • TargetTermsAnalysis
  • Выход AnchorAnalysis

routers/route_catalog.py

  • Задача Держать один источник истины для допустимых маршрутов.

  • Как решает Возвращает:

    • список allowed_routes для payload LLM
    • проверку допустимости комбинации routing_domain + intent + subintent

routers/llm.py

  • Задача Выбрать маршрут через LLM как основной селектор.

  • Как решает Формирует JSON payload из:

    • normalized_query
    • target_terms
    • anchors
    • allowed_routes

    Затем:

    • вызывает LLM
    • парсит JSON
    • возвращает сырой candidate route без deterministic business-routing
  • Вход

    • normalized_query: str
    • target_terms: list[str]
    • anchors: dict
  • Выход dict | None

routers/validator.py

  • Задача Deterministic validation ответа LLM.

  • Как решает Проверяет:

    • что routing_domain, intent, subintent заполнены
    • что комбинация маршрута входит в route_catalog
    • что confidence можно привести к числу
  • Вход dict | None

  • Выход Валидированный dict | None

routers/confidence.py

  • Задача Сделать confidence осмысленным после ответа LLM.

  • Как решает Корректирует confidence:

    • -0.1, если нет strong anchors
    • -0.1, если запрос короткий или vague
    • +0.05, если есть явный signal (file_markers, endpoint_paths, endpoint_markers)
    • затем clamp в диапазон 0.0..1.0
  • Вход

    • confidence: float
    • QueryFeatures
  • Выход confidence: float

routers/fallback.py

  • Задача Построить deterministic fallback, если LLM невалиден.

  • Как решает Правила:

    • есть file_markersDOCS / DOC_EXPLAIN / FIND_FILES
    • есть docs-signals (endpoint_paths, target_doc_hints, matched_aliases, marker groups) → DOCS / DOC_EXPLAIN / SUMMARY
    • иначе → GENERAL / GENERAL_QA / SUMMARY
  • Вход

    • user_query: str
    • QueryFeatures
    • anchors: V2RouteAnchors
    • llm_attempted: bool
  • Выход V2RouteResult

routers/prompts.yml

  • Задача Задать LLM-router контракт ответа и guidance по confidence.

  • Как решает Ограничивает модель только allowed_routes и требует JSON с полями:

    • routing_domain
    • intent
    • subintent
    • confidence
    • reason_short

6. Ключевые инварианты

  • LLM является default router.
  • Deterministic-слой не принимает основной routing decision.
  • target_terms содержат только retrieval-useful terms.
  • anchors не содержат terms.
  • /health и другие endpoint paths не должны попадать в file_names, если это не файл с расширением.
  • file_names содержат только реальные file/doc paths.
  • Fallback используется только если LLM недоступен или вернул невалидный маршрут.