--- title: Customer Support OpenEnv emoji: π½ colorFrom: blue colorTo: green sdk: docker pinned: false --- # π§ Customer Support OpenEnv [](https://www.python.org/) [](https://github.com/openenv) [](https://huggingface.co/spaces) [](https://fastapi.tiangolo.com/) [](LICENSE) > **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 ```bash git clone https://huggingface.co/spaces/sanathkumarps/customer_support_env cd customer_support_env ``` ### 2. Install ```bash pip install -r requirements.txt ``` ### 3. Run locally ```bash 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 ```bash docker build -t customer_support_env . docker run -p 7860:7860 customer_support_env ``` ### 5. Run the baseline evaluation ```bash 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 ```bash # 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](LICENSE). ---
Built for the OpenEnv Hackathon π | Customer support AI benchmark that fills a real gap.