File size: 8,090 Bytes
23c2821
4bdb808
 
 
 
23c2821
 
4bdb808
 
 
 
23c2821
 
4bdb808
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d6243f2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4bdb808
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
532cd03
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4bdb808
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
---
title: Ad Audit Environment
emoji: πŸ•΅οΈ
colorFrom: red
colorTo: yellow
sdk: docker
pinned: false
app_port: 8000
base_path: /web
tags:
  - openenv
---

# Ad Audit Environment

An RL environment for **detecting advertising fraud** in a simulated 14-day ad campaign. Agents monitor publisher traffic metrics, investigate suspicious patterns, and flag fraudulent publishers while avoiding false positives.

## The Challenge

You manage a digital ad campaign with multiple publishers. Some are legitimate, some are committing fraud. Each day you see traffic metrics and must decide: monitor, investigate, or flag.

**Fraud types:**
- **Bot Traffic** β€” CTR spikes dramatically, CVR drops near zero (bots click but never convert)
- **Click Injection** β€” CVR becomes abnormally high (fake conversions injected)
- **Domain Spoofing** β€” Impressions surge while CVR drops (fake ad inventory)

**The catch:** False positives are heavily penalized, investigations cost budget, and fraudsters adapt when investigated.

## Quick Start

```python
import asyncio
from Ad_Audit import AdAuditAction, AdAuditEnv

async def main():
    env = await AdAuditEnv.from_docker_image("adaudit-env:latest")
    try:
        result = await env.reset(episode_id="medium")
        obs = result.observation
        print(f"Day {obs.day}: {len(obs.daily_metrics)} publishers")

        # Monitor day 1
        result = await env.step(AdAuditAction(action_type="monitor"))

        # Investigate a suspicious publisher
        result = await env.step(AdAuditAction(
            action_type="investigate_publisher",
            publisher_id="pub_003",
            tool="click_timestamps"
        ))

        # Flag fraud with evidence
        result = await env.step(AdAuditAction(
            action_type="flag_fraud",
            publisher_id="pub_003",
            fraud_type="bot_traffic",
            evidence=["click_timestamps", "ip_distribution"]
        ))
        print(f"Reward: {result.reward}")
    finally:
        await env.close()

asyncio.run(main())
```

## Actions

| Action | Description | Cost |
|--------|-------------|------|
| `monitor` | Observe metrics, take no action | Free |
| `investigate_publisher` | Run a tool on one publisher | 1 investigation budget |
| `flag_fraud` | Flag publisher as fraudulent (irreversible) | Free but false positives penalized |
| `submit_report` | End the episode early | Free |

**Investigation tools:** click_timestamps, ip_distribution, device_fingerprints, referral_urls, viewability_scores, conversion_quality

**Fraud types:** bot_traffic, domain_spoofing, click_injection

### Action input format

Each action is a JSON object with the fields below. Only include fields relevant to the chosen `action_type`.

| Field | Type | Used by | Example |
|-------|------|---------|---------|
| `action_type` | string (required) | all | `"monitor"` |
| `publisher_id` | string | investigate, flag | `"pub_001"` |
| `tool` | string | investigate | `"click_timestamps"` |
| `fraud_type` | string | flag | `"bot_traffic"` |
| `evidence` | list of strings | flag | `["click_timestamps", "ip_distribution"]` |
| `summary` | string | submit_report | `"Publisher pub_002 is running bot traffic"` |

**Examples:**

```json
{"action_type": "monitor"}
```

```json
{"action_type": "investigate_publisher", "publisher_id": "pub_001", "tool": "click_timestamps"}
```

```json
{
  "action_type": "flag_fraud",
  "publisher_id": "pub_002",
  "fraud_type": "bot_traffic",
  "evidence": ["click_timestamps", "ip_distribution"]
}
```

```json
{"action_type": "submit_report", "summary": "Flagged pub_002 for bot traffic based on timestamp clustering and IP concentration."}
```

> **Web UI note:** In the web interface, fill in only the fields for your chosen action and leave the rest blank. For the `evidence` field, enter tool names separated by commas (e.g. `click_timestamps, ip_distribution`).

## Observation

Each step returns:
- **daily_metrics** β€” Per-publisher: impressions, clicks, conversions, spend, CTR, CVR
- **investigation_results** β€” Tool output (if investigated)
- **publisher_status** β€” Active or flagged
- **budget_status** β€” Campaign spend and remaining investigation budget

## Tasks

| Task | Publishers | Fraudsters | Investigation Budget | Difficulty |
|------|-----------|------------|---------------------|------------|
| `easy` | 2 | 1 (bot_traffic) | 10 | Obvious signals |
| `medium` | 4 | 2 (bot_traffic + click_injection) | 10 | Mixed fraud types |
| `hard` | 4 | 2 (domain_spoofing + bot_traffic) | 6 | Subtle signals, tight budget |

## Scoring

### Step Reward

Every action returns an immediate reward in **[0, 1]**, centered at 0.5 (neutral).

| Action | Condition | Reward |
|--------|-----------|--------|
| `monitor` | No active fraud | 0.50 |
| `monitor` | Active unflagged fraud | 0.40 β†’ 0.20 (penalty grows day over day) |
| `investigate_publisher` | Publisher is fraudulent | 0.55 β†’ 0.65 (bonus for investigating early) |
| `investigate_publisher` | Publisher is clean | 0.35 (wastes budget) |
| `flag_fraud` | Correct publisher + correct fraud type | 0.95 β†’ 1.00 (bonus for early flag) |
| `flag_fraud` | Correct publisher, wrong fraud type | 0.70 |
| `flag_fraud` | False positive | 0.05 |
| `submit_report` | Any | 0.50 |
| Invalid / malformed action | β€” | 0.05 |

The monitor penalty formula: `0.50 - (0.10 + 0.20 Γ— day/14)`, floored at 0.05. On day 1 the penalty is ~0.10; by day 14 it reaches ~0.30, reflecting increasing urgency as fraud compounds.

### Final Score

Computed at episode end, combining three weighted components into a score in **[0, 1]**:

```
final_score = 0.50 Γ— accuracy + 0.30 Γ— timeliness + 0.20 Γ— efficiency
```

#### 1. Fraud Detection Accuracy (50%)

Measures whether fraudulent publishers were correctly identified with the right fraud type.

- **+1.0 / N** per fraudster flagged with the correct fraud type
- **+0.5 / N** per fraudster flagged with the wrong fraud type
- **βˆ’0.5 / N** per false positive (clean publisher flagged as fraudulent)

Clamped to [0, 1].

#### 2. Detection Timeliness (30%)

Measures how quickly each fraudster was caught after fraud began.

```
timeliness = 1.0 βˆ’ (day_flagged βˆ’ fraud_start_day) / (14 βˆ’ fraud_start_day)
```

- Flagging immediately when fraud starts β†’ 1.0
- Flagging on the final day β†’ 0.0
- Unflagged fraudster β†’ 0.0
- Averaged across all fraudsters.

#### 3. Investigation Efficiency (20%)

Measures whether investigations were targeted at real fraudsters without wasting budget.

```
efficiency = 0.5 Γ— (useful_investigations / total_investigations)
           + 0.3 Γ— (1 βˆ’ budget_used / budget_total)
           βˆ’ 0.2 Γ— num_false_positives
```

- **Information value** β€” fraction of investigations spent on fraudulent publishers
- **Budget efficiency** β€” fraction of budget left unused
- **False positive penalty** β€” βˆ’0.2 per clean publisher incorrectly flagged

Clamped to [0, 1].

## Deployment

```bash
# Build Docker image
docker build -t adaudit-env .

# Run locally
docker run -p 8000:8000 adaudit-env

# Or without Docker
ENABLE_WEB_INTERFACE=true python -m server.app
```

**Endpoints:**
- `/web` β€” Interactive Gradio UI
- `/docs` β€” API documentation
- `/health` β€” Health check
- `/ws` β€” WebSocket for persistent sessions

## Project Structure

```
Ad_Audit/
β”œβ”€β”€ inference.py           # LLM agent + rule-based fallback
β”œβ”€β”€ models.py              # Action / Observation / State models
β”œβ”€β”€ client.py              # WebSocket client (AdAuditEnv)
β”œβ”€β”€ cases/                 # Task definitions (easy/medium/hard)
└── server/
    β”œβ”€β”€ app.py             # FastAPI server
    β”œβ”€β”€ Ad_Audit_environment.py  # Core environment logic
    β”œβ”€β”€ fraud_engine.py    # Suspicion tracking & fraud intensity
    β”œβ”€β”€ publisher_engine.py # Traffic generation
    β”œβ”€β”€ response_generator.py # Investigation tool responses
    β”œβ”€β”€ step_reward.py     # Per-step reward calculator
    └── grader.py          # Episode-end scoring
```