zum Blättern · Enter öffnet · Esc schließt

Kontakt aufnehmen.

Projekte

Kirchenbücher: vom Open-Source-Transkriber zur Datenstraße.

Eigenprojekt30. Juli 2026

Bereich
Genealogie
Umsetzung
Feb.–Mai 2026, nebenher
Kompetenz
Document AI
Stack
Python · Gemini · Flask · Vanilla JS · PyMuPDF · OpenCV · pandas · Excel · Git

Ergebnis

  • 28.950 Datensätze aus 18 Archivbeständen — als JSON mit Koordinaten im Scan statt als Fließtext
  • Zweistufige Prüfung: Regeln ohne Modell, dazu ein zweiter, ausschließlich prüfender Modelldurchgang
  • Ein Korrekturarbeitsplatz im Browser: Zeile anklicken, Stelle im Scan sehen, korrigieren, neu prüfen
  • Fehlerquoten habe ich nicht systematisch gemessen — was markiert war, blieb Handarbeit

Dieses Projekt ist kein Werkzeug, das ich erfunden habe. Es ist ein Fork — und interessant ist daran gerade, wie weit er vom Original abgedriftet ist.

Die Grundlage heißt GeneaScript (MIT-Lizenz, von dekochka): ein Kommandozeilenwerkzeug, das Fotos handschriftlicher Kirchenbucheinträge durch ein Google-Gemini-Modell schickt und das Ergebnis als lesbaren Text ausgibt. Ich habe es für meine eigene Familienforschung übernommen — und dann in eine andere Richtung weitergebaut, weil mein Material eine andere Frage stellte.

Mein Anteil sind neun Commits zwischen Februar und Mai 2026: gut 12.500 hinzugefügte Zeilen in 54 Dateien. Was davon von mir ist und was nicht, steht weiter unten im Klartext.

Bildschirm des Korrekturwerkzeugs: links eine Tabelle mit erkannten Zeilen, rechts der Scan einer aufgeschlagenen Doppelseite mit engen handschriftlichen Tabellenzeilen
Das Ausgangsmaterial: eine Doppelseite, zwei Spaltenblöcke, rund sechzig Zeilen. Links dieselben Zeilen als Daten.

Was das Werkzeug vorher tat

Das Original löst eine klar umrissene Aufgabe: Bilder aus einem lokalen Ordner oder einer Google-Drive-Ablage werden an ein Gemini-Modell geschickt, und die Transkription landet als Text in einem Google-Doc — mit Überschriften pro Seite, Links zur Bildquelle und Personenblöcken in mehreren Sprachen. Dazu gehören ein Einrichtungsassistent, zwei Betriebsarten (lokaler API-Schlüssel oder volle Google-Cloud-Integration) und ein Wiederherstellungsskript, das das Dokument aus den Modell-Logs rekonstruiert, falls der Lauf spät abbricht.

Für einen Menschen, der ein Kirchenbuch liest, ist das genau das Richtige: ein Dokument, das man von oben nach unten durchgehen kann.

Warum Text nicht genügte

Mein Material sind überwiegend keine Kirchenbücher im engeren Sinn, sondern Beichtregister (исповѣдная роспись) — und die sind keine Sammlung von Ereignissen, sondern eine Haushaltsliste: Hofnummer, laufende Nummer männlich, laufende Nummer weiblich, Name samt Stand, Alter männlich, Alter weiblich. Zeile für Zeile, Haushalt für Haushalt, ein ganzes Dorf pro Band.

Ein einzelner Bestand aus dem Jahr 1863: 20 Doppelseiten, 1.341 Zeilen. Über alle Bestände hinweg sind es inzwischen 28.950 Datensätze aus 18 Beständen, drei Ortschaften und den Jahren 1745 bis 1880.

Damit kann man als Fließtext nichts anfangen. Man kann nicht nach einem Familiennamen sortieren, nicht zählen, wie viele Haushalte ein Dorf hatte, nicht zwei Jahrgänge nebeneinanderlegen — und, was sich als das Wichtigste erwies: man findet eine zweifelhafte Angabe nicht mehr im Scan wieder. Genau das ist bei Handschrift aus dem 18. Jahrhundert aber der Normalfall.

Also brauchte das Werkzeug ein Schema statt Prosa.

Vom Archiv-PDF zum geprüften Datensatz — und weiter zum Stammbaum 1 Vorlage Archiv-PDF, 800 MB Halbseiten je Blatt Stempel, Schatten → „Was liegt vor?" 2 Doppelseiten Seiten rendern Ränder beschneiden Hälften fügen → „Ein Bild, ein Blick" 3 Erkennung Gemini, festes Schema Felder je Spalte Koordinate je Zeile → „Was steht da?" 4 Prüfung Regeln, ohne Modell 2. Durchgang: prüfen Schwelle 0,7 → „Wo hinsehen?" 5 Arbeitsplatz im Browser Zeile anklicken → Stelle im Scan; Feld korrigieren; neu prüfen Kästen kalibrieren, Haushalte neu nummerieren, Undo Export: Markdown, Excel 6 Abgleich GEDCOM aus dem Stammbaum, Namens- vergleich → Kandidaten
Die Schritte 1, 2, 4, 5 und 6 sind neu; Schritt 3 ist der Kern des ursprünglichen Werkzeugs, nur mit anderem Ausgabeformat.

Vom Text zum Schema

Der Umbau begann an der Stelle, an der das Modell antwortet. Statt einer Textantwort verlangt der Lauf jetzt ein JSON nach festem Schema — zwei Schemata, je nach Dokumentart: eines für Beichtregister (Haushalt, laufende Nummern, Name und Stand, Alter), eines für den Geburtsteil klassischer Kirchenbücher (Eintragsnummer, Geburts- und Taufdatum, Kind, Eltern, Paten, wer das Sakrament vollzog, Randnotizen).

Zwei Entscheidungen daran waren wichtiger als das Schema selbst:

Jede Zeile bekommt ihre Koordinate. Zu jedem Datensatz liefert das Modell einen Kasten im Bild — normalisiert auf 0–1000 statt in Pixeln, weil die Scans zwischen den Beständen unterschiedlich groß sind (dieser hier: 6.152 × 4.793). Damit ist jede Angabe rückverfolgbar: ein Klick, und man sieht die Handschrift, aus der sie stammt.

Das Modell soll nicht denken. Im Prompt steht das ausdrücklich: „Du bist ein Scanner, kein Interpret.“ Wenn eine Zahl in der Frauenspalte steht, der Name aber männlich klingt, bleibt sie in der Frauenspalte. Vorreformatorische Schreibung (ѣ, і, ъ am Wortende) wird nicht modernisiert. Das klingt nach einer Kleinigkeit, ist aber der Unterschied zwischen einer Quelle und einer Nachdichtung — und in der Genealogie ist eine stillschweigend „verbesserte“ Namensform ein falscher Ahne.

Aus zwei Halbseiten eine Doppelseite

Archive liefern große PDFs, in denen eine aufgeschlagene Doppelseite auf zwei PDF-Seiten aufgeteilt ist. Bei Kirchenbüchern ist das fatal: ein einziger Eintrag verteilt sich über beide Hälften — links Datum, Name und Eltern, rechts Paten und der Geistliche, der getauft hat. Getrennt verarbeitet, zerfällt jeder Eintrag in zwei Fragmente, die niemand mehr zusammensetzt.

Also ein eigener Vorlauf: Seiten rendern, Ränder am Inhalt beschneiden, Hälften zu einem Bild fügen. Vier Fügeverfahren sind eingebaut — mechanisch, mit Randbeschnitt, ausgerichtet über eine Homographie und als Panorama-Zusammensetzung. Für typische Archivscans gewinnt fast immer das einfachste mit Randbeschnitt; die aufwendigen Verfahren brauchen Überlappung, die es hier gar nicht gibt.

Der Bundsteg — der dunkle Streifen in der Falzmitte, in dem Linien sich krümmen und Text zusammengedrückt wird — bleibt bewusst unbehandelt. Kein Weichzeichnen, kein „Geradebiegen“: beides erfindet Bildinhalt. Stattdessen weiß der Prompt davon und hat eine Anweisung dafür: im Falz nichts raten, unlesbar als unlesbar melden.

Der Betrachter wurde zum Arbeitsplatz

Das Original zeigt Ergebnisse in einem Google-Doc. Bei 1.341 Zeilen pro Bestand ist das kein Arbeitsmittel mehr, sondern ein Ablageort. Aus dem kleinen Betrachter, mit dem ich anfing, wurde deshalb schrittweise ein Korrekturarbeitsplatz: links die Tabelle, rechts der Scan, dazwischen die Koordinaten aus Schritt 3. Aktuell 25 API-Routen — Felder ändern, Zeilen einfügen und löschen, durchnummerieren, Haushalte neu nummerieren, Geschlecht umschalten, Undo, Export nach Markdown und Excel, eine andere Datei über den System-Dialog öffnen.

Ausgewählte Zeile: im Scan ist die zugehörige Textzeile blau umrahmt, unten zeigt eine Leiste die Felder des Satzes und darunter eine Prüfmeldung zum Namensfeld
Eine Zeile angeklickt: der Ausschnitt springt an die Stelle im Scan, unten stehen die Felder und die Prüfmeldungen zu diesem Satz.

Der nützlichste Teil ist der unauffälligste. Die Kästen, die das Modell liefert, sitzen nicht zufällig falsch, sondern systematisch: sie wandern über eine Seite hinweg nach unten weg. Deshalb korrigiert die Kalibrierung nicht einen Kasten, sondern verschiebt alle folgenden Kästen derselben Seite um denselben Betrag mit. Eine Handbewegung richtet vierzig Zeilen.

Zwei Ebenen Prüfung

Ein Modell, das Handschrift von 1745 liest, irrt sich. Die Frage ist nicht, ob, sondern wo — und darauf antworten zwei getrennte Schichten.

Regeln, ohne Modell. Reines Python plus kleine Wörterbücher: Vornamen männlich und weiblich, Familiennamen der Gegend, Verwandtschaftsbezeichnungen, Standesangaben. Dazu Plausibilitäten: läuft die Nummerierung monoton, passen Geburts- und Taufdatum zueinander, steht im Feld „wer vollzog das Sakrament“ überhaupt ein geistlicher Titel, häufen sich Unsicherheitsmarker in einem Satz. Jede Meldung hat eine Schwere: Fehler, Warnung, Hinweis.

Ein zweiter Durchgang, der nur prüfen darf. Derselbe Scan geht ein zweites Mal an das Modell — aber mit der ersten Fassung im Prompt und einer strikt unterscheidenden Aufgabe: für jedes Feld ein Urteil (stimmt, zweifelhaft, falsch, unlesbar), eine Konfidenz und, nur bei Zweifel, ein Alternativvorschlag. Ausdrücklich verboten ist das Erfinden von Korrekturen; Inhalt im Bundsteg gilt als unlesbar, nicht als falsch.

Danach entscheidet eine Sortierstufe pro Satz: Regelfehler heißt immer prüfen, Warnung heißt prüfen, Konfidenz unter 0,7 heißt prüfen, jedes zweifelhaft oder falsch heißt prüfen. Übrig bleibt eine Datei mit genau den Sätzen, die ein Mensch ansehen soll — mit Begründung, nicht als pauschales „bitte alles kontrollieren“.

Nicht „verbessere das" — sondern „zeig mir, wo ich hinsehen muss" Erste Fassung JSON nach Schema Zeile + Koordinate Regeln, kein Modell Wörterbücher: Namen, Stände Zählungen, Datumslogik Zweiter Durchgang nur urteilen: stimmt / zweifelhaft / falsch / unlesbar Sortierstufe Fehler, Warnung, Konfidenz < 0,7 sauber bleibt unangetastet Prüfliste Satz + Begründung Arbeitsplatz: ansehen, korrigieren, neu prüfen nichts wird automatisch überschrieben
Der zweite Modelldurchgang erzeugt keinen neuen Text, sondern nur Urteile. Das macht ihn überprüfbar — und billig zu ignorieren, wenn er irrt.

Wo die Regeln Lärm machen

Auf dem oben gezeigten Bestand markiert die Regelschicht 357 von 1.341 Sätzen. Das klingt nach einer Fehlerquote, ist aber keine — und der Screenshot zeigt schön, warum. Bemängelt wird dort: „Familienname Іоаннъ nicht in der Datenbank“ mit dem hilfsbereiten Hinweis auf zwei ähnliche Namen. Іоаннъ ist aber kein Familienname, sondern ein Vorname; der Zerleger hat das Feld „Priester Іоаннъ Кониковъ Компаченко“ falsch aufgeteilt. Die Meldung sagt also mehr über meine Regeln als über die Transkription.

Genau deshalb ist das Ergebnis eine Liste und keine Automatik. Nichts wird selbsttätig überschrieben, und ich habe die Fehlerquote der Erkennung nicht systematisch gemessen — dazu hätte ich einen von Hand geprüften Referenzbestand gebraucht, den es nicht gibt. Was ich habe, ist eine Reihenfolge: erst die Sätze, bei denen zwei unabhängige Schichten Zweifel anmelden.

Prompt-Änderungen messbar machen

Der Prompt ist bei dieser Aufgabe die stärkste Stellschraube — und die verführerischste. Man ändert einen Satz, liest drei Seiten und findet es besser. Das ist kein Befund.

Deshalb gibt es ein kleines Vergleichswerkzeug: es stellt zwei Läufe desselben Bestands Seite für Seite und Feld für Feld gegenüber und schreibt die Abweichungen in eine Excel-Datei — Ebene, Seite, Satznummer, Feld, Wert A, Wert B. Damit wird aus „fühlt sich besser an“ eine filterbare Liste von Unterschieden.

Der Anlass war konkret: dem Prompt kann man eine Liste der in diesem Ort üblichen Familiennamen mitgeben. Das hilft der Erkennung — zieht aber seltene Formen in Richtung der bekannten. Deswegen steht in der Anweisung ausdrücklich, dass andere Namen möglich sind und genau so zu übernehmen sind, wie sie geschrieben stehen. Ob die Liste unterm Strich hilft, hängt am Bestand; die Vergleichsdatei macht die Frage überhaupt erst beantwortbar.

Von Zeilen zu Familien

Zeilen sind noch keine Verwandtschaft. Der letzte Teil des Forks verlässt deshalb das Archivmaterial und trifft auf zwei andere Quellen: den eigenen Stammbaum als GEDCOM-Export und eine separate Namensliste.

Drei kleine Skripte: das erste wandelt die GEDCOM-Datei in eine Personenliste in Excel. Das zweite normalisiert Familiennamen auf eine Wurzel — Vokale zusammenlegen (и/і/ы), typische Endungen abschneiden (-енко, -ський, -ов, -чук …), lateinisch geschriebene Namen ins Kyrillische übertragen — und baut daraus eine Zuordnung Name → Geschlecht im Sinne von Familienzweig. Das dritte vergleicht beide Seiten unscharf und schreibt einen Bericht: Treffer, Trefferart, Punktwert, Geburtsjahre nebeneinander, farbig nach Herkunft der Spalte.

Was dabei herauskommt, sind Kandidaten, keine Tatsachen. Bei Namen wie Иванъ Ивановъ liegt der Punktwert immer hoch; er ist eine Sortierhilfe, kein Beweis. Dieselbe Haltung wie beim Prüflauf: das Werkzeug ordnet die Arbeit, es erledigt sie nicht.

Was ein Fork schulden muss

Die MIT-Lizenz erlaubt praktisch alles, auch das Verschweigen. Ein Projektbericht darf das trotzdem nicht, deshalb hier der Schnitt:

Vom Original stammen der Erkennungskern samt Batch-Verarbeitung und Logging, der Einrichtungsassistent, die zwei Betriebsarten, die komplette Google-Integration (Drive, Docs, Vertex AI) und das Wiederherstellungsskript. Das sind über 140 Commits Vorarbeit, ohne die ich nicht in einer Woche bei laufenden Transkriptionen gewesen wäre.

Von mir sind das strukturierte Ausgabeformat samt beider Schemata und der Koordinaten, die Prompts für Beichtregister, Titelseiten und den Prüfdurchgang, der PDF-Vorlauf, der Arbeitsplatz im Browser, die Regel- und Prüfschicht, das Vergleichswerkzeug für Läufe, die Schema-Migration älterer Ergebnisdateien und der Abgleich mit dem Stammbaum.

Mein Fork selbst ist nicht öffentlich — er enthält Archivmaterial und Personendaten lebender Verwandter. Die Ausschnitte hier stammen aus meinem Arbeitsstand; gezeigt werden ausschließlich Einträge des 19. Jahrhunderts.

Was ich daraus mitnehme

Text für Menschen und Daten für Maschinen sind zwei Produkte, nicht zwei Formate. Derselbe Modellaufruf steht in der Mitte, aber alles davor und danach ist anders. Das Original war für den ersten Fall gebaut und gut darin; die Drift kam nicht von besseren Ideen, sondern von einer anderen Frage.

Ein zweiter Durchgang, der nur urteilen darf, ist verlässlicher als einer, der verbessern soll. Sein Ergebnis ist ein Urteil mit Konfidenz, kein neuer Text — man kann es gewichten, verwerfen, gegen Regeln stellen. „Mach es besser“ liefert dagegen eine zweite Version, deren Verhältnis zur ersten niemand kennt.

Regeln machen Lärm, und das ist in Ordnung, solange nichts automatisch passiert. Ein Drittel markierte Sätze wäre eine Katastrophe, wenn das Werkzeug sie selbst korrigierte. Als geordnete Warteliste ist es brauchbar.

Die wirkungsvollsten 500 Zeilen waren nicht der Modellaufruf. Es war die Kalibrierung, die aus einer Korrektur vierzig richtige Kästen macht. Bei Datenarbeit liegt der Hebel selten im klugen Teil, sondern in dem, was Wiederholung erspart.

Was davon übertragbar ist

Wer Dokumente in Daten verwandeln will — Lieferscheine, Formulare, alte Akten — findet hier vier Bausteine, die nichts mit Genealogie zu tun haben: ein festes Ausgabeschema statt freiem Text; eine Koordinate zu jedem Wert, damit man ihn im Original wiederfindet; eine Prüfschicht, die eine Warteliste erzeugt statt stiller Korrekturen; und einen Arbeitsplatz, an dem diese Warteliste in Minuten statt Stunden abgearbeitet wird.

Der Modellaufruf ist dabei der kleinste Teil — und der einzige, den man kaufen kann.

← Alle Projekte