Enterprise LLM-Architektur: Wie man strukturierte Daten zuverlässig aus unstrukturierten Texten extrahiert
Zuverlässige Datenextraktion aus unstrukturierten Texten mit LLMs — Architektur, Prompting-Strategien und Validierungsmuster für den Produktionseinsatz.
Das Problem mit unstrukturierten Daten im Enterprise-Kontext
In jedem mittelständischen Unternehmen stecken Millionen von Datenpunkten in PDFs, E-Mails, Verträgen, Angeboten und Gesprächsnotizen. Strukturierte Datenbanken enthalten nur einen Bruchteil davon. Der Rest ist buried in Text.
Klassische Ansätze — RegEx, regelbasierte Parser, manuelle Dateneingabe — skalieren nicht. Sie brechen bei leichten Formatänderungen. Sie erfordern ständige Wartung. Und sie scheitern an Sprache, die Menschen verstehen, aber Maschinen nicht.
LLMs ändern das fundamental. Aber nicht, wenn man sie wie ein Chat-Interface behandelt.
Das Problem: Im Enterprise-Einsatz ist "ungefähr richtig" nicht akzeptabel. Eine falsch extrahierte Rechnungsnummer, ein übersehenes Datum, ein fehlerhafter Betrag — das sind Fehler mit realen Kosten.
Die Architektur: Vier Schichten für zuverlässige Extraktion
Schicht 1: Schema-Definition mit Pydantic
Bevor man irgendeinen Prompt schreibt, definiert man das Zielschema präzise:
from pydantic import BaseModel, Field, validator
from typing import Optional, List
from datetime import date
from decimal import Decimal
class LineItem(BaseModel):
description: str = Field(..., min_length=1, max_length=500)
quantity: float = Field(..., gt=0)
unit_price: Decimal = Field(..., decimal_places=2)
total: Decimal = Field(..., decimal_places=2)
class InvoiceData(BaseModel):
invoice_number: str = Field(..., pattern=r'^[A-Z0-9\-]+$')
invoice_date: date
due_date: Optional[date]
vendor_name: str
total_amount: Decimal
currency: str = Field(default="EUR", pattern=r'^[A-Z]{3}$')
line_items: List[LineItem]
@validator('total_amount')
def total_must_match_items(cls, v, values):
if 'line_items' in values:
computed = sum(item.total for item in values['line_items'])
if abs(v - computed) > Decimal('0.02'):
raise ValueError(f'Total mismatch: {v} vs {computed}')
return vDas Schema ist kein Nice-to-have — es ist die einzige Quelle der Wahrheit. Alles andere orientiert sich daran.
Schicht 2: Strukturierter Prompt mit JSON-Mode
Der Prompt arbeitet direkt gegen das Schema. Kein freier Output:
import anthropic
import json
client = anthropic.Anthropic()
def extract_invoice(raw_text: str) -> dict:
system = """Du bist ein präziser Datenextraktions-Assistent für Rechnungen.
Extrahiere ausschließlich die explizit genannten Informationen.
Bei fehlenden Pflichtfeldern: setze null, nicht raten.
Beträge immer in der Originalwährung, ohne Konvertierung.
Datum-Format: YYYY-MM-DD."""
response = client.messages.create(
model="claude-opus-4-6",
max_tokens=2000,
system=system,
messages=[{
"role": "user",
"content": f"""Extrahiere die Rechnungsdaten aus folgendem Text als JSON.
Schema:
- invoice_number: string (Rechnungsnummer)
- invoice_date: string (YYYY-MM-DD)
- due_date: string|null (YYYY-MM-DD, optional)
- vendor_name: string
- total_amount: number
- currency: string (3-Letter ISO)
- line_items: array of {{description, quantity, unit_price, total}}
Text:
{raw_text}
Antworte NUR mit validem JSON, ohne Erklärung."""
}]
)
return json.loads(response.content[0].text)Schicht 3: Validierung und Fehlerbehandlung
Der LLM-Output ist der Rohstoff, nicht das Endprodukt:
from pydantic import ValidationError
import logging
logger = logging.getLogger(__name__)
def extract_and_validate(raw_text: str) -> InvoiceData | None:
try:
raw_json = extract_invoice(raw_text)
validated = InvoiceData(**raw_json)
return validated
except json.JSONDecodeError as e:
logger.error(f"LLM returned invalid JSON: {e}")
return None
except ValidationError as e:
logger.error(f"Schema validation failed: {e}")
# Hier: Retry mit expliziterem Prompt oder Human-Review-Queue
return None
except Exception as e:
logger.error(f"Unexpected extraction error: {e}")
return NoneSchicht 4: Confidence-Scoring und Human-in-the-Loop
Für kritische Felder braucht man ein Konfidenz-Signal:
def extract_with_confidence(raw_text: str) -> dict:
system = """Extrahiere Rechnungsdaten UND bewerte deine Konfidenz pro Feld.
Konfidenz-Skala:
- HIGH: Information explizit und eindeutig im Text
- MEDIUM: Information ableitbar aber nicht explizit
- LOW: Information fehlt oder unklar"""
# ... Prompt mit Konfidenz-Annotations
# Output: {"data": {...}, "confidence": {"invoice_number": "HIGH", ...}}
result = extract_invoice_with_meta(raw_text)
# Felder mit LOW confidence → Human Review Queue
low_confidence_fields = [
field for field, conf in result["confidence"].items()
if conf == "LOW"
]
if low_confidence_fields:
queue_for_human_review(result, low_confidence_fields)
return resultFehlerquellen und wie man sie eliminiert
Halluzination bei fehlenden Daten
Das häufigste Problem: Der LLM erfindet Werte, die nicht im Text stehen.
Lösung: Explizite Null-Instruktion im System-Prompt. "Bei fehlenden Informationen: null, nicht raten." In Tests mit und ohne diese Instruktion sinkt die Halluzinationsrate um 60-80%.
Format-Inkonsistenz
Datum "2024/01/15" vs "15.01.2024" vs "15. Januar 2024" — alles muss auf YYYY-MM-DD normiert werden.
Lösung: Pydantic-Validators + explizite Format-Instruktion. Alternativ: Nachverarbeitungs-Schicht mit dateutil.
Numerische Präzision
Floats für Geldbeträge sind ein Anti-Pattern. 14.99 + 29.99 = 44.980000000000004.
Lösung: Decimal überall. Im Prompt explizit: "Beträge als Strings mit genau 2 Dezimalstellen."
Produktions-Checkliste
Bevor man die Pipeline live schaltet:
- Schema mit 50+ echten Dokumenten validiert (nicht Testdaten)
- Konfidenz-Tracking implementiert und Schwellenwerte kalibriert
- Human-Review-Queue für LOW-confidence Fälle existiert
- Logging auf Feld-Ebene (nicht nur Dokument-Ebene)
- Retry-Logik mit exponential backoff (Rate Limits)
- Kosten-Monitoring (Token pro Extraktion × Volumen)
- Drift-Detection: Regelmäßiger Vergleich gegen Ground-Truth-Sample
Was das in der Praxis kostet
Bei claude-opus-4-6 und einer durchschnittlichen Rechnung (1-2 Seiten, ~1.500 Token Input, ~300 Token Output):
- Kosten pro Extraktion: ~0,02–0,04 €
- Bei 1.000 Rechnungen/Monat: ~20–40 €
- Manuelle Erfassung bei 3 Min./Rechnung und 25 €/h: ~1.250 €
Der ROI ist in den meisten Enterprise-Kontexten eindeutig. Die Frage ist nicht ob, sondern wie gut die Implementierung ist.
Für konkrete Implementierungsfragen zu eurer Datenstruktur: [Erstgespräch buchen](/kontakt)
Siehe auch
Multi-Agent Systeme mit Claude: Architektur-Entscheidungen, die über Erfolg oder Scheitern bestimmen
16 Min LesezeitVom Chatbot zum Kollegen: Warum Agentic Workflows 2026 die Unternehmensinfrastruktur neu definieren
18 Min LesezeitLLMs für Developer Productivity im Enterprise: Was wirklich funktioniert (und was nicht)
11 Min LesezeitIn 5 Werktagen weißt du, ob sich euer KI-Invest lohnt.
Das KI-Klarheits-Audit™ — max. 2 Stunden dein Zeitaufwand, board-ready als Ergebnis. Keep / Kill / Upgrade für alle Tools, 3 priorisierte Use Cases, 90-Tage-Roadmap. Keine Verkaufsgespräche.
- Keep / Kill / Upgrade: welche Tools bleiben, welche weg können — konkret begründet
- 3 priorisierte Use Cases mit klarer 90-Tage-Roadmap
- Board-ready Report (8–12 Seiten) — heute noch zeigbar
- Klarheits-Garantie: kein Ergebnis, kein Geld
Sie suchen jemanden, der KI-Adoption und operativen Kontext zusammenbringt.
Ich bringe Business-Kontext und technische Umsetzung zusammen: GTM-Realität aus 8+ Jahren in B2B Sales und die Tiefe für AI Adoption, Use-Case-Priorisierung und Workflow-Integration — kein Theoretiker, sondern jemand der weiß, wie Unternehmen wirklich funktionieren.
- KI-Produktivität & AI Adoption: Non-Tech-Teams auf Senior-Level-Output bringen — nicht theoretisch, sondern hands-on
- 8+ Jahre B2B Sales, Growth & Operations — ich kenne operative Probleme von innen
- Python, SQL und technische Umsetzung — production-ready, nicht Demo
- Workflow Automation & Applied AI: von der Diagnose bis zum laufenden System
- Produktivitätsgenie: Diagnose first, dann bauen — kein Flickwerk, keine KI-Trends-Präsentation