RAG Pipeline for PDF: A Revolution in Document Analysis

Le brief IA que les pros lisent chaque soir
Les 7 actus IA du jour, décryptées en 5 min. Gratuit.
Inclus dès l'inscription : notre sélection des meilleurs guides & comparatifs IA.
Choisis ton rythme
Gratuit · Pas de spam · Désabonnement en 1 clic
RAG Pipeline for PDF: A Revolution in Document Analysis
Large Language Models
A production RAG pipeline for PDFs: relational parsing, table of contents (TOC) retrieval, typed responses.
This document is part of the Enterprise Document Intelligence series, which builds an enterprise RAG system from four components: document parsing, question parsing, retrieval, and generation.
This is the first of two parts on the enhanced pipeline: this part improves each component, one contract at a time, on the same document and the same question as Article 1 (minimal RAG). The second part, which will compose the four RAG components into a single pipeline, will be tested on real documents.
Where This Article Fits in the Series
This article is Article 9 (the enhanced pipeline), opening Part III.
Executable notebooks are available on GitHub: doc-intel/notebooks-vol1.
A public companion code is also available at doc-intel/notebooks-vol1.
How the Pipeline Works
About a hundred lines of Python connect four functions: parse the PDF, parse the question, retrieve a few pages, query a model.
This pipeline returns the correct answer to a clear question about a document with an integrated table of contents. However, it fails when the first input question contains typos, such as "positonal encodig," or when the document is a 200-page contract without a PDF outline. Four components need to be upgraded before the pipeline is operational.
-
Document parsing: returns more than just a flat line; a relational set including a TOC, page-level metadata, and a typed parsing_summary carrying the document type, language, and a one-paragraph summary.
-
Question parsing: transforms noisy user input into a structured brief, with corrected keywords according to the corpus vocabulary and an inferred response form (single value, list, table).
-
Retrieval: reads the TOC as an expert would: provides the complete TOC to a small LLM that selects sections by semantic relevance, then merges with key pages.
-
Generation: returns a typed response with a citation excerpt for each item, plus four contextual quality indicators that the pipeline reads to decide whether to send the response or make another pass.
The document in question is a public submission of 15 pages on arXiv, Attention Is All You Need. The question "What are the options for positional encoding?" comes with two typos, which gives work to the question parsing component. The output is what a business user needs: a typed response, with verbatim citations linked to line ranges, and complete traceability from the question to the citation.
1. Where the Basic RAG Fails
Ask a clear question about a clear PDF, run it through the simplest RAG pipeline: parse the PDF, extract keywords from the question, retrieve a few pages, query an LLM. On the Attention document with the question "What are the options for positional encoding?", this pipeline returns "sinusoidal positional encoding and learned positional embeddings" with a continuous page range cited. This worked, on a clear question, on a clear document.
Drop the same pipeline into an enterprise environment, and four weaknesses quickly emerge, one for each component:
-
Document parsing: the document is flattened. Article 1 (minimal RAG) analyzed the PDF into a flat list of lines, sufficient for counting keywords but nothing more. Pages, sections, tables, all the structure that a downstream component could exploit, is lost at the first step.
-
Question parsing: the question entered by users is rarely clear. "What are the optoins for posiitional encoding?" contains two typos. The basic keyword extractor has never seen the word "positional"; it has seen "posiitional," so retrieval misses the pages where the answer is located.
-
Retrieval: the base never looks at structure. The Attention document has a clean integrated TOC, with named sections and page numbers, three levels deep. The most precise retrieval signal in the entire document is ignored.
-
Generation: the response comes back as a raw string. A list question (options) asks for one item per option, each with its own proof. Free prose forces the caller to re-analyze the response to find the items; a typed schema with a proof range per item eliminates this step.
The four components below address these four weaknesses. Same document, same question, real LLM calls. The output is a typed list with verbatim citations, line ranges, and the complete chain of decisions that produced it.
2. Four Components, Upgraded
The form that survives the upgrade is the same as the four components introduced in Article 1 (minimal RAG). What changes is the contract per component: what each consumes, what it produces, and how the next one exploits it. The diagram below presents the complete contract: each component, the outputs it produces, and which downstream component consumes each (including the lateral channel parsing_summary in both question parsing and generation). The subsections per component then zoom in on each box.
Each of the four components is upgraded in its own articles, to be read for the complete contract:
-
Document parsing: Article 5A (what to read in a PDF) and Article 5B (the relational data model).
-
Question parsing: Article 6A (the thesis), Article 6B (extraction), and Article 6C (dispatch).
-
Retrieval: Article 7A (retrieval as filtering), Article 7B (anchor detection), and Article 7C (the LLM arbiter).
-
Generation: the response contract, prompt assembly, and validation (Articles 8A to 8C, links forthcoming).
2.1 Document Parsing: A Small Relational Set
The parsing runs once and transforms the PDF into a small set of tables that each subsequent component reuses.
- Input: pdf_path, the PDF on disk.
- Output: line_df, page_df, toc_df, parsing_summary.
The document parsing: parse_pdf reads the PDF once and returns the small relational set that each downstream component reuses.
What comes out, one line per unit:
-
line_df: one line per visible line (page_num, line_num, text, bounding box). The citation unit.
-
page_df: one line per page (page_num, text). The rough scan surface.
-
toc_df: one line per section (title, level, start_page). The clean map of the document.
-
parsing_summary: document-level metadata (doc type, language, number of pages, layout). The lateral channel to the LLM components.
Article 1 (minimal RAG) analyzed the PDF into a DataFrame called line_df, one line per line of visible text. Sufficient for keyword retrieval, but not for anything else. Article 5 (document parsing) reframes the parsing as building a small relational set: line_df remains, page_df aggregates lines by pages with their text, and toc_df carries the document's native table of contents.
The starting piece at the top of the article has already produced the three DataFrames on the Attention document. An overview of each:
-
One line per visible line, with page_num and line_num for citations.
-
The same lines, redrawn on the page: each blue box is a line_df, the gutter number is its line_num.
-
Aggregating lines page by page gives page_df, the natural page unit that carries the entire page text and context at the page level.
-
toc_df carries the native outline; on the Attention document, it has three levels and twenty-two entries, one line per section with its title, level, and starting page.
Three tables, same form contract, same numeric primary keys. The downstream components read what they need without re-analyzing the PDF; Retrieval (Section 2.3) scans keyword hits and reads toc_df to anchor on the right section, then sizes the context around it (the entire section, or a line window) to the granularity the question implies. page_df is the scanning unit at the page level, toc_df the map, line_df the atomic lines from which the anchor and window are cut. parse_pdf actually returns more in the same dictionary (image regions, internal references, named objects) plus a parsing_summary carrying document-level metadata (doc type, language, number of pages, layout, typical fields, a short summary); this section focuses on the three tables that retrieval reads, and parsing_summary will be returned in the second part as the lateral channel that travels to the LLM components.
2.2 Question Parsing: From Noise to Brief
The question parsing transforms the raw user string into a typed brief on which the next two components can act.
- Input: the raw question, the concept_keywords_df from the expert, and parsing_summary for document context.
- Output: a ParsedQuestion carrying intent, keywords, a brief RetrievalQuery, and a GenerationBrief.
The question parsing: an LLM call corrects typos and extracts keywords, then concept_keywords_df expands them.
-
keywords: corrected typos and extracted content terms in a single LLM call, then expanded with expert vocabulary.
-
intent: the form of response that the question implies (factual, list, comparison).
-
RetrievalQuery: the brief that retrieval consumes (main_query, rewrites, anchor_keywords, section_hint, layout_hint).
-
GenerationBrief: only the fields on which generation can act (the question, the form of response, disambiguation).
Article 1 (minimal RAG) called get_keywords_from_question on the clear question and obtained a corrected_question plus a short list of keywords in a single LLM call. This single call performs two tasks at once: it corrects typos and extracts keywords.
Brief IA — L'actualité IA en français
L'essentiel de l'actualité de l'intelligence artificielle, décrypté et expliqué chaque jour.