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

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