Home Ai Tools Artikel 3
Teil 3 Generative AI

himi-ai: Hilfsmittel-Einzelverträge automatisch lesen

Bild: KI-generiert


himi-ai: Hilfsmittel-Einzelverträge automatisch lesen

Ein digitaler Sachbearbeiter liest Vertrags-PDFs, prüft sich selbst und übergibt eine importfähige Tabelle.


1. Worum es geht

Hilfsmittel-Einzelverträge zwischen Krankenkassen und Leistungserbringern liegen heute meist als mehrseitige PDFs vor – mit Vertragskopf, mehreren Anlagen, Preislisten, Versorgungsbereichen, Genehmigungsregeln und Hilfsmittelnummern. Diese Inhalte manuell in ein Stammdatensystem zu übertragen, ist langwierig und fehleranfällig.

himi-ai automatisiert diesen Schritt: Aus einem PDF wird strukturiertes JSON und am Ende eine importfähige CSV-Datei für das GFI-System. Der Mensch prüft am Ende nur noch das Ergebnis im Browser, statt jede Zeile selbst abzutippen.

In einem Satz: Wir lesen Verträge nicht mehr Zeile für Zeile von Hand, sondern lassen einen digitalen Sachbearbeiter (KI + klassische Software) den Vertrag vorbereiten – und kontrollieren am Ende nur noch das Ergebnis.


2. Die Idee in einem Bild

Drei Stationen, jede mit klarer Verantwortung:

[PDF] ─► 1. Auslesen ─► 2. Verstehen ─► 3. Einordnen ─► [CSV]
         (klass. SW)    (KI)            (klass. SW)

Diese Trennung ist Absicht: KI macht das, was Regeln nicht können (Sprache verstehen, Hierarchien erkennen). Alles, was sich verlässlich rechnen lässt, bleibt klassische Software.


3. Station 1 – Auslesen (klassische Software, keine KI)

PDFs sind keine Tabellen, sondern „bedrucktes Papier in digitaler Form". Bevor irgendeine KI etwas sieht, läuft ein klassischer Extraktionsschritt:

🟦 Analogie: Ein Praktikant, der sehr genau lesen kann, aber nichts versteht. Er liefert sauberen Roh-Text und saubere Roh-Tabellen.


4. Station 2 – Verstehen (HIER kommt die KI)

Erst jetzt kommt das Sprachmodell ins Spiel – und zwar streng eingerahmt:

🟦 Analogie: Ein erfahrener Sachbearbeiter mit einem leeren, klar strukturierten Formular. Er trägt nur ein, was er findet, und nichts, was nicht ins Formular gehört.


5. Station 3 – Einordnen (klassische Software, Regeln)

Was die KI liefert, ist sauber strukturiert – aber noch nicht fachlich geprüft. Das übernimmt wieder klassische Software:

🟦 Analogie: Der Qualitätsprüfer, der das ausgefüllte Formular gegen den Katalog abgleicht und Tippfehler markiert.


6. Wer macht was?

KI macht Klassische Software macht
Hierarchie erkennen (Anlagen, Sektionen) PDF-Text und Tabellen extrahieren
Werte den richtigen Feldern zuordnen Tabellen über Seitenumbrüche zusammenführen
Mit Sprachvarianten umgehen („AC/TK", „Abrechnungscode") Regex-Validierung (HiMi, PZN, IK, LEGS)
Zusammenhängende Texte zusammenfassen Mapping ins Domänen-Modell
GKV-Katalog-Lookup
Genehmigungspflicht-Regeln aus Fließtext anwenden

Faustregel: Sprachverständnis = KI. Rechenbare Regeln = klassische Software.


7. Warum die KI nichts erfindet

Halluzinationen sind das größte Risiko bei generativer KI. Im himi-ai-Stack ist dieses Risiko an mehreren Stellen eingegrenzt:

Kurz gesagt: Die KI darf vorschlagen, der Mensch und die Regeln entscheiden.

Selbst ausprobieren

Die wichtigste Plausibilisierung ist klassische Software: reine Regex-Validierung der Identifier. Hier ein eigenständiges Beispiel, das einen Vorschlag der KI Feld für Feld gegen die formalen Muster prüft – ohne LLM, ohne Netzwerk, nur Standardbibliothek. Ein Vorschlag, der dieses Tor nicht passiert, kommt nie in der Datenbank an.

import re
from dataclasses import dataclass

PATTERNS = {
    "himi":  re.compile(r"^\d{2}\.\d{2}\.\d{2}\.\d{4}$"),  # z.B. 15.25.01.0001
    "pzn":   re.compile(r"^\d{8}$"),                        # 8-stellige PZN
    "ik":    re.compile(r"^\d{9}$"),                        # 9-stellige IK
    "legs":  re.compile(r"^[A-Z0-9]{2,6}$"),                # Abrechnungscode
}

@dataclass(frozen=True)
class Ok:
    field: str
    value: str
@dataclass(frozen=True)
class Err:
    field: str
    value: str
    reason: str

def validate(field: str, value: str):
    """Reine Funktion: (Feld, Wert) → Ok | Err."""
    pattern = PATTERNS.get(field)
    if pattern is None:
        return Err(field, value, f"unbekanntes Feld: {field}")
    if not pattern.fullmatch(value):
        return Err(field, value, f"passt nicht zu Muster {pattern.pattern}")
    return Ok(field, value)

def validate_record(record: dict):
    """Validiert alle Felder eines KI-Vorschlags."""
    return [validate(k, v) for k, v in record.items()]

# Beispiel: ein KI-Vorschlag aus Station 2 – manche Werte sind absichtlich kaputt.
ki_vorschlag = {
    "himi": "15.25.01.0001",   # ok
    "pzn":  "12345678",        # ok
    "ik":   "12345",           # zu kurz
    "legs": "AC/TK",           # Sonderzeichen → invalide
}

for result in validate_record(ki_vorschlag):
    print(result)

Erweiterungs-Idee: Trenne validate_record in partition(results) (alle Oks vs. alle Errs) und füge eine kleine Reporting-Funktion hinzu, die dem Reviewer im UI nur die problematischen Felder anzeigt – reine Datentransformation, problemlos testbar.

Genau das setzen wir jetzt um: partition trennt das Ergebnis sauber in „passt" und „passt nicht", review_report baut daraus die Markdown-Liste, die der Reviewer im UI sieht. Beides sind reine Funktionen über den Validierungs-Ergebnissen aus dem ersten Block.

import re
from dataclasses import dataclass

PATTERNS = {
    "himi": re.compile(r"^\d{2}\.\d{2}\.\d{2}\.\d{4}$"),
    "pzn":  re.compile(r"^\d{8}$"),
    "ik":   re.compile(r"^\d{9}$"),
    "legs": re.compile(r"^[A-Z0-9]{2,6}$"),
}

@dataclass(frozen=True)
class Ok:
    field: str
    value: str
@dataclass(frozen=True)
class Err:
    field: str
    value: str
    reason: str

def validate(field, value):
    pat = PATTERNS.get(field)
    if pat is None:
        return Err(field, value, f"unbekanntes Feld: {field}")
    if not pat.fullmatch(value):
        return Err(field, value, f"passt nicht zu {pat.pattern}")
    return Ok(field, value)

def partition(results):
    """Reine Trennung: (oks, errs)."""
    oks  = [r for r in results if isinstance(r, Ok)]
    errs = [r for r in results if isinstance(r, Err)]
    return oks, errs

def review_report(oks, errs) -> str:
    """Markdown-Report nur mit den problematischen Feldern."""
    lines = [f"✅ {len(oks)} Felder ok, ❌ {len(errs)} Felder zu prüfen"]
    for e in errs:
        lines.append(f"- **{e.field}** = {e.value!r}: {e.reason}")
    return "\n".join(lines)

ki_vorschlag = {
    "himi":  "15.25.01.0001",
    "pzn":   "12345678",
    "ik":    "12345",         # zu kurz
    "legs":  "AC/TK",         # Sonderzeichen
    "color": "blau",          # unbekanntes Feld
}

results   = [validate(k, v) for k, v in ki_vorschlag.items()]
oks, errs = partition(results)
print(review_report(oks, errs))

Im UI bekommt der Reviewer damit nur die echten Problemfelder vorgelegt – die KI hat vorgeschlagen, klassische Software prüft, und ein Mensch entscheidet am Ende über die Restmenge.


8. Was sieht der Anwender?

Der Ablauf im Browser ist bewusst schlank gehalten:

  1. Vertrag hochladen – PDF per Drag-and-drop in die Upload-Seite.
  2. Verarbeitung – ein Live-Log zeigt die Schritte: „Tabellen extrahiert", „LLM strukturiert", „LEGS propagiert", „GKV-Katalog abgeglichen".
  3. Editierbares Formular – Vertragskopf, Anlagen, LEGS, HiMi-Ranges, Preise, Genehmigungspflicht. Alles ist sichtbar und korrigierbar.
  4. „Als Excel-Datei öffnen" – erzeugt eine CSV-Datei (Semikolon-getrennt, UTF-8 mit BOM), die direkt in das GFI-System bzw. Excel importiert werden kann.

Im persönlichen Termin tragen die Live-Demo am laufenden Tool und der Dialog die Stunde – dieses PDF ist die kompakte Begleitlektüre.


9. Stand & Roadmap

Heute stabil:

Roadmap (Diskussionspunkte mit der GFI):


10. Kontakt & nächste Schritte

Ziel des Termins: Gemeinsam klären, wie himi-ai an den Vertrags-Onboarding-Prozess der GFI andocken kann – und welche Anlagen-Typen wir als nächstes priorisieren.

📄 Als PDF