Du lädst ein beliebiges Dokument hoch - eine Rechnung, eine Visitenkarte, ein Vertragsschnipsel. Die Pipeline erkennt automatisch den Dokumenttyp und extrahiert die relevanten Felder per Claude, komplett ohne dass vorher festgelegt wurde, welcher Typ hochgeladen wird. Kein Server, den man selbst am Laufen halten muss - event-getrieben, serverlos, auf AWS.
Läuft live gegen eine echte, deployte AWS-Pipeline (S3 → Lambda → Claude → DynamoDB → API Gateway). Free-Tier-App schläft nach Inaktivität ein, erster Aufruf kann ein paar Sekunden zum Aufwachen brauchen.
Fünf Schritte von der hochgeladenen Datei bis zum angezeigten Ergebnis - vollständig event-getrieben, kein Polling.
Das Frontend fragt beim API Gateway eine Presigned-URL an und lädt die Datei direkt nach S3 hoch - ohne eigene AWS-Zugangsschlüssel.
Das S3-ObjectCreated-Event startet automatisch die
process_document-Lambda - kein manueller Trigger.
Ein einziger Claude-Call klassifiziert den Dokumenttyp und extrahiert gleichzeitig die typ-spezifischen Felder.
Die Antwort wird gegen das passende Pydantic-Schema geprüft und als Datensatz in DynamoDB abgelegt - inklusive Fehlerfällen.
Streamlit fragt die Ergebnisliste per HTTP ab und zeigt erfolgreiche wie fehlgeschlagene Verarbeitungen live an.
Drei synthetische Dokumenttypen, jeweils mit eigenem Pydantic-Schema, damit die LLM-Ausgabe validierbar ist - nicht nur "hoffentlich JSON".
| Typ | Beispiel-Inhalt | Extrahierte Felder |
|---|---|---|
invoice |
generierte Rechnungen (Fantasie-Firmen/-Beträge) | vendor, date, amount, currency, line_items[] |
business_card |
generierte Visitenkarten-Texte (Fantasie-Namen/-Firmen) | name, company, email, phone |
contract_snippet |
generierte Vertragsklausel-Ausschnitte (Fantasie-Parteien) | parties[], clause_type, effective_date, summary |
Alle Testdokumente unter sample_documents/ sind komplett selbst generiert - kein Bezug zu echten Kundendaten.
Klassifikation und Extraktion laufen in einem
Claude-Aufruf: der Prompt kennt alle drei Schemas und liefert direkt
{"doc_type": ..., "fields": {...}} zurück - spart einen
kompletten Roundtrip gegenüber getrennten Calls. Das Routing
(welches Schema validiert?) passiert danach im Python-Code.
Die Testdokumente sind maschinenlesbarer Text/PDF, kein gescanntes Bildmaterial. Die Lambda liest den Text direkt aus S3 bzw. extrahiert ihn aus dem PDF - eine Bild-zu-Text-Stufe wäre hier zusätzlicher Aufwand ohne Mehrwert.
Schlägt der Claude-Call fehl, passt die Antwort nicht ins Schema
oder ist doc_type: "unknown", schreibt die Lambda
trotzdem einen Datensatz mit status: "failed" statt
abzustürzen. Das Dashboard zeigt das genauso an wie Erfolge.
Ein S3-Upload triggert automatisch die Verarbeitung - das ist der serverlose, event-getriebene Kern.
Rückweg: Die Streamlit-App fragt die Ergebnisliste über
API Gateway → Lambda list_documents → DynamoDB per HTTP ab
und zeigt sie live an.
| Cloud-Compute | AWS Lambda (Python 3.12) - serverlose Ausführung, kein eigener Server |
| Storage | AWS S3 - Dokumenten-Upload, Event-Trigger |
| Datenbank | AWS DynamoDB - strukturierte Ablage der Extraktionsergebnisse |
| API | AWS API Gateway (HTTP API) - öffentliche Endpunkte für Upload-URL + Ergebnisliste |
| IaC | Terraform - reproduzierbares, versioniertes Infrastruktur-Setup |
| LLM | Anthropic Claude (Haiku) - Dokumenttyp-Klassifikation + Feldextraktion |
| Validierung | Pydantic v2 - Schema-Validierung der LLM-Ausgabe pro Dokumenttyp |
| Frontend | Streamlit - Upload-UI + Ergebnis-Dashboard |
| Tests | pytest + moto - AWS-Verhalten ohne echtes AWS-Konto testbar (35 Tests) |
| Projektseiten-Hosting | GitHub Pages (diese Seite - self-contained, kein CDN) |
Kein dauerhaft laufender Server, keine Grundgebühr - Kosten entstehen nur pro Nutzung.
Zum Aufräumen nach dem Ausprobieren: terraform destroy im infra/-Verzeichnis entfernt alle angelegten AWS-Ressourcen wieder vollständig.
process_document-Lambda (möglicher nächster Ausbauschritt).POST /upload-url, GET /documents) sind öffentlich ohne Authentifizierung erreichbar (bewusste Portfolio-Demo-Vereinfachung). Einziger Kostenschutz ist ein Rate-Limit auf dem API-Gateway-Stage (10 Anfragen/Sekunde, Burst 20) - ein echter Produktiveinsatz bräuchte einen richtigen Authorizer (z.B. API-Key oder Cognito).