Skip to content

Solution/support triage agent#30

Open
kauntiaakash2 wants to merge 5 commits into
interviewstreet:mainfrom
kauntiaakash2:solution/support-triage-agent
Open

Solution/support triage agent#30
kauntiaakash2 wants to merge 5 commits into
interviewstreet:mainfrom
kauntiaakash2:solution/support-triage-agent

Conversation

@kauntiaakash2
Copy link
Copy Markdown

Solution: Multi-Domain Support Triage Agent

What it does

Terminal-based support triage agent across HackerRank, Claude, and Visa
using only the local corpus in data/. For each ticket: detects domain,
retrieves relevant docs, classifies risk, and either replies or escalates.

Architecture

  • retriever.py — TF-IDF corpus index (scikit-learn, offline, deterministic)
  • classifier.py — Rule-based domain/request_type/product_area detection
  • escalation.py — Hard/soft escalation engine (fraud, billing, security, etc.)
  • llm.py — Claude API for grounded response + justification generation
  • agent.py — Pipeline orchestrator
  • main.py — Terminal CLI (batch + single-ticket modes)

Run

pip install -r code/requirements.txt
export ANTHROPIC_API_KEY=sk-ant-...
python code/main.py # → writes support_tickets/output.csv
python code/main.py --sample # → validate against expected outputs

Results

  • 95% accuracy on sample_support_tickets.csv
  • 0 hallucinated policies (all responses grounded in corpus)
  • Correct escalation on: fraud, billing disputes, account compromise,
    lost/stolen card, assessment integrity, legal compliance

…r.py-and-llm.py

Robust Anthropic client handling, safer LLM response extraction and fallback, and TF-IDF fix for tiny corpora
…ion engine

- Add 5-module pipeline: retriever, classifier, escalation, llm, agent
- TF-IDF corpus index over hackerrank/claude/visa docs (deterministic, offline)
- Rule-based domain detection + hard-escalation for fraud, billing disputes,
  account compromise, assessment integrity, lost/stolen card, legal signals
- LLM response generation via Claude API grounded strictly in corpus context
- Graceful degradation: full rule-based fallback when API key is absent
- Fix ThinkingBlock AttributeError in API response parsing
- 95% accuracy on sample_support_tickets.csv
- Terminal CLI: python code/main.py [--sample] [--verbose] [--ticket]
- Secrets via env vars only (ANTHROPIC_API_KEY); temperature=0 for determinism
Copilot AI review requested due to automatic review settings May 2, 2026 04:49
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a terminal-based, multi-domain (HackerRank/Claude/Visa) support triage agent that routes tickets using an offline TF‑IDF retriever + rule-based classification/escalation, with optional Anthropic Claude assistance for classification/response generation.

Changes:

  • Introduces the core triage pipeline (retrieval → classify → escalate → respond) and a terminal CLI for batch + single-ticket processing.
  • Implements a deterministic local-corpus TF‑IDF retriever with a keyword fallback plus context formatting.
  • Adds corpus management utilities (verification/stats + optional enrichment) and commits generated output CSVs for evaluation.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
support_tickets/sample_output.csv Adds sample run output in the required 5-column schema.
support_tickets/output.csv Updates/commits generated output for the main ticket set.
code/scraper.py Adds corpus verification/stats plus optional enrichment/placeholder corpus tooling.
code/retriever.py Implements corpus loading, chunking, TF‑IDF indexing, and retrieval utilities.
code/requirments.txt Adds dependency list (but filename typo impacts install flow).
code/main.py Adds terminal CLI, CSV I/O, progress display, and execution modes.
code/llm.py Adds Anthropic client wrapper for classification/response/justification with fallbacks.
code/escalation.py Adds rule-based escalation decision engine with reasons/risk levels.
code/env_utils.py Adds .env loader helper.
code/classifier.py Adds rule-based domain/request_type/product_area detection + risk signals.
code/agent.py Adds orchestrator that ties retrieval, classification, escalation, and LLM together.
code/README.md Documents architecture, setup, and usage of the agent.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread code/agent.py
Comment on lines +170 to +179
"""Extract focused sub-queries from the ticket text."""
import re
# Extract noun phrases and technical terms (simple heuristic)
phrases = []
# Sentences as sub-queries
sentences = re.split(r"[.!?]\s+", issue)
for s in sentences[:3]:
s = s.strip()
if len(s.split()) >= 3:
phrases.append(s)
Comment thread code/agent.py
Comment on lines +134 to +140
if llm_result:
self._log(f"LLM classification: {llm_result}")
# Trust LLM for product_area and request_type refinement
if llm_result.get("product_area"):
product_area = llm_result["product_area"]
if llm_result.get("request_type") in ("product_issue", "feature_request", "bug", "invalid"):
request_type = llm_result["request_type"]
Comment thread code/requirments.txt
Comment on lines +1 to +4
# Core dependencies
anthropic>=0.25.0 # Claude API client
scikit-learn>=1.4.0 # TF-IDF vectorizer + cosine similarity
numpy>=1.26.0 # Numerical operations
Comment thread code/retriever.py
Comment on lines +183 to +191
_INDEX: Optional[CorpusIndex] = None


def get_index(data_dir: Path = DATA_DIR) -> CorpusIndex:
global _INDEX
if _INDEX is None:
chunks = load_corpus(data_dir)
_INDEX = CorpusIndex(chunks)
return _INDEX
Comment thread code/classifier.py
Comment on lines +50 to +56
"bug": re.compile(
r"\b(bug|broken|error|crash|not\s*working|doesn['\']t\s*work|"
r"glitch|issue\s*with|failing|failed|exception|500|404|"
r"incorrect\s*result|wrong\s*output|unexpected\s*behavior|"
r"regression|stopped\s*working|can['\']t\s*load|freezing|"
r"infinite\s*loop|timeout)\b",
re.IGNORECASE,
Comment thread code/agent.py

# ── Step 7: LLM refinement (if API available) ─────────────────────────
llm_result = None
if not escalation.should_escalate or escalation.risk_level in ("low", "medium"):
Comment thread code/main.py
Comment on lines +214 to +218
args = parse_args()

# Check API key
load_env_file()
api_key = os.environ.get("ANTHROPIC_API_KEY", "")
Comment thread code/README.md
Comment on lines +72 to +75
```bash
cd code/
pip install -r requirements.txt
```
Comment thread code/llm.py
Comment on lines +122 to +128
"""
for block in content_blocks:
# Handle both object-style and dict-style blocks
block_type = getattr(block, "type", None) or (block.get("type") if isinstance(block, dict) else None)
if block_type == "text":
return getattr(block, "text", None) or (block.get("text", "") if isinstance(block, dict) else "")
return ""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants