14 KiB
מפענח מסמכים אוניברסלי
כותרת
מפענח מסמכים אוניברסלי המופעל על ידי unstructured — קבלת פורמטים נפוצים של מסמכים באמצעות שירות יחיד, עם תיעוד מלא של מקור הנתונים ושילוב עם ספריית ניהול מסמכים, תוך רישום מיקומי המקור כמטא-דאטה של גרף ידע למעקב מקצה לקצה.
בעיה
ל-TrustGraph כיום יש מפענח ספציפי ל-PDF. תמיכה בפורמטים נוספים (DOCX, XLSX, HTML, Markdown, טקסט רגיל, PPTX וכו') דורשת או כתיבת מפענח חדש לכל פורמט או אימוץ ספריית חילוץ אוניברסלית. לכל פורמט יש מבנה שונה — חלקם מבוססי דפים, חלקם לא — ושרשרת התיעוד חייבת לתעד היכן בכל המסמך המקורי הגיע כל חלק של הטקסט שחולץ.
גישה
ספרייה: unstructured
יש להשתמש ב-unstructured.partition.auto.partition() שמזהה באופן אוטומטי את הפורמט מסוג MIME או סיומת הקובץ ומחלצת אלמנטים מובנים (כותרת, טקסט, טבלה, פריט רשימה וכו'). כל אלמנט מכיל מטא-דאטה, כולל:
page_number(לפורמטים מבוססי דפים כמו PDF, PPTX)element_id(ייחודי לכל אלמנט)coordinates(מלבן תחום עבור PDF)text(תוכן הטקסט שחולץ)category(סוג אלמנט: כותרת, טקסט, טבלה וכו')
סוגי אלמנטים
unstructured מחלץ אלמנטים מסוגים שונים ממסמכים. לכל אלמנט יש קטגוריה ומטא-דאטה נלווים:
אלמנטים טקסטואליים:
Title— כותרות סעיפיםNarrativeText— פסקאות גוףListItem— פריטי רשימה/רשימות ממוספרותHeader,Footer— כותרות/כותרות שוליים של עמודיםFigureCaption— כיתובים עבור תמונות/גרפיקהFormula— ביטויים מתמטייםAddress,EmailAddress— פרטי התקשרותCodeSnippet— בלוקי קוד (מ-Markdown)
טבלאות:
Table— נתונים טבלאיים מובנים.unstructuredמספק גםelement.text(טקסט רגיל) וגםelement.metadata.text_as_html(תגית HTML מלאה של<table>עם שורות, עמודות וכותרות). עבור פורמטים עם מבנה טבלה מוגדר (DOCX, XLSX, HTML), החילוץ אמין מאוד. עבור PDF, זיהוי טבלאות תלוי באסטרטגייתhi_resעם ניתוח פריסה.
תמונות:
Image— תמונות מוטמעות שזוהו באמצעות ניתוח פריסה (דורש אסטרטגייתhi_res). עםextract_image_block_to_payload=True, מחזיר את נתוני התמונה כ-base64 ב-element.metadata.image_base64. טקסט OCR מהתמונה זמין ב-element.text.
טיפול בטבלאות
טבלאות הן פלט ברמה ראשונה. כאשר המפענח נתקל באלמנט Table, הוא שומר על מבנה ה-HTML במקום לפשט לטקסט רגיל. זה נותן למחלץ ה-LLM במעלה הזרם קלט טוב יותר לשליפה של ידע מובנה מנתונים טבלאיים.
הטקסט של העמוד/הסעיף מורכב באופן הבא:
- אלמנטים טקסטואליים: טקסט רגיל, המחוברים עם שורות חדשות.
- אלמנטים של טבלאות: תגית טבלה HTML מ-
text_as_html, עטופה בתגית<table>כך שה-LLM יכול להבחין בין טבלאות לבין טקסט רגיל.
לדוגמה, עמוד עם כותרת, פסקה וטבלה מייצר:
סקירה פיננסית
ההכנסות גדלו ב-15% שנה אחר שנה, הודות לאימוץ ארגוני.
<table>
<tr><th>רבעון</th><th>הכנסות</th><th>צמיחה</th></tr>
<tr<td>רבעון 1</td><td>$12 מיליון</td><td>12%</td></tr>
<tr<td>רבעון 2</td><td>$14 מיליון</td><td>17%</td></tr>
</table>
זה שומר על מבנה הטבלה במהלך חלוקה לחלקים ולתוך צינור החילוץ, שבו ה-LLM יכול לחלץ קשרים ישירות מתאים מובנים ולא לנחש על התאמת עמודות מרווח לבן.
טיפול בתמונות
תמונות מחולצות ומאוחסנות בספריית הניהול כמסמכים משניים עם document_type="image" ו-ID urn:image:{uuid}. הם מקבלים משולשים של תיעוד מסוג tg:Image, המקושרים לעמוד/סעיף האב שלהם באמצעות prov:wasDerivedFrom. מטא-דאטה של תמונה (קואורדינטות, מימדים, element_id) נרשמים בתיעוד.
חשוב, תמונות אינן מופצות כפלט של TextDocument. הן מאוחסנות בלבד — אינן נשלחות במעלה הזרם למחלק או לכל צינור עיבוד טקסט. זה מכוון:
- אין עדיין צינור לעיבוד תמונות (שילוב מודל ראייה הוא עבודה עתידית)
- העברת נתוני תמונה ב-base64 או פיסות OCR לצינור חילוץ הטקסט תיצור משולשים של גרף ידע "זבל".
תמונות גם אינן נכללות בטקסט העמוד המורכב — כל אלמנטי Image מושמטים בשקט כאשר מחברים טקסט של אלמנטים עבור עמוד/סעיף. שרשרת התיעוד רושמת שתמונות קיימות ואיפה שהן הופיעו במסמך, כך שניתן יהיה לשלוף אותן על ידי צינור עיבוד תמונות עתידי מבלי לטעון מחדש את המסמך.
עבודה עתידית
- הכוונת ישויות
tg:Imageלמודל ראייה לתיאור, פרשנות דיאגרמות או חילוץ נתוני תרשימים. - אחסון תיאורי תמונה כמסמכים טקסטואליים שמוזנים לצינור החלוקה/חילוץ הסטנדרטי.
- קישור ידע שנחצה חזרה לתמונות מקור באמצעות תיעוד.
אסטרטגיות סעיפים
לפורמטים מבוססי דפים (PDF, PPTX, XLSX), אלמנטים תמיד מקובצים לפי עמוד/שקופית/גיליון תחילה. עבור פורמטים שאינם מבוססי דפים (DOCX, HTML, Markdown וכו'), למפענח יש אסטרטגיה לחלוקת המסמך לסעיפים. זה מוגדר בזמן ריצה באמצעות --section-strategy.
כל אסטרטגיה היא פונקציית קיבוץ על רשימת האלמנטים של unstructured. הפלט הוא רשימת קבוצות אלמנטים; שאר הצינור (הרכבת טקסט, אחסון בספריית הניהול, תיעוד, פליטת TextDocument) זהים ללא קשר לאסטרטגיה.
whole-document (ברירת מחדל)
פליטת כל המסמך כסעיף יחיד. תן למחלק במעלה הזרם לטפל בכל החלוקה.
- גישה פשוטה, נקודת התחלה טובה.
- עשויה ליצור
TextDocumentגדול מאוד עבור קבצים גדולים, אך המחלק מטפל בכך. - הטוב ביותר כאשר אתה רוצה הקשר מרבי לכל סעיף.
heading
פיצול בכותרות (Title). כל סעיף הוא כותרת וכל התוכן עד לכותרת ברמה שווה או גבוהה יותר. כותרות מקוננות יוצרות סעיפים מקוננים.
- מייצר יחידות מגובשות מבחינה נושאית.
- עובד היטב עבור מסמכים מובנים (דוחות, מדריכים, מפרטים).
- נותן למחלץ ה-LLM הקשר של כותרת יחד עם התוכן.
- חוזר ל-
whole-documentאם לא נמצאות כותרות.
element-type
פיצול כאשר סוג האלמנט משתנה באופן משמעותי — במיוחד, התחלה של סעיף חדש במעברים בין טקסט נרטיבי לטבלאות. אלמנטים עוקבים מאותה קטגוריה רחבה (טקסט, טקסט, טקסט או טבלה, טבלה) נשארים מקובצים.
- שומר על טבלאות כסעיפים עצמאיים.
- טוב למסמכים עם תוכן מעורב (דוחות עם טבלאות נתונים).
- לטבלאות יש תשומת לב חילוץ ייעודית.
count
קיבוץ מספר קבוע של אלמנטים לכל סעיף. ניתן להגדרה באמצעות --section-element-count (ברירת מחדל: 20).
- פשוט וצפוי.
- לא מכבד את מבנה המסמך.
- שימושי כברירת מחדל או לניסויים.
size
צבירת אלמנטים עד שמגיעים לגבול תווים, ואז התחלת סעיף חדש. מכבד את גבולות האלמנטים — לעולם לא מפצל באמצע אלמנט. ניתן להגדרה באמצעות --section-max-size (ברירת מחדל: 4000 תווים).
- מייצר גדלים בערך אחידים של סעיפים.
- מכבד את גבולות האלמנטים (בניגוד למחלק במעלה הזרם).
- פשרה טובה בין שליטה במבנה ובגודל.
- אם אלמנט יחיד חורג מהגבול, הוא הופך לסעיף משלו.
אינטראקציה עם פורמטים מבוססי דפים
עבור פורמטים מבוססי דפים, הקיבוץ לפי עמוד תמיד מקבל עדיפות. אסטרטגיות סעיפים יכולות באופן אופציונלי להחיל בתוך עמוד אם הוא גדול מאוד (לדוגמה, עמוד PDF עם טבלה עצומה), דבר ששולט על ידי --section-within-pages (ברירת מחדל: false). כאשר זה כוזב, כל עמוד תמיד סעיף אחד ללא קשר לגודל.
זיהוי פורמט
למפענח יש צורך לדעת את סוג MIME של המסמך כדי להעביר ל-partition() של unstructured. שתי אפשרויות:
- נתיב ספריית הניהול (
document_idמוגדר): אחסון מטא-דאטה של מסמך מהספרייה תחילה — זה נותן לנו אתkind(סוג MIME) שנרשם בזמן ההעלאה. ואז אחסון תוכן מסמך. שתי קריאות לספריית הניהול, אך אחזור המטא-דאטה קל משקל. - נתיב מקומי (תאימות לאחור,
dataמוגדר): אין מטא-דאטה זמין על ההודעה. השתמש ב-python-magicכדי לזהות את הפורמט מתוך בתים של תוכן כגיבוי.
אין צורך בשינויים בסכימת Document — ספריית הניהול כבר מאחסנת את סוג ה-MIME.
ארכיטקטורה
שירות universal-decoder יחיד שמבצע את הפעולות הבאות:
- מקבל הודעת
Document(מקומית או באמצעות הפניה לספריית הניהול). - אם נתיב ספריית הניהול: אחסון מטא-דאטה של מסמך (קבלת סוג MIME), ואז אחסון תוכן. אם נתיב מקומי: זיהוי פורמט מתוך בתים של תוכן.
- קריאה ל-
partition()כדי לחלץ אלמנטים. - קיבוץ אלמנטים: לפי עמוד עבור פורמטים מבוססי דפים, לפי אסטרטגיית סעיף מוגדרת עבור פורמטים שאינם מבוססי דפים.
- עבור כל עמוד/סעיף:
- יצירת ID
urn:page:{uuid}אוurn:section:{uuid}. - הרכבת טקסט עמוד: טקסט רגיל, טבלאות כ-HTML, תמונות מושמטות.
- חישוב ההיסט מוחלט של כל אלמנט בתוך טקסט העמוד.
- שמירה בספריית הניהול כתיעוד משני.
- יצירת משולשים של תיעוד עם מטא-דאטה מיקומי.
- שליחת
TextDocumentבמעלה הזרם לחלוקה.
- יצירת ID
- עבור כל אלמנט תמונה:
- יצירת ID
urn:image:{uuid}. - שמירת נתוני תמונה בספריית הניהול כתיעוד משני.
- יצירת משולשים של תיעוד (מאוחסנים בלבד, אינם נשלחים במעלה הזרם).
- יצירת ID
טיפול בפורמטים
| פורמט | סוג MIME | מבוסס עמוד | הערות |
|---|---|---|---|
| application/pdf | כן | קיבוץ לפי עמוד | |
| DOCX | application/vnd.openxmlformats... | לא | משתמש באסטרטגיית סעיף |
| PPTX | application/vnd.openxmlformats... | כן | קיבוץ לפי שקופית |
| XLSX/XLS | application/vnd.openxmlformats... | כן | קיבוץ לפי גיליון |
| HTML | text/html | לא | משתמש באסטרטגיית סעיף |
| Markdown | text/markdown | לא | משתמש באסטרטגיית סעיף |
| רגיל | text/plain | לא | משתמש באסטרטגיית סעיף |
| CSV | text/csv | לא | משתמש באסטרטגיית סעיף |
| RST | text/x-rst | לא | משתמש באסטרטגיית סעיף |
| RTF | application/rtf | לא | משתמש באסטרטגיית סעיף |
| ODT | application/vnd.oasis... | לא | משתמש באסטרטגיית סעיף |
| TSV | text/tab-separated-values | לא | משתמש באסטרטגיית סעיף |
מטא-דאטה של תיעוד
כל ישות עמוד/סעיף רושמת מטא-דאטה מיקומי כמשולשים של תיעוד בגרף GRAPH_SOURCE, ומאפשרת מעקב מלא מהמשולשים של גרף ידע חזרה למיקומי המסמך המקוריים.
שדות קיימים (כבר ב-derived_entity_triples)
page_number— מספר עמוד/גיליון/שקופית (מוגדר מ-1, רק עבור פורמטים מבוססי עמודים)char_offset— היסט מוחלט של תווים של עמוד/סעיף זה בתוך הטקסט המלא של המסמך.char_length— אורך התווים של הטקסט של עמוד/סעיף זה.
שדות חדשים (הרחבת derived_entity_triples)
mime_type— פורמט מסמך מקורי (לדוגמה,application/pdf)element_types— רשימה מופרדת בפסיקים של קטגוריותunstructuredשל אלמנטים (לדוגמה,title, paragraph, table).provenance— מידע על מקור הנתונים.