Merlin Mechler
Alle Artikel
14 Min Lesezeit

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.

KI-ArchitekturStructured OutputPythonEnterpriseAgentic Workflows

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 v

Das 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 None

Schicht 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 result

Fehlerquellen 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)

Projektanfrage

In 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
Recruiter & Hiring Manager

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
Enterprise LLM Architecture: Structured Data Extraction | Merlin Mechler