feat(classifier): optional GigaChat-2-Lite hybrid tier classify
CI / build-gateway (push) Successful in 3s
CI / sync-config (push) Successful in 1s

LLM classify via LiteLLM gigachat-classifier when heuristic confidence
is low. CLASSIFIER_MODE=heuristic|hybrid|llm. Metrics classifier_source.
This commit is contained in:
2026-08-07 22:21:27 +03:00
parent 83d516afa1
commit 6fd2f0e689
11 changed files with 213 additions and 7 deletions
+21 -4
View File
@@ -11,6 +11,7 @@ from dataclasses import dataclass, field
from enum import Enum
from typing import Any
from classifier_llm import LlmClassifier
from rules_loader import load_model_matrix, load_orchestration, load_routing_rules
log = logging.getLogger("orchestrator")
@@ -54,6 +55,7 @@ class RouteDecision:
escalation_level: int
confidence: float
delegated_internal: bool = False
classifier_source: str = "heuristic"
class SessionStore:
@@ -172,6 +174,7 @@ class Orchestrator:
def __init__(self, session_store: SessionStore) -> None:
self.sessions = session_store
self.classifier = Classifier()
self.llm_classifier = LlmClassifier()
self._orch = load_orchestration()
self._matrix = load_model_matrix()
self._models: dict[str, dict] = self._matrix.get("models", {})
@@ -217,7 +220,7 @@ class Orchestrator:
suffix = TIER_SUFFIX[tier]
return f"{prefix}-{suffix}"
def resolve(
async def resolve(
self,
messages: list[dict[str, Any]],
*,
@@ -229,6 +232,17 @@ class Orchestrator:
) -> RouteDecision:
mode = quality_mode or self.default_quality
tier, confidence = self.classifier.classify(messages, has_image=has_image, text=text)
classifier_source = "heuristic"
if self.llm_classifier.should_use_llm(tier.value, confidence, has_image):
llm_result = await self.llm_classifier.classify(text)
if llm_result:
tier = Tier(llm_result[0])
confidence = llm_result[1]
classifier_source = "gigachat"
elif self.llm_classifier.mode == "llm":
classifier_source = "heuristic_fallback"
ctx = self.sessions.get(session_id)
prompt_hash = hashlib.sha256(text.encode()).hexdigest()[:16]
@@ -263,11 +277,13 @@ class Orchestrator:
escalation_level=escalation,
confidence=confidence,
delegated_internal=True,
classifier_source=classifier_source,
)
delegated = confidence < self.classifier._low_conf and tier in (
Tier.MEDIUM_OPS,
Tier.SIMPLE,
delegated = (
classifier_source == "heuristic"
and confidence < self.classifier._low_conf
and tier in (Tier.MEDIUM_OPS, Tier.SIMPLE)
)
return RouteDecision(
@@ -278,6 +294,7 @@ class Orchestrator:
escalation_level=escalation,
confidence=confidence,
delegated_internal=delegated,
classifier_source=classifier_source,
)
def after_request(