Free lesson · GenAI Data Engineering

అన్ని extraction outputs‌ను సాధారణీకరించే ఏకీకృత document model‌ను రూపొందించండి

Typed content blocks మరియు extraction method metadata‌తో format-agnostic document schema‌ను సృష్టించండి. Docling, VLM, మరియు Document AI outputs కోసం adapters నిర్మించండి.

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

Free to read — no subscription required.

పరిచయం

Docling, Document AI, మరియు ఒక vision-language model నుండి డేటాను తీసుకునే ఇంజెషన్ పైప్‌లైన్‌ను మీరు నిర్మించినప్పుడు, ప్రతి బ్యాకెండ్ కంటెంట్‌ను తన సొంత ఆకారంలో తిరిగి ఇస్తుంది — ఇక్కడ bounding boxes, అక్కడ పేజీ హైరార్కీలు, మరోచోట ఫ్రీఫార్మ్ JSON — మరియు ప్రతి డౌన్‌స్ట్రీమ్ కన్స్యూమర్ చివరికి if extractor == "docling": … పై బ్రాంచ్ చేస్తూ ఉంటుంది, కోడ్‌బేస్ ఎక్స్‌ట్రాక్టర్ పేర్ల చుట్టూ శిలాజంగా మారేదాకా. ఏకీకృత డాక్యుమెంట్ మోడల్‌ను దాటవేసే టీమ్‌లు కొత్త ఎక్స్‌ట్రాక్టర్ వచ్చిన ప్రతిసారీ chunkers, embedders, మరియు search indexers ను తిరిగి రాయడంలో తర్వాతి క్వార్టర్‌ను గడుపుతాయి. ఈ పాఠం చివరికి, discriminated-union కంటెంట్ బ్లాక్‌లు, provenance మెటాడేటా, మరియు స్థిరమైన అడాప్టర్ సరిహద్దుతో ఒక canonical డాక్యుమెంట్ స్కీమాను రూపొందించగలరు, తద్వారా ఏ ఎక్స్‌ట్రాక్టర్ ఉత్పత్తి చేసినా డౌన్‌స్ట్రీమ్ సిస్టమ్‌లు ఒకే ఆకారాన్ని వినియోగిస్తాయి.

కీలక పదజాలం

  • ఏకీకృత డాక్యుమెంట్ మోడల్ (Unified document model): ప్రతి ఎక్స్‌ట్రాక్టర్ అడాప్టర్ లక్ష్యంగా పెట్టుకునే ఒకే canonical స్కీమా (ఇక్కడ, UnifiedDocument), తద్వారా డౌన్‌స్ట్రీమ్ chunkers, embedders, మరియు indexers ఎక్స్‌ట్రాక్టర్ పేరు మీద బ్రాంచ్ చేయకుండా ఒకే ఆకారాన్ని వినియోగిస్తాయి.
  • Discriminated union: ప్రతి వేరియంట్ ఒక literal block_type ట్యాగ్‌ను కలిగి ఉండే పాలిమార్ఫిక్ కంటెంట్-బ్లాక్ ప్రాతినిధ్యం (ఉదా. TableBlock పై Literal["table"]), దీన్ని Pydantic మిశ్రమ బ్లాక్‌ల జాబితాలను అస్పష్టత లేకుండా డీసీరియలైజ్ చేయడానికి ఉపయోగిస్తుంది.
  • Provenance మెటాడేటా: ఏ ఎక్స్‌ట్రాక్టర్ బ్లాక్‌ను ఉత్పత్తి చేసిందో (పేరు, వెర్షన్, పేజీ, bounding box, confidence, quality_flags) ప్రతి-బ్లాక్ స్థాయిలో ట్రాక్ చేయడం, బ్లాక్ మీదే ఉంచబడుతుంది, తద్వారా quality-aware ప్రాసెసింగ్ డౌన్‌స్ట్రీమ్‌లో ఫిల్టర్ చేయగలదు లేదా రీ-రూట్ చేయగలదు.
  • ఎక్స్‌ట్రాక్షన్ అడాప్టర్ (Extraction adapter): ఒక ఎక్స్‌ట్రాక్టర్ యొక్క నేటివ్ అవుట్‌పుట్‌ను UnifiedDocument లోకి అనువదించడమే ఏకైక పని అయిన వేరుచేయబడిన క్లాస్ (ఉదా. DoclingAdapter), ఇది ఇంజెషన్‌ను ఎక్స్‌ట్రాక్టర్ ఎంపిక నుండి విడదీసే స్థిరమైన సరిహద్దును ఏర్పరుస్తుంది.

భావనలు

ఈ పాఠం ఒకే డిజైన్‌గా కలిసిపోయే మూడు ఆలోచనలను బోధిస్తుంది.

ఒక canonical స్కీమా, అనేక అడాప్టర్లు. UnifiedDocument మోడల్ ప్రతి డౌన్‌స్ట్రీమ్ కన్స్యూమర్ ఆధారపడే ఒప్పందం; DoclingAdapter మరియు భవిష్యత్తులో వచ్చే ఏదైనా DocumentAIAdapter / VLMAdapter తమ బ్యాకెండ్ నేటివ్ అవుట్‌పుట్‌ను ఆ ఒప్పందంలోకి మ్యాప్ చేయడానికే ఉంటాయి. కొత్త ఎక్స్‌ట్రాక్టర్‌ను జోడించడం స్కీమాను లేదా ఏ కన్స్యూమర్‌ను ఎప్పుడూ మార్చదు — అది ఒక అడాప్టర్ క్లాస్‌ను జోడిస్తుంది, మరేమీ కాదు.

ఫ్రీ-ఫార్మ్ JSON కంటే discriminated unions. నిజమైన డాక్యుమెంట్లు పేరాగ్రాఫ్‌లు, హెడింగ్‌లు, టేబుల్‌లు, ఫిగర్‌లు, మరియు లిస్ట్‌లను కలుపుతాయి. ప్రతిదాన్ని literal block_type ట్యాగ్‌తో Pydantic మోడల్‌గా ఎన్‌కోడ్ చేయడం వలన list[ContentBlock | TableBlock] సరిగ్గా డీసీరియలైజ్ అవుతుంది, అదే సమయంలో TableBlock.headers లేదా ContentBlock.level వంటి వేరియంట్-నిర్దిష్ట ఫీల్డ్‌లకు టైప్ చేసిన యాక్సెస్ లభిస్తుంది. ఫ్రీ-ఫార్మ్ dicts అదే డేటాను ఇస్తాయి కానీ వాలిడేషన్ మరియు IDE మద్దతును కోల్పోతాయి.

Provenance ఒక ఫస్ట్-క్లాస్ ఫీల్డ్, సైడ్‌కార్ లాగ్ కాదు. ప్రతి బ్లాక్ తన సొంత Provenance (extractor, version, page, bbox, confidence, quality_flags) ను కలిగి ఉండటం వలన, డౌన్‌స్ట్రీమ్ కోడ్ ప్రతి-బ్లాక్ నిర్ణయాలు తీసుకోగలదు — తక్కువ-confidence VLM అవుట్‌పుట్‌ను తొలగించడం, ఫ్లాగ్ చేసిన బ్లాక్‌లను సమీక్ష కోసం రీ-రూట్ చేయడం, RAG జవాబులో citations ను ఆపాదించడం — బాహ్య మెటాడేటా స్టోర్‌కు తిరిగి join చేయకుండానే. కింద ఉన్న కోడ్ వాక్‌త్రూ ఈ మూడు ఆలోచనల్లో ప్రతిదీ స్కీమాలో ఎలా కనిపిస్తుందో మరియు DoclingAdapter వాటిని ఎలా ఉత్పత్తి చేస్తుందో ఖచ్చితంగా చూపిస్తుంది.

కోడ్ వాక్‌త్రూ

Pydantic స్కీమాను నిర్వచించడం

డాక్యుమెంట్ కంటెంట్ యొక్క పాలిమార్ఫిక్ స్వభావాన్ని నిర్వహించడానికి 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 మీ పైప్‌లైన్ నిర్వహించే అన్ని కంటెంట్ టైప్‌లను నిర్వచిస్తుంది. ఫ్రీ-ఫార్మ్ స్ట్రింగ్‌ల బదులు enum ను ఉపయోగించడం వాలిడేషన్ సమయంలో టైపోలను పట్టుకుంటుంది మరియు డౌన్‌స్ట్రీమ్ ప్రాసెసర్లలో సంపూర్ణ pattern matching ను సాధ్యం చేస్తుంది.
  • లైన్లు 14-20: Provenance మోడల్ ప్రతి బ్లాక్‌ను ఏ ఎక్స్‌ట్రాక్టర్ ఉత్పత్తి చేసిందో ట్రాక్ చేస్తుంది. quality_flags జాబితా ఎక్స్‌ట్రాక్షన్ సమయంలో గుర్తించిన సమస్యలను నమోదు చేస్తుంది — "low_confidence", "possible_hallucination", "truncated" — డౌన్‌స్ట్రీమ్‌లో quality-aware ప్రాసెసింగ్‌ను సాధ్యం చేస్తుంది.
  • లైన్లు 28-31: TableBlock block_type: Literal["table"] తో discriminated union నమూనాను ఉపయోగిస్తుంది, తద్వారా Pydantic మిశ్రమ కంటెంట్ బ్లాక్ జాబితాలను సరిగ్గా డీసీరియలైజ్ చేయగలదు. Headers మరియు rows row_span మరియు col_span ద్వారా విలీన సెల్‌లకు మద్దతు ఇచ్చే TableCell ఆబ్జెక్ట్‌లను ఉపయోగిస్తాయి.
  • లైన్లు 33-37: ContentBlock children ఫీల్డ్ ద్వారా పునరావృత నెస్టింగ్‌కు మద్దతు ఇస్తుంది, సెక్షన్లు సబ్‌సెక్షన్లను, అవి పేరాగ్రాఫ్‌లను కలిగి ఉండే నిజమైన డాక్యుమెంట్ల హైరార్కికల్ నిర్మాణాన్ని ప్రతిబింబిస్తుంది.
  • లైన్లు 43-52: టాప్-లెవల్ UnifiedDocument డాక్యుమెంట్-స్థాయి మెటాడేటాను, ప్రతి ఒక్కటి బ్లాక్‌లను కలిగి ఉండే పేజీల జాబితాను, మరియు పరిణామం కోసం schema_version ను సంగ్రహిస్తుంది.

ఎక్స్‌ట్రాక్షన్ అడాప్టర్లను నిర్మించడం

ప్రతి అడాప్టర్ ఎక్స్‌ట్రాక్టర్-నిర్దిష్ట అవుట్‌పుట్‌ను ఏకీకృత మోడల్‌లోకి రూపాంతరం చేస్తుంది:

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: ప్రతి అడాప్టర్ తన ఎక్స్‌ట్రాక్టర్ గుర్తింపును క్లాస్ కాన్‌స్టంట్‌లుగా ప్రకటిస్తుంది, ఈ అడాప్టర్ ప్రాసెస్ చేసే అన్ని డాక్యుమెంట్లలో స్థిరమైన provenance ట్రాకింగ్‌ను నిర్ధారిస్తుంది.
  • లైన్లు 14-23: కంటెంట్ బ్లాక్‌లను పేజీ నంబర్ ప్రకారం గ్రూప్ చేయండి. Docling యొక్క iterate_items() ఎలిమెంట్లను చదివే క్రమంలో ఇస్తుంది, కానీ పేజీ మార్పులను provenance మెటాడేటా నుండి గుర్తించాలి.
  • లైన్లు 25-31: Docling అవుట్‌పుట్ నుండి ఎక్స్‌ట్రాక్టర్ పేరు, వెర్షన్, పేజీ నంబర్, మరియు bounding box తో ప్రతి బ్లాక్‌కు Provenance ఆబ్జెక్ట్‌లను నిర్మించండి.
  • లైన్లు 33-52: Docling ఎలిమెంట్ టైప్‌లను ఏకీకృత మోడల్ బ్లాక్ టైప్‌లకు మ్యాప్ చేయండి. SectionHeaderItem తన level ను కాపాడుకుంటూ heading అవుతుంది. TableItem DataFrame గా ఎక్స్‌పోర్ట్ చేయబడి, ఆపై సరైన TableCell ఆబ్జెక్ట్‌లతో canonical TableBlock ఫార్మాట్‌లోకి మార్చబడుతుంది. మిగతా అన్ని ఎలిమెంట్లు డిఫాల్ట్‌గా పేరాగ్రాఫ్‌లు అవుతాయి.
  • లైన్లు 65-72: సోర్స్ URI నుండి ఉత్పన్నమైన నిర్ణాయక ID తో తుది UnifiedDocument ను నిర్మించండి, తద్వారా idempotent రీ-ఎక్స్‌ట్రాక్షన్ అదే డాక్యుమెంట్ ID ని ఉత్పత్తి చేస్తుందని నిర్ధారించబడుతుంది.

అడాప్టర్ నమూనా మీ పైప్‌లైన్‌ను ఏ ఒక్క ఎక్స్‌ట్రాక్షన్ బ్యాకెండ్ నుండీ విడదీస్తుంది. కొత్త ఎక్స్‌ట్రాక్టర్‌ను జోడించడానికి ఏ డౌన్‌స్ట్రీమ్ కన్స్యూమర్ కోడ్‌ను మార్చకుండా ఒక కొత్త అడాప్టర్ క్లాస్‌ను రాయడం మాత్రమే అవసరం.

Loading diagram...

విభాగ అనువర్తనం

చేయవలసినవి మరియు చేయకూడనివి

ఇప్పుడు మీరు అమలును పూర్తిగా చూశారు, కింద ఉన్న పద్ధతులు మన్నికైన విధానాన్ని బలహీనమైన విధానం నుండి వేరు చేస్తాయి.

చేయవలసినవి

  1. ప్రతి కంటెంట్-బ్లాక్ వేరియంట్‌ను Literal["..."] block_type తో ట్యాగ్ చేయండి, తద్వారా Pydantic మిశ్రమ list[ContentBlock | TableBlock] కంటెంట్‌ను అస్పష్టత లేకుండా డీసీరియలైజ్ చేయగలదు మరియు కన్స్యూమర్లు ట్యాగ్ మీద డిస్పాచ్ చేయగలరు.
  2. ప్రతి బ్లాక్ మీద Provenance ను తప్పనిసరి చేయండి — ఎక్స్‌ట్రాక్టర్ పేరు, వెర్షన్, పేజీ నంబర్, అందుబాటులో ఉన్నచోట bbox, మరియు quality_flags — తద్వారా డౌన్‌స్ట్రీమ్ రీ-ర్యాంకింగ్, డీబగ్గింగ్, మరియు citation మార్గాలు బాహ్య మెటాడేటా స్టోర్‌కు తిరిగి join చేయవలసిన అవసరం ఎప్పుడూ ఉండదు.
  3. మీరు బ్లాక్ టైప్‌ను జోడించినప్పుడు లేదా ఫీల్డ్ అర్థాన్ని మార్చినప్పుడు UnifiedDocument పై schema_version ను పెంచండి, మరియు కన్స్యూమర్లు వెర్షన్ మీద బ్రాంచ్ చేయాలని (ఎక్స్‌ట్రాక్టర్ మీద ఎప్పుడూ కాదు) నేర్పండి.

చేయకూడనివి

  1. if extractor == "docling" బ్రాంచింగ్ అడాప్టర్ సరిహద్దును దాటి లీక్ అవ్వనివ్వకండి — ఒకసారి UnifiedDocument ఏర్పడిన తర్వాత, ఏ chunker, embedder, లేదా indexer కూడా ఏ బ్యాకెండ్ దాన్ని ఉత్పత్తి చేసిందో తెలుసుకోవాల్సిన అవసరం ఉండకూడదు.
  2. తెలియని ఎక్స్‌ట్రాక్టర్ ఎలిమెంట్ టైప్‌లను ఫ్రీ-ఫార్మ్ dict బ్లాబ్‌లలోకి వదిలేయకండి; వాటిని అత్యంత సమీపమైన canonical BlockType కు మ్యాప్ చేయండి (డిఫాల్ట్‌గా PARAGRAPH), తద్వారా discriminated union సంపూర్ణంగా ఉంటుంది మరియు వాలిడేషన్ అర్థవంతంగా ఉంటుంది.
  3. Provenance ను ఐచ్ఛికంగా చేయకండి లేదా సైడ్‌కార్ లాగ్‌లో నిల్వ చేయకండి — నార్మలైజేషన్ తర్వాత quality-aware ప్రాసెసింగ్ పనిచేయడానికి బ్లాక్-స్థానిక 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 →