Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

26 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🧠 Multi-Domain Support Triage Agent

Python 3.9+ scikit-learn Domains Terminal HackerRank Orchestrate

A production-grade, fully offline support-triage pipeline that ingests raw support tickets, classifies them across three enterprise domains, evaluates risk and safety, retrieves grounded documentation, and generates safe β€” or escalates sensitive β€” responses. No LLM API calls. No hallucinations.


✨ What Makes This Agent Different

Capability Detail
🏷️ Multi-signal classification Weighted n-gram taxonomy with TF-IDF normalization, exclusivity bonus & confidence calibration
πŸ” BM25-inspired retrieval Dual-signal ranking (TF-IDF cosine + Jaccard-like lexical overlap) with length normalization
πŸ›‘οΈ 4-tier safety engine Critical β†’ High β†’ Medium β†’ Low risk matrix with diminishing-returns scoring & audit trail
πŸ“ Grounded responses Sentence-level extraction from corpus β€” zero fabricated policies
⚑ Fast & offline Pure NumPy/sklearn pipeline; processes 100+ tickets per minute on a laptop
πŸ“Š Full observability Per-ticket confidence scores, processing time (ms), and escalation reasons exported to CSV

πŸ—‚οΈ Repository Layout

orchestrate-support-agent/
β”‚
β”œβ”€β”€ code/
β”‚   β”œβ”€β”€ main.py          # πŸš€ Entry point β€” orchestrates the full pipeline
β”‚   β”œβ”€β”€ classifier.py    # 🏷️  Multi-signal domain & request-type classifier
β”‚   β”œβ”€β”€ retriever.py     # πŸ” BM25-inspired TF-IDF retriever with query expansion
β”‚   β”œβ”€β”€ safety.py        # πŸ›‘οΈ  4-tier risk engine with confidence-adjusted thresholds
β”‚   └── responder.py     # πŸ“ Sentence-extraction response generator
β”‚
β”œβ”€β”€ data/
β”‚   β”œβ”€β”€ hackerrank/      # Scraped HackerRank support corpus (.txt / .md / .html)
β”‚   β”œβ”€β”€ claude/          # Claude Help Center corpus
β”‚   └── visa/            # Visa Support corpus
β”‚
β”œβ”€β”€ support_tickets/
β”‚   β”œβ”€β”€ sample_support_tickets.csv   # Labelled examples for validation
β”‚   β”œβ”€β”€ support_tickets.csv          # 🎯 Competition input β€” run the agent against this
β”‚   └── output.csv                   # βœ… Agent-generated results
β”‚
β”œβ”€β”€ .env.example         # Copy β†’ .env and fill in any optional API keys
β”œβ”€β”€ AGENTS.md            # Agent-framework rules & logging contract
└── README.md            # You are here

πŸ”¬ Pipeline Architecture

                     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                     β”‚         support_tickets.csv          β”‚
                     β”‚  issue | subject | company           β”‚
                     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                        β”‚  for each row
                                        β–Ό
                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                          β”‚      🏷️  CLASSIFIER       β”‚
                          β”‚  ─────────────────────   β”‚
                          β”‚  β€’ n-gram keyword match  β”‚
                          β”‚  β€’ TF-IDF score per       β”‚
                          β”‚    domain                 β”‚
                          β”‚  β€’ Exclusivity bonus      β”‚
                          β”‚  β€’ Confidence 0 β†’ 1       β”‚
                          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                       β”‚
                     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                     β”‚  Confidence < threshold?            β”‚
                     β”‚  YES ──► ESCALATE                  β”‚
                     β”‚  NO  ──► continue                  β”‚
                     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                       β”‚
                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                          β”‚      πŸ›‘οΈ  SAFETY ENGINE    β”‚
                          β”‚  ─────────────────────   β”‚
                          β”‚  Critical / High β†’       β”‚
                          β”‚    auto-escalate         β”‚
                          β”‚  Medium + low conf β†’     β”‚
                          β”‚    escalate              β”‚
                          β”‚  Low β†’ pass through      β”‚
                          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                       β”‚
                     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                     β”‚  Safety triggered?                  β”‚
                     β”‚  YES ──► ESCALATE (with reason)    β”‚
                     β”‚  NO  ──► continue                  β”‚
                     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                       β”‚
                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                          β”‚      πŸ” RETRIEVER         β”‚
                          β”‚  ─────────────────────   β”‚
                          β”‚  β€’ Domain-specific index β”‚
                          β”‚  β€’ Query expansion       β”‚
                          β”‚  β€’ BM25 normalization    β”‚
                          β”‚  β€’ Lexical blend         β”‚
                          β”‚  β€’ top-k chunks          β”‚
                          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                       β”‚
                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                          β”‚      πŸ“ RESPONDER         β”‚
                          β”‚  ─────────────────────   β”‚
                          β”‚  β€’ Sentence extraction   β”‚
                          β”‚  β€’ Quality filtering     β”‚
                          β”‚  β€’ Token overlap scoring β”‚
                          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                       β”‚
                     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                     β”‚           output.csv                β”‚
                     β”‚  status | product_area | response   β”‚
                     β”‚  justification | request_type       β”‚
                     β”‚  classification_confidence          β”‚
                     β”‚  response_confidence | proc_ms      β”‚
                     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

🧩 Module Deep-Dive

classifier.py β€” Domain & Intent Classification

Classifies every ticket into a product domain and request type using a weighted keyword taxonomy β€” no LLM required.

  • Domains: hackerRank_assessments Β· claude_platform Β· visa_payments Β· general_support
  • Request types: bug Β· feature_request Β· billing_dispute Β· security Β· product_issue Β· invalid
  • Confidence model: match density + exclusivity bonus β†’ calibrated score [0, 0.98]

retriever.py β€” BM25-Inspired Document Retrieval

Builds per-domain TF-IDF indices at startup and retrieves the most relevant corpus chunks for each ticket.

Feature Implementation
Indexing TfidfVectorizer with bigrams & sublinear TF, 8 000 max features
Ranking (1 - 0.35) Γ— TF-IDF cosine + 0.35 Γ— lexical overlap
Length norm BM25 b = 0.4 normalization to prevent long-chunk bias
Query expansion Suffix-stemming & synonym seeds (e.g., payment β†’ pay, api β†’ endpoint)
Chunking 200-word windows, 40-word overlap, 15-word minimum
Fallback Primary domain β†’ general_support if no docs found

safety.py β€” 4-Tier Risk Engine

Every ticket is scanned against a compiled pattern library before any response is generated.

Tier Auto-Escalate? Example Triggers
πŸ”΄ Critical Always account compromised, identity theft, data breach
🟠 High Always fraud, stolen card, phishing, hack
🟑 Medium If confidence < 0.5 or composite score β‰₯ 4.0 refund, account locked, double charge
🟒 Low Never (score reducer) "how do I", "documentation", "what is"

Diminishing returns prevent score inflation when multiple patterns of the same tier fire.


responder.py β€” Grounded Response Generation

Extracts the single best-matching sentence from retrieved corpus chunks β€” never invents information.

  • Filters out boilerplate, navigation fragments, headings, and questions
  • Scores remaining sentences by token overlap with the query
  • Falls back to any well-formed sentence if no high-overlap match is found
  • Ensures capitalization and terminal punctuation

πŸš€ Quick Start

1 β€” Prerequisites

pip install pandas numpy scikit-learn

2 β€” Prepare the corpus

Place scraped support documentation under data/:

data/
  hackerrank/   ← HackerRank support pages (.txt / .md / .html)
  claude/       ← Claude Help Center pages
  visa/         ← Visa Support pages

The retriever auto-detects the domain from the directory name. Any .txt, .md, or .html file is indexed.

3 β€” Run the agent

cd code
python main.py

The agent reads ../support_tickets/support_tickets.csv, processes every row through the full pipeline, and writes results to ../support_tickets/output.csv.

Sample terminal output:

πŸ“š Loading domain-specific support corpus...
βœ… Retriever ready β€” 1 842 chunks across 3 domains.

[1] Processing...
[2] Processing...
...
[N] Processing...

βœ… output.csv updated successfully!

πŸ“€ Output Schema

Column Type Values
status string replied Β· escalated
product_area string hackerRank_assessments Β· claude_platform Β· visa_payments Β· general_support
response string User-facing answer or escalation message
justification string Why this decision was made
request_type string product_issue Β· feature_request Β· bug Β· invalid
classification_confidence float 0.0 – 1.0
response_confidence float 0.0 – 1.0
processing_ms int Wall-clock time per ticket in milliseconds

🧠 Design Principles

  1. Corpus-grounded only β€” the agent never uses outside knowledge or pre-trained LLM completions. Every response is extracted verbatim or synthesized exclusively from the provided documentation corpus.
  2. Fail safe β€” when in doubt, escalate. Low confidence, missing docs, and critical risk patterns all route to a human agent.
  3. Full auditability β€” every output row carries confidence scores, risk tier, and processing time so evaluators can trace every decision.
  4. Zero external calls β€” the entire pipeline runs locally with no network dependency at inference time.

πŸ“‹ Evaluation Criteria Alignment

Criterion How this agent addresses it
Correct status Safety engine + confidence thresholds provide deterministic escalation logic
Correct product_area Weighted n-gram taxonomy with exclusivity calibration
Grounded response Sentence extraction β€” only corpus text, never hallucinated
Meaningful justification Escalation reason or domain attribution appended to every row
Correct request_type Regex pattern hierarchy ordered from most β†’ least specific

πŸ† Certificate

HackerRank Orchestrate Certificate


πŸ“œ License & Attribution

Built for the HackerRank Orchestrate hackathon (May 2026).
Support corpus sourced from:


Built with πŸ” TF-IDF Β· πŸ›‘οΈ Safety-first design Β· πŸ“ Corpus-grounded responses

About

An AI-powered multi-agent customer support orchestration system built for intelligent query routing, automation, and scalable support workflows.

Topics

Resources

Stars

Watchers

Forks

Contributors

Languages