פתיחת דפי בנק היא לא הדבר הכי מהנה בעולם. הם מגיעים כקבצי PDF סרוקים, ייצואי CSV או קבצי XML עטופים בראשי תיבות מסתוריים כמו OFX. עבור רואי חשבון, מנהלי חשבונות ובני תשתיות פינטק, הפיכת המסמכים הללו לנתונים נקיים ומובנים היא כאב ראש מתמיד. כשמודלי שפה גדולים (LLMs) הופיעו על הבמה, נראה היה שהם מציעים מוצא. פשוט תזינו למכונה PDF ותבקשו JSON. מה יכול להשתבש?
למדתי בדיוק מה יכול להשתבש בזמן שבניתי את StatementDecoder, כלי שנועד להמיר דפי בנק לנתונים שניתן לעבוד איתם. כמו מפתחים רבים, הנחתי שהחלק הקשה יהיה ללמד את המערכת לקרוא פריסות (layouts) מגוונות של מסמכים. טעיתי. קריאת המסמכים הייתה כמעט טריוויאלית. הסיוט האמיתי היה לזהות מתי המכונה המציאה בשקט מספר או החליפה בין שתי ספרות בסכום עסקה.
הדמו שעבד טוב מדי
הניסיון הראשון שלי היה פשוט בצורה מפתה. הזרקתי דפי בנק ישירות לתוך LLM וביקשתי בתמורה JSON מובנה. התוצאות הרגישו כמו קסם. המודל התמודד עם פריסות שונות בקלות. הוא קרא קבצי PDF סרוקים שפארסרים (parsers) סטנדרטיים נתקעו איתם. נראה היה שהוא מבין טבלאות, כותרות ודפי בנק מרובי עמודים ללא הנחיות מפורשות. במשך כמה שעות מפוארות, חשבתי שהבעיה נפתרה.
אז בדקתי אותו מול נתוני לקוחות אמיתיים, והקסם התנדף. בנקים בבריטניה משתמשים כל אחד בעיצוב דפי הבנק שלו, וההבדלים אינם רק קוסמטיים. דפי הבנק של Wise כוללים מוזרויות עיצוב משלהם. ייצואי CSV של Revolut נראים פשוטים עד ששמים לב לאופן שבו הם מטפלים בעסקאות במטבעות שונים ובשדות מטא-דאטה. קבצי OFX ישנים, פורמט שנראה באמת כאילו הוא שייך לשנות ה-90, מציפים כל פארסר שמצפה לסימון (markup) מודרני במבני תגיות ארכאיים ובעיות קידוד.
המודל עדיין חילץ נתונים הרבה יותר טוב מכל מערכת תבניות מוכנה מהמדף. אבל "הרבה יותר טוב" זה לא מספיק כשמדובר בכסף.
כשדיוק של 99% הוא כישלון
הנה הבעיה היסודית בשימוש ב-AI לחילוץ נתונים פיננסיים. אם מודל מעבד מאתיים שורות של עסקאות ומצליח ב-199 מהן, הפלט נראה מושלם. ה-JSON בנוי היטב. המפתחות והערכים תואמים. סקירה רגילה עשויה לא להראות דבר חשוד. אך אם הטעות היחידה הזו מחליפה בין שתי ספרות בסכום, הופכת הפקדה למשיכה, או מזיחה נקודה עשרונית, הנהלת החשבונות שלך נפגמת. לא תתפסו את זה על ידי מבט חטף על קיר של נתונים מובנים.
אדם שסוקר JSON גולמי כמעט לעולם לא יבחין בספרה שהוחלפה בסכום עסקה. העיצוב מושלם, מה שבאופן פרדוקסלי הופך את הטעות למסוכנת יותר. אי אפשר להשיק כלי פיננסי שהוא צודק ברוב הזמן. הוא חייב להיות צודק, או שהוא חייב להכריז בקול רם שהוא לא בטוח.
התגובה הראשונית שלי הייתה צפויה. יצרתי פרומפטים טובים יותר. שדרגתי למודלים בעלי יכולות גבוהות יותר. ניסיתי שיטות של שרשרת מחשבה (chain-of-thought reasoning) כדי לגרום למודל להציג את תהליך העבודה שלו. אף אחד מהדברים האלה לא פתר את בעיית הליבה. ביקשתי מאותה מערכת הסתברותית לייצר תשובה, ואז ביקשתי מאותה מערכת בדיוק לאשר שהתשובה נכונה. זה לא אימות. זהו "תיאטרון עקביות עצמית".
תנו למתמטיקה להחליט
לדפי בנק יש תכונה שלרוב אין למסמכים אחרים: אילוצים אריתמטיים מובנים. היתרה הפותחת בתוספת סכום כל העסקאות חייבת להיות שווה ליתרה הסופית. יתרות מצטברות, אם הן קיימות, חייבות להסתדר שורה אחר שורה. אלו אינן העדפות סגנוניות. אלו חוקים נוקשים.
בניתי מחדש את הארכיטקטורה סביב התובנה הזו. כעת, כל חילוץ, ללא קשר למקורו, עובר דרך שכבת אימות לפני שמשתמש כל רואה אותו. זה לא משנה אם הנתונים הגיעו מ-LLM שמפרש PDF מטושטש, ממנוע OCR שקורא דף סרוק, או מניתוח CSV ישיר. המאמת מתייחס לכל המקורות כחשודים באותה מידה.
הבדיקה פשוטה באופן אכזרי. חברו כל עסקה ליתרה הפותחת. השוו את התוצאה ליתרה הסופית המצוינת. אם המספרים אינם תואמים, משהו לא בסדר. סמנו את דף הבנק לבדיקה. דחו את החילוץ. אל תתנו לו להגיע למשתמש.
השינוי הבודד הזה שינה את האופי המלא של המוצר. מודל השפה כבר לא היה צריך להיות מושלם. הוא רק היה צריך להיות טוב מספיק כדי לייצר פלט שיכול לשרוד מבחן מתמטי. הלחץ עבר מהשגת דיוק בלתי אפשרי בתחום ללא אילוצים, לבניית לולאת משוב הדוקה בין יצירה לאימות.
The validator also exposed patterns in the errors. Certain document types consistently failed the math check, which told me exactly where to invest effort. Instead of blindly improving prompt engineering across the board, I could see that specific bank layouts caused systematic mistakes.
Code Where Code Belongs, AI Where It Shines
Perhaps the most humbling lesson was realizing how much of the pipeline did not need AI at all. When I encountered messy Australian OFX files, my instinct was to throw tokens at the problem. I briefly considered feeding the broken XML to the model and asking it to repair the structure before parsing. Instead, I wrote twenty lines of deterministic code. It fixed the encoding quirks and malformed tags instantly, with zero cost per file and perfect reproducibility.
That experience crystallized how extraction pipelines should be organized. There are three distinct jobs, and they should not be mixed together.
- The model understands messy documents. Scanned PDFs with warped tables, mixed fonts, and handwritten
