Skip to main content

Task Classifier

Overview​

The task classifier analyzes user prompts to determine complexity level, then routes the request to an appropriate model tier — cheap models for simple tasks, premium models for complex ones. This is the moat #1 feature that differentiates Yabanin from generic proxies.

Architecture​

┌─────────────┐
Request ───────► │ Classifier │
│ Pipeline │
└──────┬──────┘
│
┌────────────┼────────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Easy │ │ Medium │ │ Hard │
│ ↓ │ │ ↓ │ │ ↓ │
│ Cheap │ │ Mid │ │ Premium │
│ Pool │ │ Pool │ │ Pool │
└─────────┘ └─────────┘ └─────────┘

Components​

ComponentPackageDescription
Classifier interfacepkg/classifier/classifier.goClassifier interface with Classify() and Name() methods
Rule tier V0pkg/classifier/rule_tier.goDeterministic classification based on prompt features (keywords, length, code fences)
ML classifier V1pkg/classifier/ml_v1.goHTTP client for self-hosted bge-small-en-v1.5 model service
Classifier cachepkg/classifier/registry_cached*.go4-tier lookup: Redis exact → DB exact → DB semantic (pgvector) → inner classifier
Tier routerpkg/router/tier_pool.goWeighted round-robin pool selection per complexity class
Circuit breakerpkg/classifier/circuit_breaker.goClosed/Open/HalfOpen state machine for ML service health
Evalgate judgepkg/evalgate/judge.goLLM-as-judge quality evaluation comparing cheap vs premium responses
Calibrationpkg/classifier/calibration.goPlatt scaling to align classifier confidence with actual accuracy
A/B assignerpkg/classifier/ab_assigner.goDeterministic SHA-256 bucketing for classifier experiments
Feedback collectorpkg/feedback/collector.goRecords thumbs_up/down/regenerate signals for online learning

Classification Classes​

ClassDescriptionExample keywordsMapped tier
EasySimple, short prompts with clear intentsummarize, translate, list, extract, name, what isCheap pool (gpt-4o-mini)
MediumGeneral questions, moderate complexityNo strong markers, 200–2000 tokensMid pool
HardComplex reasoning, debugging, architecturedebug, architect, step by step, code review, troubleshootPremium pool (gpt-4o)

Per-Org Routing Modes​

Each organization can override routing behavior via the admin API:

ModeBehaviorThreshold
auto (default)Route by classifier confidence0.6
aggressive_costAggressive cheap routing0.4
always_premiumAll requests → premium poolN/A
always_cheapAll requests → cheap poolN/A
classifier_onlyOnly route when very confident0.9
disabledSkip classifier entirelyN/A

Admin API​

GET /api/organizations/{id}/routing # Get org routing settings
PATCH /api/organizations/{id}/routing # Update routing_mode + threshold (root only)
POST /v1/feedback # Submit thumbs_up/down/regenerate feedback (Authorization: Bearer <org or agent API key>; the org is derived from the key)

Configuration​

Env varDefaultDescription
YABANIN_CLASSIFIER_SERVICE_URL""ML classifier service URL (empty = rule-tier only)
YABANIN_EVALGATE_URL""Judge endpoint for quality evaluation
YABANIN_EVALGATE_API_KEY""API key for judge endpoint
YABANIN_EVALGATE_MODELgpt-4o-miniModel to use as judge
YABANIN_EVALGATE_SAMPLE_RATE0.05Fraction of Medium/low-conf requests to sample
YABANIN_CLASSIFIER_CIRCUIT_ENABLEDtrueEnable circuit breaker for ML service
YABANIN_CLASSIFIER_CIRCUIT_THRESHOLD3Consecutive failures before open state
YABANIN_CLASSIFIER_CIRCUIT_TIMEOUT30sDuration to stay in open state

Metrics​

MetricTypeLabelsDescription
classifier_class_totalCounterclass, sourceClassification counts by class and source
classifier_confidenceHistogram—Classification confidence distribution
classifier_latency_secondsHistogramsourceClassification latency
tier_routing_totalCounterclass, from_model, to_modelModel routing decisions
tier_routing_skipped_totalCounterreasonSkipped routings (low_confidence, etc.)
classifier_cache_hit_totalCountertypeCache hits by type (exact/semantic)
classifier_circuit_breaker_stateGaugeclassifierCircuit breaker state (0=closed, 1=open, 2=half-open)
evalgate_verdict_totalCountershould_upgradeJudge verdict counts
evalgate_latency_secondsHistogram—Judge evaluation latency

Adding a New Rule​

Rules are defined in pkg/classifier/rule_tier.go in the Classify method. The rule order is:

  1. Hard rules checked first (prompt >2000 tokens, hard keywords, code fences >50 lines, tool calls)
  2. Easy rules checked second (short prompt + easy keywords, no code fences)
  3. Default → Medium

To add a new rule:

  1. Add the keyword or pattern to features.go keyword lists
  2. Add a check in rule_tier.go before the default Medium return
  3. Set appropriate confidence value (0.60–0.90)
  4. Add a test case in rule_tier_test.go

Retraining ML Model​

  1. Generate dataset: python scripts/build_dataset.py --output datasets/classifier/prompts_train.jsonl
  2. Fine-tune: python scripts/train_classifier.py --train datasets/classifier/prompts_train.jsonl --test datasets/classifier/prompts_test.jsonl --output artifacts/classifier-v1.pt
  3. Export to ONNX for serving (requires optimum package):
    optimum export onnx --model artifacts/classifier-v1.pt --task text-classification classifier.onnx
  4. Deploy new model weights to classifier service and restart

Limitations​

  • English-language prompts only (bge-small-en-v1.5)
  • Very short prompts (under 20 chars) may be miscategorized
  • Multi-modal prompts (images, files) are analyzed by text content only
  • Classifier does not consider conversation history depth beyond token count