AgentArena / FOR_SMLFLG.md
smlflg's picture
Initial public upload from Projekte/AgentArena
3b0d6b3 verified
|
Raw History Blame Contribute Delete
5.78 kB
# AgentArena
## Was ist das?
Benchmark-Plattform zum Vergleich von AI-Agenten auf echten Coding-Tasks.
Agenten loesen Tasks in isolierten Docker-Sandboxes, Ergebnisse landen in einem Leaderboard mit pass@k, Kosten und Geschwindigkeit.
**Alleinstellungsmerkmal:** Explizites Kosten-Tracking ($/Task) β€” kein anderes Benchmark-Tool (SWE-bench, Inspect AI, AgentBench, Aider) trackt das.
## Architektur & Tech-Stack
```
Browser (htmx + Tailwind)
β”‚
FastAPI (main.py :8420) ←→ SQLite (database.py)
β”‚
β”œβ”€β”€ Routes: /, /tasks/:slug, /runs/:id
β”œβ”€β”€ API: POST /api/runs, POST /api/tasks/import, GET /api/leaderboard
└── SSE: GET /api/runs/:id/stream
β”‚
core/runner.py (Orchestrierung)
β”‚
β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ β”‚
Container A Container B
(Agent Sandbox) (Judge Sandbox)
β”‚ β”‚
Adapter (Host) judge.py
β”œβ”€β”€ claude_code β”œβ”€β”€ Functional (50%)
β”œβ”€β”€ aider β”œβ”€β”€ Regression (20%)
└── codex β”œβ”€β”€ Lint (15%)
└── Complexity (15%)
```
### 2-Container Judge Isolation (Sicherheitsmodell)
```
Container A (Agent): Container B (Judge):
1. Clone repo 1. Frischer Clone (clean)
2. Agent arbeitet (Host CLI) 2. git apply agent.patch
3. Produziert Diff 3. pytest + ruff + radon
4. Wird ZERSTOERT 4. Score berechnen
5. Wird ZERSTOERT
```
Agent kann Judge NICHT manipulieren β€” separate Container, kein shared state.
| Schicht | Tech |
|---------|------|
| Backend | FastAPI + SQLAlchemy + SQLite |
| Frontend | Jinja2 + htmx + Tailwind CSS |
| Adapters | claude_code, aider, codex (alle Host-basiert) |
| Evaluation | judge.py (4 Dimensionen) + metrics.py (composite) |
| Sandbox | Docker containers (python:3.12-slim) |
| Netzwerk | arena-net (Docker network) |
**Modelle:** Task (slug, repo_url, success_cmd, time_limit_s), Agent (name, adapter_type), Run (status, tokens, cost_usd, tests_passed, judge_score, pass_at_k_group, metrics_json, trajectory, diff_text)
## Starten / Nutzen
```bash
cd ~/Projekte/AgentArena
source .venv/bin/activate
docker network create arena-net 2>/dev/null || true
uvicorn main:app --reload --port 8420
# Task importieren
curl -X POST http://localhost:8420/api/tasks/import \
-H "Content-Type: application/x-yaml" \
--data-binary @tasks/fix_off_by_one.yaml
# Run starten (Claude Code)
curl -X POST http://localhost:8420/api/runs \
-H "Content-Type: application/json" \
-d '{"task_slug":"fix-off-by-one","agent_name":"claude-sonnet","adapter_type":"claude_code"}'
# Run starten (Aider + MiniMax)
curl -X POST http://localhost:8420/api/runs \
-H "Content-Type: application/json" \
-d '{"task_slug":"fix-off-by-one","agent_name":"aider-minimax","adapter_type":"aider"}'
# Leaderboard
curl http://localhost:8420/api/leaderboard | python -m json.tool
```
## Adapter-Setup
| Adapter | CLI | Auth | Status |
|---------|-----|------|--------|
| Claude Code | `claude --print --dangerously-skip-permissions` | OAuth (kein Key noetig) | Getestet, score=0.80 |
| Aider | `aider --yes-always --model openai/MiniMax-M2.5` | MINIMAX_API_KEY in ~/.claude/.env | Getestet, score=1.0 |
| Codex | `codex --quiet --full-auto` | OPENAI_API_KEY | Noch nicht getestet |
Alle Adapter laufen auf dem **Host** (nicht im Docker-Container), klonen das Repo in ein Temp-Dir, und liefern den Diff zurueck.
## Was funktioniert (Stand 2026-03-08)
- **2 Adapter getestet:** Claude Code (score=0.80) + Aider/MiniMax (score=1.0)
- **Judge Isolation:** 2-Container-Modell (Agent + Judge getrennt)
- **4-Dimensionen Judge:** Functional, Regression, Lint, Complexity
- **Regression Crash Detection:** Unterscheidet pytest-Crashes von echten Testfehlern
- **Git Stash Check:** Lint/Complexity vergleicht before/after korrekt
- **Container Leak Prevention:** try/except mit destroy() in Sandbox.create()
- **Zombie Run Sweep:** Markiert pending/running Runs als error bei Server-Neustart
- **Race-safe Agent Creation:** IntegrityError + rollback + re-query
- **Pass@k:** Unbiased Estimator, parallele Runs mit eigener DB-Session
- **Leaderboard:** pass@1, pass@3, avg_cost, avg_duration, composite_score
- **3 Tasks:** fix-off-by-one, add-input-validation, refactor-extract-function
- **Task-Repos:** /tmp/arena-tasks/ (3 Mini-Repos mit Bugs + Tests)
- **SSE Streaming:** Live-Updates laufender Runs
- **Diff-Viewer:** Farbige +/- Zeilen in Run-Detail
## Was fehlt / Next Steps
1. **Codex Adapter testen** β€” braucht OPENAI_API_KEY
2. **Patch-Apply Bug** β€” Run #9 zeigt "Patch failed to apply" (untersuchen)
3. **Confidence Intervals** β€” Score ohne Varianz ist schwach
4. **LLM Judge** β€” qualitative Bewertung via Gemini Flash
5. **Auth / API Keys** β€” fuer Multi-User
6. **GitHub-Polish** β€” README aufhuebschen, Screenshots
## Entscheidungen & Lessons Learned
- **2-Container-Modell:** Agent kann Judge nicht manipulieren β€” kritisch fuer faire Bewertung
- **Host-basierte Adapter:** Claude CLI + Aider laufen auf Host, nicht im Container (CLIs nicht im Docker verfuegbar)
- **MiniMax als guenstigster Agent:** ~$0.05/1M Tokens vs Claude ~$3/1M β€” perfekt fuer viele Runs
- **pass_at_k_group als String:** Flexible Gruppierung ohne extra Tabelle
- **SSE statt WebSocket:** Einfacher, reicht fuer diesen Use-Case
- **SQLite reicht:** Migration zu Postgres offen, aber nicht noetig
- **Cross-Model-Review lohnt sich:** MiniMax + Codex haben 13 Findings geliefert, 5 Quick Wins sofort gefixt
- **Regression Guard:** pytest "1 error in 0.12s" (Crash) β‰  "3 failed" (echte Fehler) β€” Regex + has_real_tests Check