Dhanushkumarps
fix: utf-8 emoji encoding in yaml frontmatter
fcc9900
|
Raw
History Blame Contribute Delete
11.6 kB
metadata
title: Customer Support OpenEnv
emoji: πŸ‘½
colorFrom: blue
colorTo: green
sdk: docker
pinned: false

🎧 Customer Support OpenEnv

Python 3.10+ OpenEnv Hugging Face Spaces FastAPI License: MIT

OpenEnv Hackathon submission β€” a production-grade customer support simulation environment for training and evaluating LLM-based support agents.


🌍 Why This Environment?

Customer support is one of the most common enterprise AI use cases, yet no standard RL/agent benchmark exists for it.
This environment fills that gap: it provides a realistic, multi-difficulty, fully graded benchmark where agents must:

  • 🏷️ Classify support tickets into the correct category
  • ✍️ Respond empathetically and accurately to customer issues
  • πŸ—£οΈ Hold multi-turn conversations β€” clarify, resolve, and close tickets

All graded automatically with clear, deterministic rubrics (0.0–1.0) and meaningful partial rewards on every turn.


βš™οΈ How It Works β€” Workflow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                         AGENT LOOP                                  β”‚
β”‚                                                                     β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   POST /reset   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚   β”‚          β”‚ ──────────────► β”‚         FastAPI Server          β”‚  β”‚
β”‚   β”‚  Agent   β”‚                 β”‚         (server/app.py)         β”‚  β”‚
β”‚   β”‚ (client) β”‚ ◄────────────── β”‚                                 β”‚  β”‚
β”‚   β”‚          β”‚   Observation   β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚  β”‚
β”‚   β”‚          β”‚                 β”‚  β”‚   SupportEnvironment     β”‚   β”‚  β”‚
β”‚   β”‚          β”‚   POST /step    β”‚  β”‚   (environment.py)       β”‚   β”‚  β”‚
β”‚   β”‚          β”‚ ──────────────► β”‚  β”‚                          β”‚   β”‚  β”‚
β”‚   β”‚          β”‚   obs+reward    β”‚  β”‚  15 scenarios Γ— 5 types  β”‚   β”‚  β”‚
β”‚   β”‚          β”‚ ◄────────────── β”‚  β”‚  3 graders (easy/med/hrd)β”‚   β”‚  β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                 β”‚  β”‚  Cumulative reward logic β”‚   β”‚  β”‚
β”‚                                β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚  β”‚
β”‚   GET /state  ──────────────►  β”‚                                 β”‚  β”‚
β”‚   POST /grader ─────────────►  β”‚  Score + turn breakdown         β”‚  β”‚
β”‚   GET /tasks  ──────────────►  β”‚  Task list + action schemas     β”‚  β”‚
β”‚   POST /baseline ───────────►  β”‚  Built-in oracle agent scores   β”‚  β”‚
└───────────────────────────────────────────────────────────────────-β”€β”˜

Episode lifecycle:

  1. Agent calls POST /reset β†’ gets the opening customer message
  2. Agent sends replies via POST /step β†’ gets observation + reward each turn
  3. Agent calls POST /grader β†’ gets full score breakdown with turn_scores
  4. Episode ends when done: true in the observation

πŸ—‚οΈ Environment Description

Simulates a customer support system across 5 issue categories with 15 unique scenarios (3 per category):

Category Sample Scenarios
Refund Missing delivery refund, damaged product return, cancelled-order refund delay
Technical App crash after update, Slack webhook error, PDF export blank
Shipping 3-week missing order, wrong-door delivery, split shipment partial arrival
Billing Duplicate subscription charge, unauthorized upgrade charge, invoice ghost charge
Account Password reset email missing, account suspended, email address transfer

πŸ“₯ Action Space

Each agent step submits a SupportAction:

Field Type Required Description
message str βœ… The agent's text reply to the customer
intent str ❌ Declared intent: "classify", "respond", "clarify", "escalate", or "close"

πŸ“€ Observation Space

The environment returns a SupportObservation after each step:

Field Type Description
conversation List[str] Full message history (alternating customer / agent)
customer_query str The latest customer message the agent must address
task_name str Difficulty tier: "easy", "medium", or "hard"
done bool Whether the episode has ended
reward float | None Step-level reward (0.0–1.0); None on opening observation
cumulative_reward float Running average reward across all turns so far
turn_scores List[float] Per-turn reward breakdown (useful for analysis)
info str | None Optional context or hints for the agent

πŸ“‹ Tasks

🟒 Easy β€” Ticket Classification

Objective: Output the correct issue category for a customer message.

Scoring:

  • βœ… 1.0 β€” Exact category in reply (refund, billing, etc.)
  • 🟑 0.5 β€” Partial keyword match
  • ❌ 0.0 β€” Wrong or missing category
  • Max steps: 1

🟑 Medium β€” Single-Turn Response

Objective: Write a complete, empathetic reply resolving the customer's issue.

Scoring rubric:

Component Reward
+0.20 per matching keyword (max 4) 0.00–0.80
Empathy detected (apologize/sorry/understand) +0.10
Reply length > 80 chars +0.10
Unnecessary escalation penalty βˆ’0.20

All scores clamped to [0.0, 1.0]. Max steps: 1


πŸ”΄ Hard β€” Multi-Turn Conversation

Objective: Handle a 3-turn dialogue: clarify β†’ resolve β†’ close.

Turn Behaviour Max Reward
1 (clarify) Ask a ? question (bonus if on-topic) +0.40
2 (resolve) Keyword + empathy + detail +0.50
3 (close) Polite closing phrase +0.30

cumulative_reward = mean(turn_scores), clamped to [0.0, 1.0]. Max steps: 10


🎯 Reward Function Design

Signal When Magnitude
Correct classification Easy, step 1 +1.0 / +0.5 / 0.0
Keyword coverage Medium & Hard turn 2 +0.20 per keyword
Empathy language Medium & Hard turn 2 +0.10–+0.12
Response detail (length) Medium & Hard turn 2 +0.08–+0.10
Clarifying question Hard turn 1 +0.30 (+0.10 bonus)
Polite close Hard turn 3 +0.30
Unnecessary escalation Medium βˆ’0.20
Exceeding max steps All tasks Episode terminates

Key property: Every turn gives a partial signal β€” agents never wait until the end to learn if they did well.


πŸ”Œ API Endpoints

Method Endpoint Description
GET / Health check
POST /reset Start a new episode
POST /step Submit an agent action
GET /state Current session internal state
GET /tasks Task list with typed action schemas
POST /grader Score + turn breakdown for completed episode
POST /baseline Run built-in oracle agent, return average scores

πŸš€ Setup & Usage

1. Clone

git clone https://huggingface.co/spaces/sanathkumarps/customer_support_env
cd customer_support_env

2. Install

pip install -r requirements.txt

3. Run locally

uvicorn server.app:app --host 0.0.0.0 --port 7860 --reload

Visit http://localhost:7860/docs for interactive Swagger docs.

4. Run with Docker

docker build -t customer_support_env .
docker run -p 7860:7860 customer_support_env

5. Run the baseline evaluation

export GROQ_API_KEY="gsk-..."          # required
export ENV_BASE_URL="http://localhost:7860"   # optional
export GROQ_MODEL="llama-3.1-8b-instant"       # optional, default: llama-3.1-8b-instant

python run_baseline.py

Results print to console and save to baseline_scores.json.

6. Quick API test

# Health check
curl http://localhost:7860/

# Start easy episode
curl -X POST http://localhost:7860/reset \
  -H "Content-Type: application/json" \
  -d '{"task_name":"easy","seed":42}'

# Submit action (replace SESSION_ID)
curl -X POST http://localhost:7860/step \
  -H "Content-Type: application/json" \
  -d '{"session_id":"SESSION_ID","message":"refund","intent":"classify"}'

# Get grader score
curl -X POST http://localhost:7860/grader \
  -H "Content-Type: application/json" \
  -d '{"session_id":"SESSION_ID"}'

πŸ“Š Baseline Scores

Task Avg Score Model Episodes
Easy 0.90 llama-3.1-8b-instant 5
Medium 0.55 llama-3.1-8b-instant 5
Hard 0.40 llama-3.1-8b-instant 5

Run python run_baseline.py after starting the server to generate fresh scores.


πŸ“ Project Structure

customer_support_env/
β”œβ”€β”€ models.py              # Pydantic models: SupportAction, SupportObservation, SupportState
β”œβ”€β”€ client.py              # OpenEnv typed client library
β”œβ”€β”€ openenv.yaml           # OpenEnv metadata manifest
β”œβ”€β”€ requirements.txt       # Python dependencies (groq, fastapi, uvicorn…)
β”œβ”€β”€ run_baseline.py        # llama-3.1-8b-instant baseline evaluation script
β”œβ”€β”€ README.md              # This file
β”œβ”€β”€ Dockerfile             # Container config for Hugging Face Spaces
β”œβ”€β”€ .dockerignore          # Excludes venv, __pycache__, .env from image
β”œβ”€β”€ baseline_scores.json   # Auto-generated baseline results
└── server/
    β”œβ”€β”€ __init__.py        # Package marker
    β”œβ”€β”€ app.py             # FastAPI server β€” all 7 endpoints
    └── environment.py     # Core env: 15 scenarios, 3 graders, reward logic

πŸ—οΈ Architecture

models.py                  ← Pydantic contracts (Action / Observation / State)
    β”‚
    β”œβ”€β”€ server/environment.py   ← Episode logic, 15 scenarios, 3 graders
    β”‚       β”‚
    β”‚       └── Reward signals: per-turn partial rewards + cumulative score
    β”‚
    └── server/app.py           ← FastAPI: /reset /step /state /tasks /grader /baseline
            β”‚
            └── client.py       ← Typed client for external scripts

πŸ“œ License

MIT β€” see LICENSE.


Built for the OpenEnv Hackathon πŸš€  |  Customer support AI benchmark that fills a real gap.