| title | DamageClaims |
|---|---|
| emoji | π |
| colorFrom | indigo |
| colorTo | gray |
| sdk | docker |
| app_port | 8000 |
| pinned | false |
| short_description | DamageClaims is a real-world OpenEnv environment |
Automated freight insurance adjudication via reinforcement learning.
DamageClaims is a production-ready OpenEnv environment that models the end-to-end claims investigation workflow used by freight insurance adjusters. An LLM agent gathers evidence documents, reasons over multi-party liability, detects fraud, and submits a structured payout decision β all within a strict turn budget.
This is not a toy benchmark. It models operational constraints from real logistics and insurance workflows.
Freight damage claims are expensive to process manually. A single adjuster must:
- Collect and cross-reference 5β10 documents per claim (bills of lading, inspection reports, delivery receipts, photos)
- Attribute liability across three parties β carrier, warehouse, and shipper β whose responsibilities overlap
- Calculate accurate payouts against declared and verified cargo values
- Flag inflated or fraudulent claims before issuing payment
At scale, this process is slow, inconsistent, and error-prone. DamageClaims trains an agent to handle this automatically β making grounded, auditable decisions from evidence under time pressure.
flowchart TD
A[LLM Agent] -->|Builds prompt from observation| B[inference.py]
B -->|Parses JSON action| C[DamageClaimsEnv Client]
C -->|HTTP POST /reset, /step| D[FastAPI Server]
D --> E[DamageClaimsEnvironment]
E -->|Loads task config| F[data/tasks.json]
E -->|Scores decision| G[Deterministic Grader]
G -->|approval + liability + payout + efficiency - doc_penalty| E
E -->|DamageClaimsObservation| D
D -->|observation, reward, done| C
C --> B
B -->|START, STEP, END logs| H[stdout / CI pipeline]
sequenceDiagram
participant Agent
participant Client as EnvClient
participant Server as FastAPI
participant Env as DamageClaimsEnvironment
Agent->>Client: reset(task_id)
Client->>Server: POST /reset
Server->>Env: reset()
Env-->>Client: DamageClaimsObservation (turn=0, done=False)
loop Max 8 turns
Agent->>Client: step(action)
Client->>Server: POST /step
Server->>Env: step(action)
Env->>Env: apply action + grade + reward
Env-->>Client: observation, reward, done
Client-->>Agent: updated state
end
Note over Agent,Env: submit_decision triggers grader and ends episode
| Task | Difficulty | Claim ID | Scenario | Ground Truth |
|---|---|---|---|---|
simple_carrier_fault |
Easy | CLM-001 | 3 laptops with cracked screens damaged in transit | 100% carrier liability |
split_liability |
Medium | CLM-002 | Pharma cold-chain breach during shipping and storage | 60% carrier / 40% warehouse |
fraud_detection |
Hard | CLM-003 | Luxury watch shipment with inflated declared value and partial theft | Partial approval, reduced payout |
All tasks are deterministic. Each specifies available_documents, critical_documents, ground_truth targets, and question_hints.
The grader computes a single score in [0.0, 1.0] from five components:
score = approval_score + liability_score + payout_score + efficiency_bonus - doc_penalty
| Component | Weight | Condition |
|---|---|---|
| Approval correct | +0.40 | approved matches ground truth |
| Liability per party (Γγ°γ€3) | +0.10 each | Within 15 percentage points of ground truth |
| Payout accuracy | +0.20 | Relative error β€ 10% of ground-truth payout |
| Efficiency bonus | up to +0.10 | (MAX_TURNS - turns_used) / (MAX_TURNS - 1) |
| Document penalty | β0.20 Γγ°γ€ (missing / total) | Proportional to critical documents not collected |
{
"critical_docs_collected": 2,
"critical_docs_required": 3,
"turns_remaining": 4
}{
"approval": 0.4,
"liability": 0.3,
"payout": 0.2,
"efficiency": 0.071,
"doc_penalty": -0.0
}| Action | Reward |
|---|---|
| Valid document requested | +0.05 |
| Document not in available list | β0.05 |
| Question asked | +0.02 |
submit_decision (terminal) |
grade() output |
| Max turns reached without submit | 0.0 |
Actions use the DamageClaimsAction model:
| Field | Type | Notes |
|---|---|---|
action_type |
enum | request_document, ask_question, submit_decision |
document_name |
string or null | Required for request_document |
question |
string or null | Required for ask_question |
decision |
ClaimDecision or null |
Required for submit_decision |
ClaimDecision fields:
| Field | Type | Constraint |
|---|---|---|
approved |
bool | Approve or reject claim |
payout_usd |
float | Dollar amount |
carrier_liability_pct |
float | Must sum to 100 (Β±1.0) with others |
warehouse_liability_pct |
float | β |
shipper_liability_pct |
float | β |
.
βββ inference.py # Agent driver: prompt loop, logging, fallback decisions
βββ client.py # DamageClaimsEnv HTTP client
βββ models.py # Pydantic action and observation models
βββ openenv.yaml # OpenEnv spec
βββ pyproject.toml
βββ data/
β βββ tasks.json # Task definitions, ground truth, document library
βββ assets/
β βββ banner.png
β βββ logo.png
βββ scripts/
β βββ validate-submission.sh
βββ server/
βββ app.py # FastAPI endpoints: /reset /step /state /health
βββ damageClaims_environment.py # Core environment + grader
βββ Dockerfile
βββ requirements.txt
- Python 3.10+
uvor standardpip
| Local Dev | Docker |
|---|---|
python -m venv .venv |
docker build -t damageclaims-env:latest . |
source .venv/bin/activate |
docker run --rm -p 8000:8000 damageclaims-env:latest |
pip install -e . |
curl http://127.0.0.1:8000/health |
uvicorn server.app:app --host 0.0.0.0 --port 8000 |
β |
uv run python inference.py |
β |
Copy .env.example and fill in your credentials:
cp .env.example .env
API_BASE_URL=https://api.groq.com/openai/v1 MODEL_NAME=llama-3.3-70b-versatile HF_TOKEN=your_api_key_here
API_KEY is accepted as a fallback if HF_TOKEN is not set.
curl -sS -X POST http://127.0.0.1:8000/reset \ -H "Content-Type: application/json" \ -d '{"task_id": "simple_carrier_fault"}'
uv run python inference.py
Expected output format:
[START] task=simple_carrier_fault env=damageClaims model=llama-3.3-70b-versatile
[STEP] step=1 action=request_document reward=0.05 done=false error=null
[STEP] step=2 action=request_document reward=0.05 done=false error=null
[STEP] step=3 action=submit_decision reward=0.53 done=true error=null
[END] success=true steps=3 score=0.525 rewards=0.05,0.05,0.53
--- simple_carrier_fault: score=0.525 ---
=== AVERAGE SCORE: 0.500 ===
.venv/bin/openenv validate
- Create a Docker SDK Space.
- Set Space secrets:
API_BASE_URL,MODEL_NAME,HF_TOKEN. - Expose port
8000. - Run the submission validator after deploy:
bash scripts/validate-submission.sh https://<space_name>-<user_name>.hf.space .
The validator checks three things in order:
- HF Space live β POST
/resetreturns HTTP 200 - Docker build β
docker buildcompletes within 600 seconds - OpenEnv validate β
openenv validatepasses in the repo directory
| Item | Status |
|---|---|
HF Space responds to /reset |
Implemented |
openenv.yaml at repo root, spec-compliant |
Implemented |
| Docker builds with health check | Implemented |
inference.py reproduces baseline at temperature=0.1 |
Implemented |
| 3 tasks (easy / medium / hard) with deterministic graders | Implemented |
Scores clamped to [0.0, 1.0] |
Implemented |
| Partial progress signal in every observation | Implemented |
reset() / step() / state() interface satisfied |
Implemented |
| Symptom | Fix |
|---|---|
openenv validate fails |
Confirm openenv.yaml is at repo root and app: server.app:app is importable |
| Auth error during inference | Verify HF_TOKEN or API_KEY is set in .env |
| Docker health check fails | docker logs <container_id> β confirm port 8000 is exposed |
KeyError on task_id |
Valid IDs: simple_carrier_fault, split_liability, fraud_detection |
| Liability validation error | Ensure the three liability percentages sum to exactly 100 |
| Network issues in container | Check egress proxy settings; x-deny-reason header indicates block reason |
| Component | Location |
|---|---|
openenv.yaml |
Repo root |
Action model (DamageClaimsAction) |
models.py |
Observation model (DamageClaimsObservation) |
models.py |
API endpoints (/reset, /step, /state, /health) |
server/app.py |
| Environment class | server/damageClaims_environment.py |