# ZeroClaw Agent-Architektur — Referenzdokumentation Dieses Dokument beschreibt die vollstaendige Architektur des Compliance-Agenten, damit sie als Blaupause fuer weitere Agenten (z.B. Sales, HR, Finance) genutzt werden kann. --- ## 1. Ueberblick ``` ┌─────────────────────────────────────────────────────────────────┐ │ FRONTEND (Next.js) │ │ admin-compliance/app/sdk/agent/page.tsx │ │ 5 Tabs: Quick | Scan | Cookie-Test | Vergleich | Login-Test │ │ │ │ Proxy-Routes: /api/sdk/v1/agent/* │ │ → leiten an Backend weiter (vermeidet SSL-Cert-Probleme) │ └──────────────────────┬──────────────────────────────────────────┘ │ POST /api/sdk/v1/agent/{mode} ▼ ┌─────────────────────────────────────────────────────────────────┐ │ BACKEND (Python/FastAPI) │ │ backend-compliance:8002 │ │ │ │ Orchestriert den gesamten Flow: │ │ 1. Ruft Playwright-Service fuer Website-Crawling │ │ 2. Erkennt Services via Regex (82+ Patterns) │ │ 3. Ruft LLM fuer Klassifikation/Korrekturen │ │ 4. Prueft Pflichtfelder (Art. 13, §355, §305ff) │ │ 5. Sendet E-Mail-Report │ │ │ │ Routes: │ │ - agent_analyze_routes.py (Schnellanalyse) │ │ - agent_scan_routes.py (Website-Scan + DSI Discovery) │ │ - agent_compare_routes.py (Multi-Website-Vergleich) │ │ - agent_notification_routes.py (E-Mail) │ │ - agent_history_routes.py (Scan-Verlauf + PDF) │ └──────────┬──────────────────────┬───────────────────────────────┘ │ │ ▼ ▼ ┌─────────────────────┐ ┌──────────────────────────────────────┐ │ OLLAMA (LLM) │ │ CONSENT-TESTER (Playwright) │ │ Mac Mini lokal │ │ consent-tester:8094 │ │ │ │ │ │ Qwen 3.5:35b-a3b │ │ Headless Chromium Browser: │ │ Port: 11434 │ │ - /scan (3-Phasen Cookie-Test) │ │ │ │ - /website-scan (JS-Rendering) │ │ Endpunkte: │ │ - /dsi-discovery (Dokumentensuche) │ │ /api/chat │ │ - /authenticated-scan (Login-Test) │ │ /api/generate │ │ │ │ /api/embeddings │ │ 20 Banner-Checks (rechtlich) │ └─────────────────────┘ └──────────────────────────────────────┘ ``` --- ## 2. Request-Flow (am Beispiel Website-Scan) ``` User klickt "Scan starten" im Frontend │ ▼ POST /api/sdk/v1/agent/scan { url, mode, recipient } │ ├── Next.js API Route (Proxy) │ admin-compliance/app/api/sdk/v1/agent/scan/route.ts │ → Leitet an backend-compliance:8002 weiter │ → Timeout: 5 Minuten │ ▼ Backend: agent_scan_routes.py :: scan_website_endpoint() │ ├── Schritt 1: Playwright Website-Scan │ POST http://consent-tester:8094/website-scan │ → Chromium oeffnet URL, rendert JavaScript │ → Klickt Navigations-Menues, entdeckt Unterseiten │ → Gibt HTML aller Seiten zurueck (max 50 Seiten, 3 Min Timeout) │ ├── Schritt 1b: DSI Document Discovery │ POST http://consent-tester:8094/dsi-discovery │ → Findet alle rechtlichen Dokumente (DSI, AGB, Widerruf, Cookie) │ → Oeffnet Accordions, Tabs, Sidebars │ → Folgt Cross-Domain-Links (z.B. help.instagram.com) │ → Extrahiert Text aus jedem Dokument │ → Backend prueft Vollstaendigkeit (Art. 13 Checkliste) │ ├── Schritt 2: Service-Erkennung (deterministisch, kein LLM) │ service_registry.py: 82+ Regex-Patterns gegen HTML │ → Google Analytics, Facebook Pixel, Stripe, Hotjar, etc. │ → Jeder Service hat: Kategorie, Anbieter, Land, Rechtsgrundlage │ ├── Schritt 3: DSE-Extraktion (LLM) │ POST http://ollama:11434/api/generate │ Prompt: "Extrahiere alle erwahnten Dienste aus dieser DSE..." │ → Qwen 3.5 liest den DSE-Text und gibt JSON zurueck │ → Fallback: Regex-Suche wenn LLM fehlschlaegt │ ├── Schritt 4: SOLL/IST-Vergleich │ SOLL = Services aus DSE (was dokumentiert ist) │ IST = Services auf Website (was tatsaechlich laeuft) │ → "undocumented": auf Website, nicht in DSE (Verstoss!) │ → "documented": beides OK │ → "outdated": in DSE, nicht mehr auf Website │ ├── Schritt 5: Pflichtfeld-Pruefung │ mandatory_content_checker.py: 9 Art. 13 DSGVO Felder │ legal_basis_validator.py: Rechtsgrundlage korrekt? │ dsi_document_checker.py: Jedes gefundene Dokument pruefen │ ├── Schritt 6: Korrekturen generieren (LLM, nur bei Findings) │ POST http://ollama:11434/api/generate │ Prompt: "Erstelle DSE-Textbaustein fuer Google Analytics..." │ → Qwen 3.5 generiert einbaufertigen Text │ ├── Schritt 7: E-Mail senden │ smtp_sender.py → Mailpit (SMTP :1025) │ HTML-Report mit allen Findings + Korrekturen │ └── Response zurueck an Frontend ScanResponse { pages_scanned, services[], findings[], discovered_documents[], summary } ``` --- ## 3. Komponenten im Detail ### 3.1 Frontend (Next.js) **Seite:** `admin-compliance/app/sdk/agent/page.tsx` **Hooks:** `admin-compliance/app/sdk/agent/_hooks/` **Komponenten:** `admin-compliance/app/sdk/agent/_components/` | Komponente | Aufgabe | |---|---| | ScanResult.tsx | Service-Tabelle, Findings, PDF-Download | | ConsentTestResult.tsx | 3-Phasen-Anzeige + Banner-Checks | | CompareResult.tsx | Side-by-Side Vergleich | | AuthTestResult.tsx | 5 Login-Checks | | TextReference.tsx | Originaltext + Korrekturvorschlag | | FollowUpQuestions.tsx | Ja/Nein Fragen | **Proxy-Pattern:** Jeder API-Call geht ueber eine Next.js API Route (`app/api/sdk/v1/agent/*/route.ts`) die serverseitig an das Backend weiterleitet. Das vermeidet CORS- und SSL-Probleme. ### 3.2 Backend (Python/FastAPI) **Service:** `backend-compliance:8002` **Prefix:** `/api/compliance/agent/` | Route-Datei | Endpunkt | Aufgabe | |---|---|---| | agent_analyze_routes.py | POST /analyze | Schnellanalyse (1 URL) | | agent_scan_routes.py | POST /scan | Deep Scan + DSI Discovery | | agent_compare_routes.py | POST /compare | Multi-URL Vergleich | | agent_notification_routes.py | POST /notify | E-Mail senden | | agent_history_routes.py | GET/POST /scans | Scan-Verlauf | | agent_recurring_routes.py | */monitored-urls | Wiederkehrende Scans | **Wichtiges Design-Prinzip:** Das Backend orchestriert, macht aber keine Browser-Operationen. Alles was einen Browser braucht → consent-tester. ### 3.3 Consent-Tester (Playwright/FastAPI) **Service:** `consent-tester:8094` **Dockerfile:** Chromium als appuser installiert (Permission-Fix) | Endpunkt | Aufgabe | Dateien | |---|---|---| | POST /scan | 3-Phasen Cookie-Test | consent_scanner.py, banner_text_checker.py, banner_advanced_checks.py | | POST /website-scan | JS-gerendertes Crawling | playwright_scanner.py | | POST /dsi-discovery | Dokumenten-Suche | dsi_discovery.py | | POST /authenticated-scan | Login + Rechte-Check | authenticated_scanner.py | | GET /health | Healthcheck | main.py | **20 Banner-Checks** in 3 Dateien: - banner_text_checker.py (Checks 1-11) - banner_advanced_checks.py (Checks 12-20) ### 3.4 LLM (Ollama) **Modell:** Qwen 3.5:35b-a3b (23.9 GB, lokal auf Mac Mini) **Port:** 11434 (erreichbar als `host.docker.internal:11434`) **Zwei Aufruf-Patterns:** ```python # Pattern 1: /api/generate (einfache Completion) resp = await client.post(f"{OLLAMA_URL}/api/generate", json={ "model": "qwen3.5:35b-a3b", "prompt": "Erstelle einen DSE-Textbaustein...", "stream": False, }) text = resp.json()["response"] # Pattern 2: /api/chat (Chat mit System-Prompt) resp = await client.post(f"{OLLAMA_URL}/api/chat", json={ "model": "qwen3.5:35b-a3b", "messages": [ {"role": "system", "content": "Du bist ein DSGVO-Experte..."}, {"role": "user", "content": prompt}, ], "stream": False, "format": "json", # Erzwingt JSON-Ausgabe }) text = resp.json()["message"]["content"] ``` **Think-Mode beachten:** Qwen 3.5 gibt `...` Tags aus. Diese muessen aus der Antwort entfernt werden: ```python raw = re.sub(r".*?", "", raw, flags=re.DOTALL).strip() ``` ### 3.5 Soul Files (Agent-Persoenlichkeiten) **Pfad:** `admin-compliance/agent-core/soul/` | Datei | Agent | Aufgabe | |---|---|---| | compliance-advisor.soul.md | Compliance Advisor | Rechtsfragen beantworten (RAG) | | drafting-agent.soul.md | Drafting Agent | DSGVO-Dokumente generieren | **Aufbau einer Soul-Datei:** 1. Identitaet (Wer bin ich?) 2. Kompetenzbereich (Was kann ich?) 3. RAG-Nutzung (Welche Quellen?) 4. Kommunikationsstil (Wie antworte ich?) 5. Einschraenkungen (Was darf ich nicht?) 6. Produktwissen (Features des Tools) 7. FAQ (Haeufige Fragen + Antworten) 8. Eskalation (Wann verweise ich weiter?) --- ## 4. Blaupause: Neuen Agenten erstellen ### Schritt 1: Soul-Datei erstellen ```markdown # Mein Agent ## Identitaet Du bist der [Name]-Agent. Du hilfst bei [Aufgabe]. ## Kompetenzbereich - [Thema 1] - [Thema 2] ## Kommunikationsstil - Sachlich, verstaendlich - Quellenangaben ## Einschraenkungen - Keine [X]-Beratung ``` ### Schritt 2: Backend-Route erstellen ```python # backend-compliance/compliance/api/mein_agent_routes.py from fastapi import APIRouter router = APIRouter(prefix="/compliance/mein-agent", tags=["mein-agent"]) @router.post("/analyze") async def analyze(req: AnalyzeRequest): # 1. Daten holen (Playwright, API, DB) # 2. LLM aufrufen (Ollama) # 3. Ergebnis aufbereiten # 4. E-Mail senden return result ``` ### Schritt 3: Frontend-Page erstellen ``` admin-compliance/app/sdk/mein-agent/ ├── page.tsx # Hauptseite mit Tabs ├── _hooks/ # State + API-Calls └── _components/ # Ergebnis-Anzeige ``` ### Schritt 4: Next.js Proxy-Route ```typescript // admin-compliance/app/api/sdk/v1/mein-agent/[[...path]]/route.ts const BACKEND_URL = 'http://backend-compliance:8002' export async function POST(req, { params }) { const path = (await params).path?.join('/') || '' const resp = await fetch(`${BACKEND_URL}/api/compliance/mein-agent/${path}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: await req.text(), }) return NextResponse.json(await resp.json()) } ``` ### Schritt 5: In docker-compose.yml registrieren Der Agent laeuft als Teil des Backend-Services (kein eigener Container noetig, es sei denn er braucht Playwright — dann eigenen Service wie consent-tester). --- ## 5. Timeouts | Komponente | Timeout | Grund | |---|---|---| | Frontend → Backend Proxy | 300s (5 Min) | Scan kann lange dauern | | Backend → Playwright | 180s (3 Min) | Browser-Rendering + Crawling | | Backend → Ollama LLM | 180s (3 Min) | Grosse Modelle sind langsam | | Playwright → Website | 20s pro Seite | Einzelne Seite laden | | Exhaustive Crawl | 180-300s | Safety-Limit fuer rekursives Crawling | --- ## 6. Environment-Variablen | Variable | Default | Beschreibung | |---|---|---| | OLLAMA_URL | http://host.docker.internal:11434 | Ollama LLM Endpunkt | | OLLAMA_MODEL | qwen3.5:35b-a3b | Standard-Modell | | BACKEND_URL | http://backend-compliance:8002 | Backend API | | CONSENT_SERVICE_URL | http://consent-tester:8094 | Playwright-Service | | RAG_SERVICE_URL | http://rag-service:8097 | RAG/Embedding Service | | QDRANT_URL | https://qdrant-dev.breakpilot.ai | Vektor-Datenbank | | SMTP_HOST | mailpit | E-Mail Server | | SMTP_PORT | 1025 | SMTP Port | --- ## 7. Dateien (Referenz) ### Backend | Datei | LOC | Aufgabe | |---|---|---| | agent_scan_routes.py | 448 | Scan-Orchestrierung | | agent_scan_helpers.py | 109 | Summary + Korrekturen | | agent_analyze_routes.py | 309 | Schnellanalyse | | agent_compare_routes.py | 94 | Multi-Vergleich | | agent_notification_routes.py | 111 | E-Mail | | service_registry.py | 508 | 82+ Service-Patterns | | dsi_document_checker.py | 229 | Dokument-Checklisten | | mandatory_content_checker.py | 274 | Art. 13 Pflichtfelder | | legal_basis_validator.py | 155 | Rechtsgrundlagen | ### Consent-Tester | Datei | LOC | Aufgabe | |---|---|---| | main.py | 321 | FastAPI + Endpunkte | | consent_scanner.py | 213 | 3-Phasen-Test | | banner_text_checker.py | 407 | Banner-Checks 1-11 | | banner_advanced_checks.py | 396 | Banner-Checks 12-20 | | dsi_discovery.py | 488 | Dokumenten-Suche | | playwright_scanner.py | 266 | Website-Crawling | | authenticated_scanner.py | 230 | Login-Tests | ### Frontend | Datei | LOC | Aufgabe | |---|---|---| | agent/page.tsx | 207 | 5-Tab Agent UI | | ScanResult.tsx | 241 | Scan-Ergebnis | | ConsentTestResult.tsx | 207 | Cookie-Test-Ergebnis | | TextReference.tsx | 108 | Korrekturvorschlaege |