CoolFace
Apppublic

Harshvardhan-M/customer-support-triage

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes
App README

๐ŸŽง Customer Support Triage โ€” OpenEnv Environment

An OpenEnv-compliant RL environment where AI agents learn to triage real-world customer support tickets: classify urgency, route to departments, escalate sensitive cases, and draft responses.

๐Ÿ‘‰ [Interactive Demo โ†’](/demo)


Why This Environment?

Customer support triage is a high-volume, high-stakes real-world task:

  • โ€”Misrouting or mis-prioritizing tickets costs revenue and customer trust
  • โ€”Requires multi-step reasoning: inferring urgency from tone, applying business rules, recognising legal risk
  • โ€”Evaluation is deterministic โ€” no human labellers needed
  • โ€”The RL/agent community can immediately use this for evaluation and training

Tasks

TaskDifficultyMax StepsDescription
urgency_classification๐ŸŸข Easy10Classify 5 tickets as low\medium\high\critical. Partial credit for adjacent levels.
department_routing๐ŸŸก Medium18Route 6 tickets to billing\technical\returns\general\manager. Optional urgency bonus.
full_triage๐Ÿ”ด Hard40Handle 5 complex tickets: classify โ†’ route โ†’ escalate โ†’ draft response โ†’ resolve.

API

bash
# Reset
curl -X POST http://localhost:7860/reset \
  -H "Content-Type: application/json" \
  -d '{"task_name": "full_triage"}'

# Step
curl -X POST http://localhost:7860/step \
  -H "Content-Type: application/json" \
  -d '{"action_type": "classify", "urgency": "critical"}'

# State
curl http://localhost:7860/state

# Validate spec compliance
curl http://localhost:7860/validate
EndpointMethodDescription
/GETHealth check
/resetPOSTStart episode: {"task_name": "..."}
/stepPOSTTake action
/stateGETFull internal state
/tasksGETTask metadata
/validateGETOpenEnv spec compliance check
/docsGETSwagger UI
/demoGETInteractive Gradio demo

Observation Space

json
{
  "current_ticket": {
    "ticket_id": "TKT-005",
    "subject": "URGENT: Production database is DOWN",
    "body": "...",
    "product": "CloudDB Enterprise",
    "channel": "phone",
    "created_at": "2024-03-15T02:47:00Z"
  },
  "customer": {
    "email": "sre@megacorp.com",
    "tier": "enterprise",
    "account_age_days": 1825,
    "total_tickets": 42,
    "previous_tickets": [...]
  },
  "queue_position": 3,
  "total_in_queue": 5,
  "task_name": "full_triage",
  "available_actions": ["classify","route","escalate","draft_response","resolve"],
  "step_count": 7,
  "episode_reward": 0.85,
  "done": false,
  "last_action_feedback": "dept='technical' vs 'billing' โ†’ 0.00",
  "last_action_error": null
}

Action Space

json
{
  "action_type": "draft_response",
  "response_draft": "We are treating this as a P0 incident and escalating immediately.",
  "reasoning": "Enterprise customer, $3k/min revenue loss โ€” needs immediate human escalation."
}
FieldTypeValues
action_typestring (required)classify \route \escalate \draft_response \resolve \request_info
urgencystring\nulllow \medium \high \critical
departmentstring\nullbilling \technical \returns \general \manager
response_draftstring\nullCustomer-facing text
escalate_reasonstring\nullReason for escalation
reasoningstring\nullChain of thought (not scored)

Reward Function

Shaped across the full trajectory โ€” not sparse:

ComponentDescription
urgency_accuracyPartial credit: 1.0 exact, 0.5 off-by-1, 0.2 off-by-2
routing_accuracyBinary: 1.0 correct department, 0.0 wrong
escalation_correctnessCorrect=+1.0, wrong decision=โˆ’0.3
response_qualityKeyword coverage of expected response terms
efficiency_bonusFast resolution of critical tickets
error_penaltyInvalid actions, approaching step limit
Terminal+0.3 if final score โ‰ฅ 0.9, โˆ’0.2 if < 0.4

Reward clamped to [โˆ’1.0, 1.0] per step.


Setup

bash
# Local
pip install -r requirements.txt
uvicorn app:app --host 0.0.0.0 --port 7860

# Docker
docker build -t cst-env .
docker run -p 7860:7860 cst-env

# Run baseline agent
export API_BASE_URL="https://api.openai.com/v1"
export MODEL_NAME="gpt-4o-mini"
export HF_TOKEN="your-key"
export ENV_BASE_URL="http://localhost:7860"
python inference.py

# Pre-submission validation
python validate.py

Baseline Scores

Measured with gpt-4o-mini at temperature 0:

TaskDifficultyGrader Score
urgency_classificationEasy~0.72
department_routingMedium~0.61
full_triageHard~0.38

The hard task genuinely challenges frontier models โ€” escalation decisions and response quality both require multi-step business reasoning.


Project Structure

โ”œโ”€โ”€ app.py              FastAPI app (HF Space entry point)
โ”œโ”€โ”€ demo.py             Gradio interactive demo (mounted at /demo)
โ”œโ”€โ”€ inference.py        Baseline agent script
โ”œโ”€โ”€ validate.py         Pre-submission validator
โ”œโ”€โ”€ openenv.yaml        OpenEnv spec metadata
โ”œโ”€โ”€ Dockerfile
โ”œโ”€โ”€ requirements.txt
โ”œโ”€โ”€ README.md
โ””โ”€โ”€ env/
    โ”œโ”€โ”€ __init__.py
    โ”œโ”€โ”€ environment.py  Core OpenEnv class: reset() / step() / state()
    โ”œโ”€โ”€ models.py       Pydantic models: Observation, Action, Reward
    โ”œโ”€โ”€ ticket_data.py  13 synthetic tickets with ground-truth labels
    โ”œโ”€โ”€ graders.py      Deterministic graders for all 3 tasks
    โ””โ”€โ”€ reward.py       Shaped reward function

OpenEnv Compliance

  • โ€”[x] Typed Pydantic models: TriageObservation, TriageAction, TriageReward
  • โ€”[x] reset(task_name) โ†’ TriageObservation
  • โ€”[x] step(action) โ†’ (observation, reward, done, info)
  • โ€”[x] state() โ†’ full internal state dict
  • โ€”[x] openenv.yaml with complete metadata
  • โ€”[x] 3 tasks: easy โ†’ medium โ†’ hard
  • โ€”[x] All grader scores in [0.0, 1.0], deterministic
  • โ€”[x] Non-sparse shaped reward
  • โ€”[x] inference.py using OpenAI client
  • โ€”[x] Working Dockerfile
  • โ€”[x] 22/22 unit tests passing