Testapp/docs/architecture.md
Nora 3f5b1a59a5 docs: Agenten-Steckbriefe (Ist-Stand v0.1) + README-Status & Prototyp-Anleitung
- docs/agent_specs.md: implementierte Agenten, Live/Mock-Pfade, Abweichungen vom Ziel-Design
- README: Status-Tabelle aktualisiert, Prototyp-/Test-Befehle ergänzt

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 13:59:29 +00:00

12 KiB

eBay-Auto-Lister — Systemarchitektur

1. Überblick & Ziele

Der eBay-Auto-Lister ist ein Python-basiertes Multi-Agent-System, das den vollständigen Prozess vom Produktfoto bis zur veröffentlichten eBay-Anzeige automatisiert. Durch den Einsatz spezialisierter KI-Agenten in einer koordinierten Pipeline wird jeder Schritt von der Bildanalyse über die Preisrecherche und Listing-Erstellung bis hin zur Chat-Moderation abgedeckt.

Kernziele

  • Vollautomatisierung: Minimaler manueller Aufwand nach dem Upload eines Fotos
  • Qualitätssicherung: Jeder Agent liefert strukturierte, validierbare Outputs
  • Skalierbarkeit: Agenten können unabhängig erweitert oder ersetzt werden
  • Compliance: Einhaltung der eBay-API-Richtlinien und -Nutzungsbedingungen

2. BMAD-Orchestrierungsmodell

Warum Orchestrierung statt monolithisch?

Ein monolithischer Ansatz würde alle Aufgaben (Vision, Preisanalyse, Texterstellung, Moderation) in einem einzigen Prozess vermischen. Das erzeugt:

  • Enge Kopplung: Änderungen an einem Schritt gefährden alle anderen
  • Keine Wiederverwendbarkeit: Einzelschritte können nicht isoliert getestet oder ausgetauscht werden
  • Schwache Fehlerbehandlung: Ein Fehler stoppt die gesamte Pipeline

Das BMAD-Prinzip (Business Method Agent Design) löst dies durch klare Rollenverteilung, definierte Schnittstellen (Contracts) und einen zentralen Orchestrator, der den Zustand hält und die Hand-offs steuert.

Rolle des Orchestrators

Der Orchestrator ist der einzige Teilnehmer, der den vollständigen Session-State kennt. Er:

  1. Nimmt den initialen Job-Request entgegen (Foto-Pfad, Nutzerkonfiguration)
  2. Übergibt Tasks sequenziell an die Fach-Agenten
  3. Validiert den Output jedes Agenten gegen dessen Contract
  4. Schreibt Zwischenergebnisse in das gemeinsame ItemState-Objekt
  5. Behandelt Fehler und entscheidet über Retry oder Abbruch
  6. Startet nach Veröffentlichung den Chat-Moderation-Agenten als parallelen Service

Hand-offs zwischen Agenten

Jeder Hand-off ist ein expliziter Methodenaufruf mit typisiertem Input und Output:

Orchestrator → Bildanalyse-Agent     : ImageAnalysisRequest  → ItemData
Orchestrator → Preis-Recherche-Agent : PriceResearchRequest  → PriceSuggestion
Orchestrator → Listing-Erstellung    : ListingRequest        → Listing
Orchestrator → eBay-API              : Listing               → PublishedListingId
Orchestrator → Chat-Moderation-Agent : ModerationServiceConfig (Fire-and-Forget)

Nachrichten & State

  • ItemState: Zentrales Zustandsobjekt, das der Orchestrator durch die gesamte Pipeline mitführt
  • Messages: Jeder Agenten-Aufruf ist eine strukturierte Nachricht (Dataclass); kein Shared-Memory zwischen Agenten
  • Zustandspersistenz: Nach jedem erfolgreichen Schritt wird der State in eine JSON-Datei geschrieben (Resume-Fähigkeit bei Absturz)

3. Pipeline-Diagramm

flowchart TD
    A([Foto-Upload]) --> B[Orchestrator]

    B -->|ImageAnalysisRequest| C[Bildanalyse-Agent]
    C -->|ItemData| B

    B -->|PriceResearchRequest| D[Preis-Recherche-Agent]
    D -->|PriceSuggestion| B

    B -->|ListingRequest| E[Listing-Erstellung-Agent]
    E -->|Listing| B

    B -->|Listing via eBay-API| F[(eBay Marketplace)]
    F -->|PublishedListingId| B

    B -->|ModerationServiceConfig| G[Chat-Moderation-Agent]
    G <-->|Käufer-Nachrichten| F

    style A fill:#4a9eff,color:#fff
    style B fill:#ff8c42,color:#fff
    style C fill:#6bcb77,color:#fff
    style D fill:#6bcb77,color:#fff
    style E fill:#6bcb77,color:#fff
    style F fill:#c9b8e8,color:#333
    style G fill:#ffd166,color:#333

4. Agent-Steckbriefe

Orchestrator

Eigenschaft Beschreibung
Rolle Zentraler Koordinator der gesamten Pipeline
Verantwortung Job-Verwaltung, State-Management, Fehlerbehandlung, Hand-offs
Inputs Job-Request (Foto-Pfad, Nutzerkonfiguration)
Outputs Finaler ItemState mit published_listing_id
Tools/Modelle Kein KI-Modell; reine Python-Orchestrierungslogik
Fehlerfälle Agent-Timeout → Retry (max. 3x); Contract-Verletzung → Abbruch mit Fehlermeldung; API-Fehler → Exponential Backoff

Bildanalyse-Agent

Eigenschaft Beschreibung
Rolle Extrahiert strukturierte Produktdaten aus Fotos
Verantwortung Objekterkennung, Zustandsbewertung, Kategorie-Klassifikation, Merkmalextraktion
Inputs ImageAnalysisRequest(image_path: str, language: str)
Outputs / Contract ItemData(title: str, category: str, condition: str, features: list[str], brand: str | None, confidence: float)
Tools/Modelle Vision-LLM (z. B. claude-sonnet-4-6 mit Vision); optional lokales CLIP-Modell für Vorklassifikation
Fehlerfälle Bild unlesbar → ImageAnalysisError; confidence < 0.6 → Orchestrator fragt Nutzer zur Verifikation; Kein Objekt erkannt → Abbruch

Preis-Recherche-Agent

Eigenschaft Beschreibung
Rolle Ermittelt marktgerechte Preisempfehlung
Verantwortung Scraping abgeschlossener eBay-Verkäufe, Preisstatistik, Wettbewerbsanalyse
Inputs PriceResearchRequest(item: ItemData, max_results: int = 20)
Outputs / Contract PriceSuggestion(suggested_price: Decimal, price_range: tuple[Decimal, Decimal], avg_sold_price: Decimal, sample_size: int, confidence: float)
Tools/Modelle eBay Finding API (abgeschlossene Listings); Scraper-Fallback für erweiterte Daten; statistisches Modul (src/scrapers/price_analyzer.py)
Fehlerfälle Keine Vergleichsdaten → PriceResearchWarning + Schätzwert; API-Rate-Limit → Warten + Retry; sample_size < 3 → Niedrige Konfidenz wird im Output markiert

Listing-Erstellung-Agent

Eigenschaft Beschreibung
Rolle Generiert verkaufsfördernde eBay-Anzeigentexte
Verantwortung Titel (max. 80 Zeichen), Beschreibungstext, eBay-Kategoriezuordnung, Versandoptionen vorschlagen
Inputs ListingRequest(item: ItemData, price: PriceSuggestion, language: str, seller_config: SellerConfig)
Outputs / Contract Listing(title: str, description: str, category_id: str, price: Decimal, condition_id: str, shipping_options: list[ShippingOption], images: list[str])
Tools/Modelle Text-LLM (claude-sonnet-4-6); eBay-Kategorie-Lookup-Tabelle; Titel-Optimizer mit Keyword-Extraktion
Fehlerfälle Titel > 80 Zeichen → automatisches Kürzen + Log; Ungültige Kategorie-ID → Fallback auf Elternkategorie; LLM-Timeout → Retry mit vereinfachtem Prompt

Chat-Moderation-Agent

Eigenschaft Beschreibung
Rolle Begleitender Service für Käufer-Kommunikation nach Veröffentlichung
Verantwortung Automatische Beantwortung häufiger Fragen, Spam-Filterung, Eskalation komplexer Anfragen
Inputs ModerationServiceConfig(listing_id: str, item: ItemData, auto_reply: bool, escalation_email: str)
Outputs / Contract Feuert Events: MessageReplied, MessageEscalated, SpamDetected
Tools/Modelle Text-LLM (claude-haiku-4-5-20251001 für niedrige Latenz); eBay Messaging API; Spam-Klassifikator
Fehlerfälle Unbekannte Frage + auto_reply=True → Standardantwort + Eskalation; API-Fehler → Silent Retry; Modell-Timeout → Direkte Weiterleitung an Verkäufer

5. Datenmodelle

from dataclasses import dataclass, field
from decimal import Decimal


@dataclass
class ItemData:
    title: str
    category: str
    condition: str                   # "new", "used_good", "used_fair", "defective"
    features: list[str] = field(default_factory=list)
    brand: str | None = None
    confidence: float = 0.0


@dataclass
class PriceSuggestion:
    suggested_price: Decimal
    price_range: tuple[Decimal, Decimal]
    avg_sold_price: Decimal
    sample_size: int
    confidence: float


@dataclass
class ShippingOption:
    service: str
    cost: Decimal
    estimated_days: int


@dataclass
class Listing:
    title: str                       # max. 80 Zeichen
    description: str
    category_id: str
    price: Decimal
    condition_id: str
    shipping_options: list[ShippingOption]
    images: list[str]                # lokale Dateipfade oder URLs
    published_listing_id: str | None = None


@dataclass
class Message:
    listing_id: str
    sender_id: str
    content: str
    timestamp: str                   # ISO 8601
    reply: str | None = None
    escalated: bool = False


@dataclass
class ItemState:
    job_id: str
    image_path: str
    item_data: ItemData | None = None
    price_suggestion: PriceSuggestion | None = None
    listing: Listing | None = None
    published_listing_id: str | None = None
    status: str = "pending"          # pending, analyzing, pricing, listing, publishing, live, error
    error: str | None = None

6. Tech-Stack & Modulstruktur

Tech-Stack

Komponente Technologie
Sprache Python 3.12+
KI-Modelle Anthropic Claude API (claude-sonnet-4-6, claude-haiku-4-5-20251001)
eBay-Integration eBay Trading API, eBay Finding API, eBay Messaging API
HTTP-Client httpx (async)
Validierung pydantic v2
Secrets SOPS + age
Tests pytest + pytest-asyncio
Linting ruff

Modulstruktur

src/
├── agents/
│   ├── orchestrator.py          # Pipeline-Koordination, State-Management
│   ├── image_analysis.py        # Bildanalyse-Agent
│   ├── price_research.py        # Preis-Recherche-Agent
│   ├── listing_creation.py      # Listing-Erstellung-Agent
│   └── chat_moderation.py       # Chat-Moderation-Agent (Service)
├── scrapers/
│   ├── ebay_sold_listings.py    # Scraper für abgeschlossene Verkäufe
│   └── price_analyzer.py        # Statistische Preisauswertung
├── api/
│   ├── ebay_trading.py          # eBay Trading API Client
│   ├── ebay_finding.py          # eBay Finding API Client
│   └── ebay_messaging.py        # eBay Messaging API Client
├── models.py                    # Alle Dataclasses / Pydantic-Modelle
└── config.py                    # Konfiguration aus Umgebungsvariablen

tests/
├── agents/
├── scrapers/
└── api/

docs/
└── architecture.md

7. Sicherheit & Compliance

eBay-API & Nutzungsbedingungen

  • Rate Limits: Alle API-Aufrufe laufen durch ein zentrales Rate-Limit-Modul mit Exponential Backoff
  • ToS-Compliance: Automatisch generierte Texte werden auf verbotene Inhalte geprüft (Keyword-Blacklist + LLM-Validierung)
  • Kein Scraping produktiver Listings: Preisrecherche ausschließlich über die offizielle Finding API oder explizit erlaubte Endpunkte
  • API-Credentials: Niemals im Code hardcodiert — ausschließlich über Umgebungsvariablen

Secrets-Management (SOPS + age)

Dieses Projekt folgt dem globalen Secrets-Standard des openclaw-Servers:

  • Verschlüsselung: Alle .env-Dateien werden mit SOPS + age verschlüsselt
  • age Public Key: age1vf04awvs2t0agylyz6yz2yrkngks3592d6s8agw3uu8hs8qks32qzpaldg
  • Management: /opt/secrets/secrets.sh encrypt ebay-auto-lister nach jeder Änderung
  • Berechtigungen: .env-Dateien müssen chmod 600 haben

.env-Regeln

# .env (NIEMALS committen)
EBAY_APP_ID=...
EBAY_CERT_ID=...
EBAY_DEV_ID=...
EBAY_AUTH_TOKEN=...
ANTHROPIC_API_KEY=...
  • .env ist in .gitignore eingetragen — ein Commit schlägt fehl, wenn .env staged wird
  • CI/CD erhält Secrets ausschließlich über verschlüsselte Umgebungsvariablen, nicht über Repository-Dateien
  • Rotation von API-Keys erfolgt über secrets.sh edit ebay-auto-lister → Änderung → secrets.sh encrypt ebay-auto-lister