Nimbus-Bank-Triage / src /agents /classifier.py
MrNoOne07's picture
Upload folder using huggingface_hub
6848579 verified
Raw
History Blame Contribute Delete
3.21 kB
"""
Nimbus Bank Triage β€” Classifier Agent
Reads the sanitized ticket and produces a structured classification:
category, urgency, sentiment, confidence, and reasoning.
Uses Claude Haiku at temperature 0.0 for deterministic results.
"""
import os
from typing import Literal
from langchain_core.messages import SystemMessage, HumanMessage
from pydantic import BaseModel, Field
from src.utils.models import get_fast_llm, invoke_structured_with_retry
# ── Load classifier prompt ───────────────────────────────────
_PROMPT_PATH = os.path.join(
os.path.dirname(os.path.dirname(__file__)), "prompts", "classifier.md"
)
with open(_PROMPT_PATH, "r", encoding="utf-8") as f:
CLASSIFIER_SYSTEM_PROMPT = f.read()
# Confidence threshold β€” below this, ticket is flagged for human triage
CONFIDENCE_THRESHOLD = int(os.environ.get("CLASSIFIER_CONFIDENCE_THRESHOLD", "70"))
# ── Structured output schema ────────────────────────────────
class ClassificationResult(BaseModel):
category: Literal["Fraud", "Dispute", "Access_Issue", "Inquiry"] = Field(
description="Ticket category"
)
urgency: Literal["Critical", "High", "Medium", "Low"] = Field(
description="Urgency level"
)
sentiment: Literal["Angry", "Distressed", "Neutral", "Positive"] = Field(
description="Customer sentiment"
)
confidence: int = Field(ge=0, le=100, description="Classification confidence 0-100")
reasoning: str = Field(description="Short explanation for the audit log")
def classify_ticket(state: dict) -> dict:
"""
Classifier Agent node function.
Reads the wrapped payload from state and produces a structured
classification with category, urgency, sentiment, and confidence.
Args:
state: Current TriageState dict
Returns:
Partial state update with classification fields.
"""
wrapped_payload = state.get("wrapped_payload", "")
errors = list(state.get("errors", []))
try:
llm = get_fast_llm()
result = invoke_structured_with_retry(
llm=llm,
messages=[
SystemMessage(content=CLASSIFIER_SYSTEM_PROMPT),
HumanMessage(content=f"Classify this support ticket:\n\n{wrapped_payload}"),
],
schema=ClassificationResult,
)
return {
"category": result["category"],
"urgency": result["urgency"],
"sentiment": result["sentiment"],
"classifier_confidence": result["confidence"],
"classifier_reasoning": result["reasoning"],
"errors": errors,
}
except Exception as e:
# Classification failure β†’ low confidence forces human triage
errors.append(f"classifier_error: {type(e).__name__}: {e}")
return {
"category": "Inquiry",
"urgency": "High",
"sentiment": "Neutral",
"classifier_confidence": 0,
"classifier_reasoning": f"Classification failed: {type(e).__name__}",
"errors": errors,
}