Multi-domain support triage for HackerRank, Claude, and Visa.
pip install -r requirements.txt# 1. Build the corpus (scrapes + synthetic fallback)
cd code && python code/scraper.py
# 2. Run the triage agent on your input CSV
python code/main.py --input input/support_tickets.csv --output output/output.csvhackerrank_orchertrator/
├── code/
│ ├── main.py # CLI entry point
│ ├── triage.py # Core decision pipeline
│ ├── classifier.py # Request type + risk + product classification
│ ├── retriever.py # FAISS dense retriever (TF-IDF fallback)
│ ├── responder.py # Grounded response generation
│ ├── chunker.py # Document chunking
│ ├── indexer.py # Index builder
│ ├── scraper.py # Support doc scraper + synthetic corpus
│ ├── evaluator.py # Precision@k + MRR evaluation
│ └── utils.py # CSV normalisation, logging, doc loading
├── data/
│ ├── corpus_raw.json # Scraped + synthetic support docs
│ └── corpus_chunks.json
├── input/
│ └── support_tickets.csv
├── output/
│ └── output.csv
├── logs/
│ └── log.txt
└── requirements.txt
Input Ticket
↓
Preprocessing (normalise CSV columns, combine subject + issue)
↓
Classify: request_type (fraud/billing/account_access/bug/feature_request/general_inquiry/invalid)
product_area (hackerrank/claude/visa/general)
risk_signals (fraud, injection, data breach, etc.)
↓
Retrieve: TF-IDF (default) or BGE+FAISS+CrossEncoder if HuggingFace available
Product-filtered → falls back to global pool if no matches
↓
Decision:
• invalid / fraud → always escalate
• risky billing/account_access → escalate
• no relevant docs found → escalate (no hallucination)
• otherwise → reply with grounded response
↓
Response: empathetic opener + up to 3 deduplicated corpus passages + footer
↓
Log to logs/log.txt
- No hallucination guarantee: Only corpus text is included in responses.
- Flexible CSV ingestion: Column names are resolved case-insensitively (
Issue,issue,ISSUEall work). - Two-tier retriever: Dense BGE+FAISS when HuggingFace is reachable; TF-IDF bigram otherwise — same interface.
- Conservative escalation: Fraud is always escalated. Billing/account-access escalates only when specific risk signals are detected (avoiding over-escalation of innocent queries).
- Corpus extensibility: Add more docs to
data/corpus_raw.jsonor runscraper.pywith additional URLs.