[Challenge] Warum LLMs bei der Grid-Extraktion halluzinieren und wie wir eine handgeschriebene Scorecard in n8n geparst haben

:waving_hand: Hey n8n Community,

Document-Extraktions-Pipelines verarbeiten Rechnungen und Lebensläufe wunderbar. Aber während eines Spieleabends haben wir unserem KI-Modell etwas zu fressen gegeben, das einfach aussah, aber alles komplett zerstörte: einen handschriftlich ausgefüllten Kniffel-Spielzettel.

:mouse_trap: Die Gitter-Falle

Das Ziel: Ein Foto machen, Spieler mit einem handschriftlichen Sternchen (*) über ihrem Namen finden, ihre Punkte extrahieren, den 35-Punkte-Bonus berechnen (wenn oben $\ge$ 63), alles addieren und an Sheets und Telegram pushen.

Schaut euch das angehängte Foto an:

[![r/VibeCodersNest - [Challenge] Why LLMs hallucinate on grid extraction and how we parsed a handwritten scorecard in n8n|562.5xauto](Reddit - Please wait for verification"
&format=pjpg\"
&auto=webp\"
&s=fc466d9eba848f0d22ecd4429817b2c4df9c5479)](Reddit - Please wait for verification"
&format=pjpg\"
&auto=webp\"
&s=fc466d9eba848f0d22ecd4429817b2c4df9c5479 “Bild aus r/VibeCodersNest – [Challenge] Why LLMs hallucinate on grid extraction and how we parsed a handwritten scorecard in n8n”)

Für Menschen ist es offensichtlich. Aber das KI-Modell hat Namen halluziniert („Ivan

1 „Gefällt mir“

Der Ansatz der Math-Offloading ist genau richtig - wenn man die gesamte Arithmetik in einem Code-Node behält statt sich auf das LLM zu verlassen, wird die Pipeline unabhängig vom Modell deterministisch. Die spaltenbasierte JSON-Schema-Beschränkung ([{player_name, sum_top, sum_bottom}]) ist eine saubere Methode, um Row Bleeding zu bekämpfen.

Etwas, das es wert ist zu versuchen, wenn die Genauigkeit bei Fotos schlechter Qualität immer noch nachlässt: Jede Spalte als separaten Bildbereich zuschneiden, bevor sie an das Vision-Modell übergeben wird. Selbst ein grober, koordinatenbasierter Zuschnitt in einem Code-Node (mit den Bilddimensionen, die du aus dem Scorecard-Layout kennst) kann positionelle Halluzinationen dramatisch reduzieren, indem dem Modell ein einfacherer, einspaltige Kontext gegeben wird.

1 „Gefällt mir“

Hey @nguyenthieutoan, danke für dein Feedback!

Die Idee, jede Spalte in ein separates Bild zu croppen, ist definitiv interessant. Meine einzige Sorge ist, dass dafür das Foto jedes Mal mit ziemlich konsistenter Bildkomposition aufgenommen werden müsste. Andernfalls besteht das Risiko, dass während des Croppingprozesses wichtige Informationen abgeschnitten werden.

Das gesagt, es ist ein großartiger Vorschlag, und ich werde es definitiv ausprobieren, um zu sehen, wie praktisch es in einer realen Umgebung ist. Danke, dass du die Idee geteilt hast!

Das Framing-Problem ist berechtigt, aber du kannst es umgehen, indem du jedem Zuschnitt einen großzügigen Überlap hinzufügst – etwa 10–15% Puffer auf beiden Seiten jeder Spaltengrenzen statt an der exakten Kante zu schneiden. Das LLM konzentriert sich trotzdem auf die richtige Spalte, weil dein Schema + Prompt es auf einen Spieler gleichzeitig festlegt, und ein bisschen Überlap ist weit weniger schädlich als in die Zahlen zu schneiden. Bei gedruckten Scorecards wie Kniffel, wo die Spaltenüberschriften eine feste Breite haben, kannst du die Zuschnittgrenzen auch einmalig aus einem Referenzbild ableiten und dieselben Pixel-Offsets zuverlässig auf allen Fotos wiederverwenden, die unter ähnlichen Bedingungen aufgenommen wurden (gleicher Tisch, gleicher Abstand zum Telefon).

1 „Gefällt mir“

Hey @nguyenthieutoan, das klingt vernünftig! Ich werde diesen Ansatz definitiv ausprobieren.

Es ist einfach lustig zu sehen, wie leistungsfähig KI generell sein kann, und dann kommt plötzlich eine einzelne Edge-Case-Idee daher und man merkt, dass sie viele Lösungen zum Scheitern bringt. Ich genießen es eigentlich wirklich, solche Situationen zu entdecken – sie sind meistens die aufschlussreichsten.