feat(classifier): optional GigaChat-2-Lite hybrid tier classify
LLM classify via LiteLLM gigachat-classifier when heuristic confidence is low. CLASSIFIER_MODE=heuristic|hybrid|llm. Metrics classifier_source.
This commit is contained in:
+21
-4
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user