CoolFace
Apppublic

Anicher/email_triage

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

πŸ“§ Email Triage OpenEnv

A real-world email triage and prioritization environment for training and evaluating AI agents. Agents must process an inbox of emails β€” classifying urgency, routing to departments, drafting replies, flagging escalations, and archiving spam.

Why Email Triage?

Knowledge workers spend 2–3 hours per day on email. This is one of the most common, highest-value tasks for LLM agents to assist with β€” yet no standardized benchmark exists. This environment fills that gap.


Environment Description

The agent receives an inbox of realistic business emails spanning:

  • β€”Security incidents and production outages
  • β€”Customer support requests and complaints
  • β€”Sales inquiries and contract negotiations
  • β€”HR matters (leave, reviews, complaints)
  • β€”Legal and billing urgencies
  • β€”Spam and low-priority marketing

The agent must take structured actions on each email to process the inbox effectively.


Action Space

Each action targets one email and specifies one operation:

FieldValuesDescription
email_idstringTarget email
action_typeclassify, route, reply, archive, escalate, skipOperation to perform
urgencyurgent, normal, low(classify only)
categorysupport, sales, internal, spam, billing, technical, hr, legal(classify only)
departmentsupport, sales, engineering, hr, legal, finance, management(route only)
reply_textstring (1-3 sentences)Draft reply (reply only)
escalate_reasonstringReason for escalation (escalate only)

Observation Space

json
{
  "inbox": [{"id", "subject", "sender", "body", "timestamp", "thread_id"}],
  "processed": ["e001", "e003", ...],
  "step_count": 5,
  "task_id": "task_easy",
  "score_so_far": 0.45,
  "message": "Classification: urgency=1.0, category=0.5"
}

Tasks

Task 1 β€” Email Classification (Easy)

  • β€”Emails: 10
  • β€”Max steps: 30
  • β€”Goal: Classify each email by urgency (urgent/normal/low) and category
  • β€”Score: Mean of per-email classification accuracy
  • β€”Expected difficulty: Frontier models ~0.80+, smaller models ~0.50-0.65

Task 2 β€” Email Routing & Reply Drafting (Medium)

  • β€”Emails: 15
  • β€”Max steps: 60
  • β€”Goal: Route emails to the correct department AND draft replies for actionable emails
  • β€”Score: 40% routing + 40% reply quality + 20% coverage
  • β€”Expected difficulty: Frontier models ~0.65-0.75, smaller models ~0.40-0.55

Task 3 β€” Inbox Zero Sprint (Hard)

  • β€”Emails: 20
  • β€”Max steps: 100
  • β€”Goal: Full pipeline β€” classify, route, reply, escalate, archive spam
  • β€”Score: 25% classify + 25% routing + 25% reply + 15% escalation + 10% spam handling
  • β€”Expected difficulty: Frontier models ~0.55-0.70, smaller models ~0.30-0.45

Reward Function

The environment provides dense reward signals β€” not just end-of-episode scores:

  • β€”Correct classification: +1/n_emails Γ— (0.5Γ—urgency + 0.5Γ—category)
  • β€”Correct routing: +1/n_emails Γ— department_match
  • β€”Quality reply: +1/n_emails Γ— keyword_overlap_score
  • β€”Archive spam/low-priority: +0.8/n_emails
  • β€”Correct escalation: +1/n_emails
  • β€”Archive urgent email: -0.5/n_emails ← penalty
  • β€”Reply to spam: -0.3/n_emails ← penalty
  • β€”False escalation: -0.3/n_emails ← penalty
  • β€”Invalid action: -0.05

API

Reset

bash
POST /reset
{"task_id": "task_easy", "session_id": "my_session"}

Step

bash
POST /step
{
  "session_id": "my_session",
  "action": {
    "email_id": "e001",
    "action_type": "classify",
    "urgency": "urgent",
    "category": "technical"
  }
}

State

bash
GET /state?session_id=my_session

Final Score

bash
GET /score?session_id=my_session

Setup & Usage

Local (Docker)

bash
docker build -t email-triage-env .
docker run -p 7860:7860 email-triage-env

Local (Python)

bash
pip install -r requirements.txt
python main.py

Inference

bash
export HF_TOKEN=your_key
export API_BASE_URL=https://router.huggingface.co/v1
export MODEL_NAME=Qwen/Qwen2.5-72B-Instruct
export ENV_BASE_URL=http://localhost:7860

python inference.py

Baseline Scores

Measured with Qwen/Qwen2.5-72B-Instruct via HuggingFace Inference API:

TaskScoreNotes
task_easy (Classification)~0.72Strong on urgency, weaker on category edge cases
task_medium (Routing+Reply)~0.58Routing generally good, reply quality variable
task_hard (Inbox Zero)~0.49Full pipeline stress-tests multi-step planning
Average~0.60

Project Structure

email-triage-env/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ email_data.py      # 20 emails with ground-truth labels
β”‚   β”œβ”€β”€ environment.py     # EmailTriageEnv (step/reset/state)
β”‚   β”œβ”€β”€ graders.py         # Per-task scoring functions
β”‚   β”œβ”€β”€ models.py          # Pydantic typed models
β”‚   └── server.py          # FastAPI server
β”œβ”€β”€ tests/
β”‚   └── test_environment.py
β”œβ”€β”€ Dockerfile
β”œβ”€β”€ inference.py           # Baseline agent script
β”œβ”€β”€ main.py
β”œβ”€β”€ openenv.yaml
β”œβ”€β”€ requirements.txt
└── README.md

License

MIT