Free lesson · GenAI Data Engineering

அனைத்து extraction வெளியீடுகளையும் இயல்பாக்கும் ஒருங்கிணைந்த document model-ஐ வடிவமைக்கவும்

Typed content blocks மற்றும் extraction method metadata கொண்ட, format-agnostic document schema-வை உருவாக்கவும். Docling, VLM மற்றும் Document AI வெளியீடுகளுக்கான adapters-ஐ உருவாக்கவும்.

Course: GenAI Data Pipelines · Chapter 1 · Document Ingestion with VLMs

Free to read — no subscription required.

அறிமுகம்

Docling, Document AI மற்றும் ஒரு vision-language model ஆகியவற்றிலிருந்து உள்ளடக்கத்தை இழுக்கும் ஒரு ingestion pipeline-ஐ நீங்கள் உருவாக்கும்போது, ஒவ்வொரு backend-உம் தனக்கே உரிய வடிவத்தில் உள்ளடக்கத்தைத் திருப்பித் தருகிறது — இங்கே bounding boxes, அங்கே page hierarchies, வேறொரு இடத்தில் freeform JSON — மேலும் ஒவ்வொரு downstream consumer-உம் if extractor == "docling": … என்று கிளைபிரிந்து, இறுதியில் codebase extractor பெயர்களைச் சுற்றி புதைபடிவமாக உறைந்துவிடுகிறது. ஒருங்கிணைந்த ஆவண மாதிரியைத் தவிர்க்கும் குழுக்கள், ஒவ்வொரு புதிய extractor வெளியாகும்போதும் chunkers, embedders மற்றும் search indexers-ஐ மீண்டும் எழுதுவதில் அடுத்த காலாண்டைச் செலவிடுகின்றன. இப்பாடத்தின் முடிவில், discriminated-union content blocks, provenance metadata மற்றும் ஒரு நிலையான adapter எல்லையுடன் கூடிய canonical document schema-வை வடிவமைக்க உங்களால் முடியும், இதனால் எந்த extractor அதை உருவாக்கியிருந்தாலும் downstream அமைப்புகள் ஒரே வடிவத்தைப் பயன்படுத்துகின்றன.

முக்கிய சொற்கள்

  • ஒருங்கிணைந்த ஆவண மாதிரி (Unified document model): ஒவ்வொரு extractor adapter-உம் இலக்காகக் கொள்ளும் ஒரே canonical schema (இங்கே, UnifiedDocument), இதனால் downstream chunkers, embedders மற்றும் indexers extractor பெயரின் அடிப்படையில் கிளைபிரிவதற்குப் பதிலாக ஒரே வடிவத்தைப் பயன்படுத்துகின்றன.
  • Discriminated union: ஒவ்வொரு variant-உம் ஒரு literal block_type tag-ஐ (எ.கா. TableBlock-இல் Literal["table"]) கொண்டிருக்கும் polymorphic content-block பிரதிநிதித்துவம்; Pydantic இதைப் பயன்படுத்தி கலப்பு block பட்டியல்களைத் தெளிவின்மை இல்லாமல் deserialize செய்கிறது.
  • Provenance metadata: எந்த extractor அந்த block-ஐ உருவாக்கியது என்பதை block அளவில் கண்காணிப்பது (பெயர், பதிப்பு, பக்கம், bounding box, confidence, quality_flags), block-இலேயே வைக்கப்படுவதால் quality-aware processing downstream-இல் வடிகட்டவோ மறு-வழிப்படுத்தவோ முடியும்.
  • Extraction adapter: ஒரு extractor-இன் native output-ஐ UnifiedDocument-ஆக மொழிபெயர்ப்பது மட்டுமே வேலையாகக் கொண்ட தனிமைப்படுத்தப்பட்ட class (எ.கா. DoclingAdapter); இது ingestion-ஐ extractor தேர்விலிருந்து பிரிக்கும் நிலையான எல்லையை உருவாக்குகிறது.

கருத்துகள்

இப்பாடம் ஒரே வடிவமைப்பாக ஒன்றிணையும் மூன்று யோசனைகளைக் கற்பிக்கிறது.

ஒரே canonical schema, பல adapters. UnifiedDocument மாதிரி என்பது ஒவ்வொரு downstream consumer-உம் சார்ந்திருக்கும் ஒப்பந்தம்; DoclingAdapter மற்றும் எதிர்கால DocumentAIAdapter / VLMAdapter ஆகியவை தங்கள் backend-இன் native output-ஐ அந்த ஒப்பந்தத்திற்கு மாற்றுவதற்காக மட்டுமே இருக்கின்றன. புதிய extractor-ஐச் சேர்ப்பது schema-வையோ எந்த consumer-ஐயோ ஒருபோதும் மாற்றாது — அது ஒரு adapter class-ஐச் சேர்க்கிறது, வேறு எதையும் அல்ல.

Free-form JSON-க்குப் பதிலாக discriminated unions. உண்மையான ஆவணங்கள் பத்திகள், தலைப்புகள், அட்டவணைகள், படங்கள் மற்றும் பட்டியல்களைக் கலந்து கொண்டிருக்கின்றன. ஒவ்வொன்றையும் literal block_type tag-உடன் கூடிய Pydantic மாதிரியாகக் குறியிடுவது, list[ContentBlock | TableBlock] சரியாக deserialize ஆக அனுமதிக்கிறது, அதே நேரத்தில் TableBlock.headers அல்லது ContentBlock.level போன்ற variant-குறிப்பிட்ட புலங்களுக்கு typed அணுகலையும் வழங்குகிறது. Free-form dicts அதே தரவை உருவாக்கினாலும் validation மற்றும் IDE ஆதரவை இழக்கின்றன.

Provenance என்பது முதன்மைப் புலம், sidecar log அல்ல. ஒவ்வொரு block-உம் தனக்கே உரிய Provenance-ஐ (extractor, version, page, bbox, confidence, quality_flags) கொண்டிருப்பதால், downstream code ஒவ்வொரு block-க்கும் தனித்தனியாக முடிவுகளை எடுக்க முடியும் — குறைந்த confidence கொண்ட VLM output-ஐ நீக்குவது, flag செய்யப்பட்ட blocks-ஐ மதிப்பாய்வுக்கு மறு-வழிப்படுத்துவது, RAG பதிலில் citations-ஐ இணைப்பது — இவை அனைத்தும் வெளிப்புற metadata store-உடன் மீண்டும் join செய்யாமலேயே. கீழே உள்ள Code Walkthrough, இந்த மூன்று யோசனைகளில் ஒவ்வொன்றும் schema-வில் எப்படித் தோன்றுகிறது என்பதையும், DoclingAdapter அவற்றை எப்படி உருவாக்குகிறது என்பதையும் துல்லியமாகக் காட்டுகிறது.

Code Walkthrough

Pydantic Schema-வை வரையறுத்தல்

ஆவண உள்ளடக்கத்தின் polymorphic தன்மையைக் கையாள discriminated unions-உடன் Pydantic மாதிரிகளைப் பயன்படுத்துங்கள்:

Code snippetpython
1from pydantic import BaseModel, Field 2from typing import Literal, Optional 3from datetime import datetime 4from enum import Enum 5 6class BlockType(str, Enum): 7 PARAGRAPH = "paragraph" 8 HEADING = "heading" 9 TABLE = "table" 10 FIGURE = "figure" 11 LIST_ITEM = "list_item" 12 CODE = "code" 13 14class Provenance(BaseModel): 15 extractor: str 16 extractor_version: str 17 page_number: Optional[int] = None 18 bbox: Optional[tuple[float, float, float, float]] = None 19 confidence: Optional[float] = None 20 quality_flags: list[str] = Field(default_factory=list) 21 22class TableCell(BaseModel): 23 text: str 24 row_span: int = 1 25 col_span: int = 1 26 27class TableBlock(BaseModel): 28 block_type: Literal["table"] = "table" 29 headers: list[str] 30 rows: list[list[TableCell]] 31 provenance: Provenance 32 33class ContentBlock(BaseModel): 34 block_type: BlockType 35 text: str 36 level: Optional[int] = None 37 children: list["ContentBlock"] = Field(default_factory=list) 38 provenance: Provenance 39 40class DocumentPage(BaseModel): 41 page_number: int 42 blocks: list[ContentBlock | TableBlock] 43 44class UnifiedDocument(BaseModel): 45 document_id: str 46 source_uri: str 47 schema_version: str = "1.0" 48 format: str 49 page_count: int 50 extraction_timestamp: datetime 51 pages: list[DocumentPage] 52 metadata: dict = Field(default_factory=dict)
  • வரிகள் 6-12: BlockType enum உங்கள் pipeline கையாளும் அனைத்து உள்ளடக்க வகைகளையும் வரையறுக்கிறது. Free-form strings-க்குப் பதிலாக enum-ஐப் பயன்படுத்துவது validation நேரத்தில் எழுத்துப் பிழைகளைப் பிடிக்கிறது மற்றும் downstream processors-இல் முழுமையான pattern matching-ஐ சாத்தியமாக்குகிறது.
  • வரிகள் 14-20: Provenance மாதிரி ஒவ்வொரு block-ஐயும் எந்த extractor உருவாக்கியது என்பதைக் கண்காணிக்கிறது. quality_flags பட்டியல் extraction-இன் போது கண்டறியப்பட்ட சிக்கல்களைப் பதிவு செய்கிறது — "low_confidence", "possible_hallucination", "truncated" — இது downstream-இல் quality-aware processing-ஐ சாத்தியமாக்குகிறது.
  • வரிகள் 28-31: TableBlock block_type: Literal["table"]-உடன் discriminated union pattern-ஐப் பயன்படுத்துகிறது, இதனால் Pydantic கலப்பு content block பட்டியல்களைச் சரியாக deserialize செய்ய முடியும். Headers மற்றும் rows row_span மற்றும் col_span வழியாக இணைக்கப்பட்ட cells-ஐ ஆதரிக்கும் TableCell objects-ஐப் பயன்படுத்துகின்றன.
  • வரிகள் 33-37: ContentBlock children புலம் வழியாக recursive nesting-ஐ ஆதரிக்கிறது, இது பிரிவுகள் துணைப்பிரிவுகளைக் கொண்டிருக்கும், அவை பத்திகளைக் கொண்டிருக்கும் உண்மையான ஆவணங்களின் படிநிலை அமைப்பைப் பிரதிபலிக்கிறது.
  • வரிகள் 43-52: மேல்-நிலை UnifiedDocument ஆவண-நிலை metadata, ஒவ்வொன்றும் blocks-ஐக் கொண்ட பக்கங்களின் பட்டியல், மற்றும் பரிணாம வளர்ச்சிக்கான schema_version ஆகியவற்றைப் பிடிக்கிறது.

Extraction Adapters-ஐ உருவாக்குதல்

ஒவ்வொரு adapter-உம் extractor-குறிப்பிட்ட output-ஐ ஒருங்கிணைந்த மாதிரியாக மாற்றுகிறது:

Code snippetpython
1class DoclingAdapter: 2 EXTRACTOR_NAME = "docling" 3 EXTRACTOR_VERSION = "2.0" 4 5 def to_unified_document( 6 self, result, source_uri: str 7 ) -> UnifiedDocument: 8 doc = result.document 9 pages = [] 10 11 current_page_blocks = [] 12 current_page = 1 13 14 for item, level in doc.iterate_items(): 15 page_num = item.prov[0].page_no if item.prov else current_page 16 17 if page_num != current_page and current_page_blocks: 18 pages.append(DocumentPage( 19 page_number=current_page, 20 blocks=current_page_blocks, 21 )) 22 current_page_blocks = [] 23 current_page = page_num 24 25 provenance = Provenance( 26 extractor=self.EXTRACTOR_NAME, 27 extractor_version=self.EXTRACTOR_VERSION, 28 page_number=page_num, 29 bbox=item.prov[0].bbox.as_tuple() if item.prov else None, 30 confidence=None, 31 ) 32 33 class_name = item.__class__.__name__ 34 if class_name == "SectionHeaderItem": 35 block = ContentBlock( 36 block_type=BlockType.HEADING, 37 text=item.text, 38 level=item.level, 39 provenance=provenance, 40 ) 41 elif class_name == "TableItem": 42 df = item.export_to_dataframe() 43 block = TableBlock( 44 headers=list(df.columns), 45 rows=[ 46 [TableCell(text=str(cell)) for cell in row] 47 for _, row in df.iterrows() 48 ], 49 provenance=provenance, 50 ) 51 else: 52 block = ContentBlock( 53 block_type=BlockType.PARAGRAPH, 54 text=item.text if hasattr(item, "text") else "", 55 provenance=provenance, 56 ) 57 58 current_page_blocks.append(block) 59 60 if current_page_blocks: 61 pages.append(DocumentPage( 62 page_number=current_page, 63 blocks=current_page_blocks, 64 )) 65 66 return UnifiedDocument( 67 document_id=self._generate_id(source_uri), 68 source_uri=source_uri, 69 format=str(result.input.format), 70 page_count=len(doc.pages) if hasattr(doc, "pages") else len(pages), 71 extraction_timestamp=datetime.utcnow(), 72 pages=pages, 73 ) 74 75 def _generate_id(self, uri: str) -> str: 76 import hashlib 77 return hashlib.sha256(uri.encode()).hexdigest()[:16]
  • வரிகள் 1-3: ஒவ்வொரு adapter-உம் தனது extractor அடையாளத்தை class constants-ஆக அறிவிக்கிறது, இதனால் இந்த adapter செயலாக்கும் அனைத்து ஆவணங்களிலும் நிலையான provenance கண்காணிப்பு உறுதி செய்யப்படுகிறது.
  • வரிகள் 14-23: Content blocks-ஐ பக்க எண்ணின் அடிப்படையில் குழுவாக்குங்கள். Docling-இன் iterate_items() உறுப்புகளை வாசிப்பு வரிசையில் தருகிறது, ஆனால் பக்க மாற்றங்களை provenance metadata-விலிருந்து கண்டறிய வேண்டும்.
  • வரிகள் 25-31: Docling-இன் output-இலிருந்து extractor பெயர், பதிப்பு, பக்க எண் மற்றும் bounding box-உடன் ஒவ்வொரு block-க்கும் Provenance objects-ஐ உருவாக்குங்கள்.
  • வரிகள் 33-52: Docling உறுப்பு வகைகளை ஒருங்கிணைந்த மாதிரியின் block வகைகளுக்கு map செய்யுங்கள். SectionHeaderItem அதன் level பாதுகாக்கப்பட்ட தலைப்பாக மாறுகிறது. TableItem ஒரு DataFrame-ஆக export செய்யப்பட்டு, பின்னர் சரியான TableCell objects-உடன் canonical TableBlock வடிவத்திற்கு மாற்றப்படுகிறது. மற்ற அனைத்து உறுப்புகளும் இயல்பாகப் பத்திகளாக மாறுகின்றன.
  • வரிகள் 65-72: Source URI-இலிருந்து பெறப்பட்ட deterministic ID-உடன் இறுதி UnifiedDocument-ஐ உருவாக்குங்கள், இதனால் idempotent மறு-extraction ஒரே ஆவண ID-ஐ உருவாக்குவது உறுதி செய்யப்படுகிறது.

Adapter pattern உங்கள் pipeline-ஐ எந்த ஒரு extraction backend-இலிருந்தும் பிரிக்கிறது. புதிய extractor-ஐச் சேர்ப்பதற்கு, எந்த downstream consumer code-ஐயும் மாற்றாமல் ஒரு புதிய adapter class-ஐ எழுதுவது மட்டுமே தேவை.

Loading diagram...

துறைசார் பயன்பாடு

செய்ய வேண்டியவை மற்றும் செய்யக்கூடாதவை

இப்போது நீங்கள் செயலாக்கத்தை முழுமையாகப் பார்த்துவிட்டீர்கள்; கீழே உள்ள நடைமுறைகள் நீடித்த அணுகுமுறையை உடையக்கூடிய அணுகுமுறையிலிருந்து பிரித்துக் காட்டுகின்றன.

செய்ய வேண்டியவை

  1. ஒவ்வொரு content-block variant-ஐயும் Literal["..."] block_type-உடன் tag செய்யுங்கள், இதனால் Pydantic கலப்பு list[ContentBlock | TableBlock] உள்ளடக்கத்தைத் தெளிவின்மை இல்லாமல் deserialize செய்ய முடியும், மேலும் consumers அந்த tag-இன் அடிப்படையில் dispatch செய்ய முடியும்.
  2. ஒவ்வொரு block-இலும் Provenance-ஐ கட்டாயமாக்குங்கள் — extractor பெயர், பதிப்பு, பக்க எண், கிடைக்கும் இடங்களில் bbox, மற்றும் quality_flags — இதனால் downstream re-ranking, debugging மற்றும் citation பாதைகள் ஒருபோதும் வெளிப்புற metadata store-உடன் மீண்டும் join செய்ய வேண்டியதில்லை.
  3. நீங்கள் ஒரு block வகையைச் சேர்க்கும்போதோ அல்லது ஒரு புலத்தின் பொருளை மாற்றும்போதோ UnifiedDocument-இல் schema_version-ஐ உயர்த்துங்கள், மேலும் consumers-ஐ version-இன் அடிப்படையில் கிளைபிரியக் கற்றுக்கொடுங்கள் (ஒருபோதும் extractor-இன் அடிப்படையில் அல்ல).

செய்யக்கூடாதவை

  1. if extractor == "docling" கிளைபிரிவை adapter எல்லையைத் தாண்டிக் கசிய விடாதீர்கள் — ஒரு UnifiedDocument உருவாகிவிட்டால், எந்த chunker, embedder அல்லது indexer-உம் எந்த backend அதை உருவாக்கியது என்பதை அறிந்திருக்கக் கூடாது.
  2. அறியப்படாத extractor உறுப்பு வகைகளை free-form dict blobs-இல் போட்டுவிடாதீர்கள்; அவற்றை மிக நெருக்கமான canonical BlockType-க்கு map செய்யுங்கள் (இயல்பாக PARAGRAPH), இதனால் discriminated union முழுமையாகவும் validation பொருள் உள்ளதாகவும் இருக்கும்.
  3. Provenance-ஐ optional ஆக்கவோ அல்லது sidecar log-இல் சேமிக்கவோ வேண்டாம் — normalization-க்குப் பிறகு quality-aware processing செயல்படுவதற்கான முழுக் காரணமே block-local provenance தான்.

3 hands-on labs come with this lesson — real code, in a cloud IDE. Create a free account to run them. No card.

Free account · no card · straight to the labs

Or get the full path — from

Listen to this lesson

Audio overviews of this lesson's labs and its chapter, from GenBodha Bytes.

More free lessons in GenAI Data Pipelines

All free lessons in GenAI Data Engineering →