Retrieve One Row from a Table, Not the Whole Table: Row-Level Chunks for RAG
Naive RAG retrieval treats entire tables as single chunks, forcing generation models to filter irrelevant rows instead of retrieving only the relevant row The article introduces a row-level serialization approach where each table row becomes an independent retrievable chunk Tables are parsed using Docling or Azure Document Intelligence, which emit markdown-pipe formatted lines that can be detected without per-parser branching The `serialize_table_rows` function groups contiguous pipe rows, ident
Analysis
TL;DR
- Naive RAG retrieval treats entire tables as single chunks, forcing generation models to filter irrelevant rows instead of retrieving only the relevant row
- The article introduces a row-level serialization approach where each table row becomes an independent retrievable chunk
- Tables are parsed using Docling or Azure Document Intelligence, which emit markdown-pipe formatted lines that can be detected without per-parser branching
- The
serialize_table_rowsfunction groups contiguous pipe rows, identifies headers and separators, and emits one output chunk per body row with column headers and cell values - Both table-level and row-level retrieval scales are made available, letting the dispatcher choose the appropriate granularity based on the query
Why It Matters
This addresses a critical gap in enterprise RAG systems where structured data in tables is commonly mishandled by naive chunking strategies. For AI practitioners building document intelligence pipelines, this approach enables precise row-level retrieval without requiring complex table-aware embeddings or model modifications.
Technical Details
- Parsing contract: Docling and Azure Document Intelligence emit tables as markdown-pipe lines inside
line_df, with header rows, separator rows (dashes/colons), and body rows in reading order - Detection rules: Four simple rules identify table structure—pipe-delimited rows, separator rows marking header/body split, contiguous pipe rows belonging to the same table, and non-pipe lines resetting the group
- Serialization function:
serialize_table_rowstakes apandas.DataFrameinput, groups pipe lines into tables, extracts headers from the row above the separator, handles multi-row headers viafold_multirow_header, and outputs one chunk per body row with fields:table_id,page_num,line_num,column_headers,row_cells, androw_serialized - Output format: Each serialized row contains key-value pairs like
"column_name: cell_value"joined by pipes, maintaining the same DataFrame shape as the existing retriever brick for composability - Demo: Uses Table 1 from "Attention Is All You Need" (4 rows, 4 columns) with runnable code on GitHub at
doc-intel/notebooks-vol1
Industry Insight
- Enterprise RAG systems should implement dual-scale retrieval (table-level and row-level) rather than committing to a single chunking granularity, as different queries require different levels of aggregation
- The lightweight pipe-format detection approach avoids parser-specific branching, making it portable across Document Intelligence providers and reducing maintenance overhead
- This row-level serialization pattern is immediately applicable to insurance policies, financial reports, and any domain where structured tables contain answerable facts at the row level
Disclaimer: The above content is generated by AI and is for reference only.