PDF RAG: recovering document structure and querying a corpus

Page-by-page parsing destroys the structure a reader relies on. This post rebuilds it for PDFs with a vision language model, extracts metadata and a document tree, and then queries a corpus of reports and slide decks with a two-level ReAct agent.
deep learning
LLM
RAG
Author

Nicolas Brosse

Published

March 20, 2025

Modified

August 22, 2026

A PDF is parsed page by page, and that is where the trouble starts. Someone opening a two-hundred-page report looks at the table of contents first, forms a picture of how the document is organised, and only then jumps to the section that matters. A page-by-page parser never builds that picture. It returns a sequence of local views whose heading levels reflect the font sizes that happened to appear on each page rather than the hierarchy of the document, and the usual remedy — chunk the text, embed the chunks, retrieve by similarity — searches those fragments without ever knowing where they sit in the whole. The difficulty is that a machine has to be given, explicitly and at some cost, the overview a human gets for free from a contents page.

The code accompanying this post attacks that gap in two stages. Section 1 converts PDFs to Markdown with a vision language model, reformats the result to restore a usable heading hierarchy, extracts metadata and a table of contents, and parses all of it into a document tree. Section 2 then builds a question-answering system over the same corpus: one ReAct agent per document, and a top-level agent that routes questions to them. The two stages are, for now, independent. The tree index of Section 1.4.2 is an unfinished draft that cannot be queried, so the retrieval side falls back on ordinary vector search.

Everything is built on llama-index, which is versatile but moves fast and breaks often; the code is a snapshot of an API that has since changed.

Some resources for this post:

All paths below are relative to the pdf-rag repo. The running corpus is the six PDFs shipped with it: three portrait reports of 2, 17 and 32 pages, and three landscape decks of 15, 17 and 62 slides.

PDF metadata and structure extraction

Four steps run in sequence, orchestrated by the ingestion pipeline of Section 1.5. The PDF is converted to Markdown by a vision language model (Section 1.1); that raw Markdown is reformatted to restore a coherent heading hierarchy (Section 1.2); metadata is extracted from the reformatted text — author, date, language, table of contents (Section 1.3); and the result is parsed into a tree that can be traversed (Section 1.4).

From PDF to Markdown

The companion post Parsing PDFs for LLM input compares the available conversion methods. For RAG the choice here is a vision language model: more expensive than text extraction, but it describes figures and reads tables, and unlike a hosted service such as LlamaParse it leaves the model, the provider and the prompt under your control.

VLMPDFReader (src/pdf_rag/readers.py) implements it. Each page is split off into a one-page PDF with pypdf and sent as raw PDF bytes to Gemini 2.0 Flash along with the transcription prompt below. Pages are transcribed concurrently, four at a time by default, and the results are joined with --- end page N markers; those markers are the only trace of pagination that survives into the Markdown, and most of what follows depends on them. The transcription is written to <cache_dir>/<relative_path>.md, so re-running the pipeline over a corpus already processed costs nothing.

Two details in the reader matter downstream. The first is the format flag: the reader compares the width and the height of the first page’s media box and labels the document landscape or portrait. That single bit decides how the document will be reformatted, how its table of contents will be built, and how it will eventually be parsed into a tree. The second is the fallback to Mistral, which exists because of a specific Gemini failure mode.

When Gemini ends a response with the finish reason RECITATION, it has detected that what it was generating reproduces its training data too closely — a guard against emitting copyrighted material verbatim. Faithful transcription of a published report is, by construction, exactly that, so the error fires unpredictably and truncates the page mid-stream. On that finish reason the reader renders the page to a PNG and sends it to pixtral-large-latest instead, whose transcription replaces Gemini’s; any other unexpected finish reason raises. Server errors from either API are retried by tenacity, ten attempts spaced five seconds apart.

reader = VLMPDFReader(
    cache_dir="./cache",
    api_key_gemini="your_gemini_key",  # or use env var GEMINI_API_KEY
    api_key_mistral="your_mistral_key"  # or use env var MISTRAL_API_KEY
)

# Single file
doc = reader.load_data("path/to/document.pdf")

# Multiple files
docs = reader.load_data(["doc1.pdf", "doc2.pdf"])

Here is the transcription prompt sent with every page.

Click to view template
You are a specialized document transcription assistant converting PDF documents to Markdown format.
Your primary goal is to create an accurate, complete, and well-structured Markdown representation.

<instructions>
1. Language and Content:
   - MAINTAIN the original document language throughout ALL content
   - ALL elements (headings, tables, descriptions) must use source language
   - Preserve language-specific formatting and punctuation
   - Do NOT translate any content

2. Text Content:
   - Convert all text to proper Markdown syntax
   - Use appropriate heading levels (# ## ###)
   - Preserve emphasis (bold, italic, underline)
   - Convert bullet points to Markdown lists (-, *, +)
   - Maintain original document structure and hierarchy

3. Visual Elements (CRITICAL):
   a. Tables:
      - MUST represent ALL data cells accurately in original language
      - Use proper Markdown table syntax |---|
      - Include header rows
      - Add caption above table: [Table X: Description] in document language

   b. Charts/Graphs:
      - Create detailed tabular representation of ALL data points
      - Include X/Y axis labels and units in original language
      - List ALL data series names as written
      - Add caption: [Graph X: Description] in document language

   c. Images/Figures:
      - Format as: ![Figure X: Detailed description](image_reference)
      - Describe key visual elements in original language
      - Include measurements/scales if present
      - Note any text or labels within images

4. Quality Requirements:
   - NO content may be omitted
   - Verify all numerical values are preserved
   - Double-check table column/row counts match original
   - Ensure all labels and legends are included
   - Maintain document language consistently throughout

5. Structure Check:
   - Begin each section with clear heading
   - Use consistent list formatting
   - Add blank lines between elements
   - Preserve original content order
   - Verify language consistency across sections
</instructions>

Figure 1 shows what comes back.

Raw conversion from PDF to Markdown using VLM
Figure 1: Raw conversion from PDF to Markdown using a VLM

PDFDirectoryReader, in the same module, wraps the reader for whole directories. It walks a root directory for PDFs, refuses inputs that fall outside it, and attaches file metadata to each document — path, name, type, size, creation and modification dates, path relative to the root, and the cache directory. The last two are not bookkeeping: later stages read them off the node to locate their own cache files.

reader = PDFDirectoryReader(
    root_dir="./documents",
    cache_dir="./cache",
    num_workers=4,
    show_progress=True
)

# Process single PDF file
docs = reader.load_data("documents/sample.pdf")

# Process directory of PDFs
docs = reader.load_data("documents/reports/")

# Async processing
docs = await reader.aload_data("documents/reports/")

What the raw conversion does not give is structure. Every page is transcribed in isolation, so its heading levels are chosen from the appearance of that page alone, and the resulting Markdown hierarchy rarely matches the document’s own. Headings land at the wrong depth, a running title becomes an # on every page it appears, and splitting the file on headings therefore produces sections that do not correspond to sections of the report.

Reformatting the Markdown

ReformatMarkdownComponent (src/pdf_rag/transforms.py) sends the raw transcription back to Gemini, this time as an editing task: keep every word, fix the hierarchy. Despite the appearance of a chunked process, the document is never split. Each round re-sends the whole document together with everything reformatted so far and asks the model to carry on from there; the loop ends when the model emits <end> and gives up with a RuntimeError after max_iters rounds, fifty by default. The constraint being worked around is the output limit, not the context window, which is why a model with a large context makes this practical at all. As with the reader, the result is cached, in a .reformatted.md file beside the raw transcription, and the node is marked as reformatted so a second pass is a no-op.

component = ReformatMarkdownComponent(
    api_key="your_gemini_key",  # or use env var GEMINI_API_KEY
    num_workers=4,
    show_progress=True
)

# Process nodes
processed_nodes = component(nodes)

# Async processing
processed_nodes = await component.acall(nodes)

Slides and reports need different handling here. A deck is already page-structured — each slide is a self-contained unit, and the --- end page N markers are what preserves that — whereas a report’s structure lives in its nested headings, where page breaks are noise. The prompt therefore carries a conditional:

{% if landscape %}
- Preserve `--- end page N` markers
{% endif %}

Whether the markers actually survive is worth checking, since the table of contents extraction and the landscape parser both depend on them. Across the six cached documents, the three landscape decks come back with exactly one marker per page: 15, 17 and 62. The portrait documents, where the prompt says nothing about markers, are erratic. The 17-page datasheet keeps all seventeen, the two-page report loses both, and the 32-page open-data report comes back with 84 — the model produced markers that were never in its input. Portrait documents are parsed by heading rather than by page, so none of this breaks the pipeline, but it is a useful reminder of how loosely an instruction like “preserve all original content” is honoured.

Figure 2 shows the effect on the heading structure, which is the point of the exercise.

Markdown reformatting using LLM
Figure 2: Markdown reformatting using an LLM
Click to view template prompt for Gemini
<document>
{{ document }}
</document>

{% if processed %}
<processed>
{{ processed }}
</processed>
{% endif %}

You are a professional technical documentation editor specializing in markdown documents.
Your task is to transform the document into a well-structured markdown document with clear hierarchy and organization.

<instructions>
1. Content Preservation (CRITICAL):
    - PRESERVE ALL original content without exception
    - Do not summarize or condense any information
    - Maintain all technical details, examples, and code snippets
    - Keep all original links, references, and citations
    - Preserve all numerical data and specifications
    {% if landscape %}
    - Preserve `--- end page N` markers
    {% endif %}

2. Document Structure:
    - Ensure exactly one H1 (#) title at the start
    - Use maximum 3 levels of headers (H1 -> H2 -> H3)
    - Avoid excessive nesting - prefer flatter structure
    - Group related sections under appropriate headers
    - If an existing TOC is present, maintain and update it
    - Only create new TOC if none exists

3. Formatting Standards:
    - Use consistent bullet points/numbering
    - Format code blocks with appropriate language tags
    - Properly format links and references
    - Use tables where data is tabular
    - Include blank lines between sections

4. Quality Checks:
    - Compare final document with original for completeness
    - Verify all technical information is preserved
    - Ensure all examples remain intact
    - Maintain all nuances and specific details

5. Metadata & Front Matter:
    - Include creation/update dates if present
    - Preserve author information
    - Maintain any existing tags/categories
</instructions>

{% if processed %}
Please continue reformatting from where it was left off, maintaining consistency with the processed portion.
Ensure NO content is omitted - preserve everything from the original document.
All sections should seamlessly integrate with the existing structure.
End your response with <end>.
{% else %}
Provide the complete reformatted document following the above guidelines.
WARNING: Do not omit ANY content - preserve everything from the original document.
Ensure all sections are properly nested and formatted.
End your response with <end>.
{% endif %}

Metadata extraction

With a reformatted document in hand, the next step is to pull out what describes it: author, date and language, a table of contents, a page-by-page listing for decks, and finally a structure string that the parsers of Section 1.4 turn into a tree. The extractors live in src/pdf_rag/extractors.py and share GeminiBaseExtractor, which validates the API key, holds the model name (gemini-2.0-flash) and a temperature of 0.1, and runs the per-document jobs concurrently. Each extractor writes its result into the node’s metadata, and each one branches on the portrait/landscape flag set by the reader.

ContextExtractor

The first extractor asks for one JSON object describing the document: author, publication date, language as an ISO 639-1 code, document type, themes, entities, time periods, keywords and a summary. The response is pulled out of its JSON code fence and parsed; anything else raises. On the two-page Deloitte report it returns Deloitte, 2023-01-01, en, Report, nine keywords (“systemic risk”, “banking”, “BaaS”, “stablecoins”, “API”…) and a two-sentence summary of the risks the report covers — all of it surfaced later by the Shiny app of Section 1.5.

Click to view template prompt for Gemini
<document>
{{ document }}
</document>

Please analyze the above document and provide output in the following JSON format:

{
    "author": "detected_author",
    "publication_date": "YYYY-MM-DD",
    "language": "detected_language in ISO 639-1 language code format",
    "document_type": "type_if_identifiable"
    "themes": [
        {
            "name": "Theme name",
            "description": "Brief explanation"
        }
    ],
    "entities": [
            {
                "name": "Entity name",
                "role": "Role/significance"
            }
    ],
    "time_periods": [
        {
            "start_date": "YYYY-MM-DD",
            "end_date": "YYYY-MM-DD",
            "period_description": "Description of events/developments in this timeframe",
            "is_approximate": boolean,
        }
    ],
    "keywords": [
        "keyword1",
        "keyword2"
    ],
    "summary": "Concise summary text focusing on main points"
}

Note: Keep descriptions concise and factual.
If an item is missing, answer with "".
Answer in the language of the document.

TableOfContentsExtractor

This one looks for a table of contents that already exists in the document. It truncates the text at the --- end page N marker for page head_pages (ten by default) and asks Gemini to return the contents page it finds there, or exactly <none>, which is normalised to an empty string. For a deck the prompt also asks which slide the table of contents was found on. The truncation inherits the marker fragility described above, so when the marker is absent it falls back to a line budget — head_pages times an assumed hundred lines per page — rather than silently sending the whole document.

Click to view template prompt for Gemini
<doc>
{{ doc }}
</doc>

{% if format == 'landscape' %}
Extract the table of contents (TOC) from the document if present and specify the page number where the table of contents is located.
The table of contents, if it exists, is located on a single page.
Note that each page in the document ends with a marker '--- end page n' where n is the page number.

Output format:
- If a table of contents exists:
  First line: "Table of contents found on page X"
  Following lines: Complete TOC with its original structure and hierarchy
- If no table of contents exists: Respond with exactly "<none>"
{% else %}
Extract the table of contents (TOC) from the document if it exists.
IMPORTANT: the table of contents must be contained in consecutive lines in the source document itself.

Output format:
- If a table of contents exists: complete TOC with its original structure and hierarchy
- If no table of contents exists: Respond with exactly "<none>"
{% endif %}

TableOfContentsCreator

When there is no contents page, one has to be built, and the two formats are handled by completely different mechanisms. For a portrait report no model is involved at all: a regular expression collects every Markdown heading with the line at which it occurs, producing entries such as ## Pushing through undercurrents [line 2], and prepends a root entry named after the file if the first heading is not at line 0. Headings inside fenced code blocks are skipped, and the extractor refuses to run on a document that has not been reformatted — the line numbers are only meaningful against the reformatted text. For a landscape deck, Gemini drafts a table of contents from the page markers and a second call re-emits it in a normalised form, rejecting duplicate titles and duplicate or non-ascending page numbers.

That second pass is a formatting check rather than a semantic one, and on real decks the draft is often too fine-grained to survive as a table of contents: on the 15-slide life sciences deck it returns fifteen entries, one per slide, each slide title promoted to a top-level section. What recovers the seven actual sections is the grouping step below.

Click to view draft template prompt for Gemini
<doc>
{{ doc }}
</doc>

Generate a hierarchical table of contents for the slides deck above by:

1. IDENTIFY SECTION BREAKS
- Section breaks are marked by "--- end page {n}" where n is the page number

2. EXTRACT SECTION INFO
- Get the title text from each section break page
- Record the corresponding page number
- Validate that page numbers are unique and ascending

3. FORMAT OUTPUT
Format each entry as:
# {Section Title} (Page {n})

Example output:
# Introduction (Page 1)
# Key Concepts (Page 5)
# Implementation (Page 12)

Requirements:
- Page numbers must be unique and sequential
- Ignore any formatting in the section titles

The TOC should help readers quickly navigate the main sections of the deck.
Click to view check template prompt for Gemini
<toc>
{{ toc }}
</toc>

Generate a standardized table of contents following these rules:

1. FORMAT REQUIREMENTS
- Each entry: "# {Title} (Page {n})"
- Page numbers must be integers in parentheses
- One entry per line, no blank lines
- Preserve original markdown formatting in titles
- Page numbers ascending order

2. VALIDATION
- Reject duplicate page numbers
- Reject duplicate titles
- Page numbers must exist and be > 0
- Title cannot be empty

Example valid output:
# Executive Summary (Page 1)
# Market Analysis (Page 3)
# Financial Projections (Page 7)

LandscapePagesExtractor

For decks only — it returns an empty string for portrait documents — this extractor lists every page as Page N : title, using the table of contents (the extracted one if there is one, the created one otherwise) as a reference and carrying the previous title forward for slides that have none of their own. Without a table of contents it raises rather than guessing.

Click to view template prompt for Gemini
<doc>
{{ doc }}
</doc>

<toc>
{{ toc }}
</toc>

Extract and list all pages from the slides deck in <doc>, using the table of contents in <toc> as reference.

Rules:
1. Format each line exactly as: Page N : [title]
2. List pages in ascending numerical order (1, 2, 3...)
3. When a page has no title, use the title from its preceding page
4. Include all pages, even those without content

Example:
Page 1 : Introduction
Page 2 : Market Analysis
Page 3 : Market Analysis
Page 4 : Key Findings

StructureExtractor

The last extractor produces the structure string that the parsers consume. For a portrait report it is a pure pass-through: the created table of contents, headings with line numbers, is already the structure, and no model is called. A genuine contents page extracted from the document is kept in the metadata but plays no part here, even when it exists. For a landscape deck, Gemini is asked to group the page listing under the table of contents sections, which is where the one-entry-per-slide draft collapses back into real sections.

Click to view template prompt for Gemini
<toc>
{{ toc }}
</toc>

<pages>
{{ pages }}
</pages>

Analyze the table of contents (TOC) in <toc> and the pages of the slides deck provided in <pages>.
Group the pages under their corresponding TOC sections using this format:

# [TOC Section]
- Page X : [Full Page Title]
- Page Y : [Full Page Title]

Rules:
- Each TOC section should have an appropriate level heading with #, ##, or ###.
- List all pages that belong under each section
- Maintain original page numbers and full titles
- Include pages even if their titles are slightly different from TOC entries
- Group subsections under their main section
- List pages in numerical order within each section
- Don't omit any pages
- If a page doesn't clearly fit under a TOC section, place it under "Other Pages"

Example:
# Introduction
- Page 1 : Welcome Slide
- Page 2 : Project Overview

# Key Findings
- Page 3 : Financial Results
- Page 4 : Market Analysis

Every extractor is asynchronous and processes documents concurrently.

# Initialize extractor
extractor = TableOfContentsExtractor(
    api_key="your_gemini_key",  # or use env var GEMINI_API_KEY
    head_pages=10,
    temperature=0.1
)

# Process nodes
results = await extractor.aextract(nodes)

Parsing the structure

The extractors leave a structure string on every document. This section turns it into a tree and describes the index built on top of it.

From structure string to tree

The string comes in two shapes. A portrait report is a hierarchy of Markdown headings, each carrying the line at which it starts, which is what makes it possible to jump from a node back to the text it covers.

Listing 1: Portrait structure example
# Deloitte. [line 0]
## Pushing through undercurrents [line 2]
### Technology's impact on systemic risk: A look at banking [line 3]
### Risk 1: Risk exposure from Banking as a Service offerings [line 15]
#### Table 1: Risk exposure from Banking as a Service offerings [line 29]
### Risk 2: Inadequate stability mechanisms for stablecoin arrangements [line 38]
#### Table 1: Information about forces that could amplify the risk and how the industry mitigate it? [line 52]
### Contacts [line 63]

A landscape deck is a flat list of sections, each followed by the pages that belong to it. The hierarchy is shallow — sections and pages, essentially — and the addressing is by page number rather than by line.

Listing 2: Landscape structure example
# Everest Group® Life Sciences Smart Manufacturing Services PEAK Matrix® Assessment 2023
- Page 1 : Everest Group® Life Sciences Smart Manufacturing Services PEAK Matrix® Assessment 2023

# Introduction
- Page 2 : Introduction

# Life Sciences Smart Manufacturing Services PEAK Matrix® Assessment 2023
- Page 3 : Life Sciences Smart Manufacturing Services PEAK Matrix® Assessment 2023
- Page 4 : Life Sciences Smart Manufacturing Services PEAK Matrix® Assessment 2023
- Page 12 : Life Sciences Smart Manufacturing Services PEAK Matrix® Assessment 2023
- Page 13 : Life Sciences Smart Manufacturing Services PEAK Matrix® Assessment 2023

# Deloitte profile
- Page 5 : Deloitte profile (page 1 of 6)
- Page 6 : Deloitte profile (page 2 of 6)
- Page 7 : Deloitte profile (page 3 of 6)
- Page 8 : Deloitte profile (page 4 of 6)
- Page 9 : Deloitte profile (page 5 of 6)
- Page 10 : Deloitte profile (page 6 of 6)

# Appendix
- Page 11 : Appendix

# FAQs
- Page 14 : FAQs

# Everest Group®
- Page 15 : Everest Group®

The trade-off between the two is a trade-off between the documents themselves. A report gives fine-grained access to nested sections and, through line numbers, to the exact span of text under a heading; a deck gives direct access to a slide, which is the unit a reader of a deck actually wants.

parse_portrait_structure and parse_landscape_structure (src/pdf_rag/structure_parsers.py) turn either shape into a TreeNode tree, walking the lines with a stack of open sections and popping back whenever a heading of equal or higher level appears. Each node carries a number: a line number for reports, a page number for slides, and a negative number for the abstract nodes that represent section headings, with -1 reserved for the document root.

The two parsers differ in how much they distrust their input. The portrait parser asserts that the first heading sits at line 0 and that line numbers never decrease — a cheap check that the created table of contents is consistent with the text it was derived from. The landscape parser has more to guard against, because its input was written by a model rather than by a regular expression: a page listed twice is skipped with a warning, a page number beyond the document’s page count is skipped as well, and any page the model never mentioned is collected under an Uncategorized node so that no slide silently disappears from the tree.

Listing 3: Landscape structure parsed
life-sciences-smart-manufacturing-services-peak-matrix-assessment-2023 [-1]
  Everest Group® Life Sciences Smart Manufacturing Services PEAK Matrix® Assessment 2023 [-2]
    Everest Group® Life Sciences Smart Manufacturing Services PEAK Matrix® Assessment 2023 [1]
  Introduction [-3]
    Introduction [2]
  Life Sciences Smart Manufacturing Services PEAK Matrix® Assessment 2023 [-4]
    Life Sciences Smart Manufacturing Services PEAK Matrix® Assessment 2023 [3]
    Life Sciences Smart Manufacturing Services PEAK Matrix® Assessment 2023 [4]
    Life Sciences Smart Manufacturing Services PEAK Matrix® Assessment 2023 [12]
    Life Sciences Smart Manufacturing Services PEAK Matrix® Assessment 2023 [13]
  Deloitte profile [-5]
    Deloitte profile (page 1 of 6) [5]
    Deloitte profile (page 2 of 6) [6]
    Deloitte profile (page 3 of 6) [7]
    Deloitte profile (page 4 of 6) [8]
    Deloitte profile (page 5 of 6) [9]
    Deloitte profile (page 6 of 6) [10]
  Appendix [-6]
    Appendix [11]
  FAQs [-7]
    FAQs [14]
  Everest Group® [-8]
    Everest Group® [15]

Indentation shows the parent/child relationships. For a deck, positive numbers are page numbers and negative numbers are the abstract nodes grouping related sections; for a report, positive numbers are line numbers. The same trees are browsable in the HF space demo for PDF metadata.

Listing 4: Portrait structure parsed
deloitte-tech-risk-sector-banking [-1]
  Deloitte. [0]
    Pushing through undercurrents [2]
      Technology's impact on systemic risk: A look at banking [3]
      Risk 1: Risk exposure from Banking as a Service offerings [15]
        Table 1: Risk exposure from Banking as a Service offerings [29]
      Risk 2: Inadequate stability mechanisms for stablecoin arrangements [38]
        Table 1: Information about forces that could amplify the risk and how the industry mitigate it? [52]
      Contacts [63]

The tree index

To hang content on that skeleton, the document text has to be cut into nodes addressed the same way. Two parsers in src/pdf_rag/markdown_parsers.py do this. MarkdownLineNodeParser splits a report on its headings, recording for each node the path of enclosing headings and the line number where it starts, and ignores headings inside fenced code blocks. MarkdownPageNodeParser splits a deck on the --- end page N markers, recording the page number, and optionally cuts long pages further with a sentence splitter. One is header-addressed, the other page-addressed, matching the two structures above.

TreeIndex (src/pdf_rag/tree_index.py) assembles the two. For each document it builds a mapping from number to node — line numbers for reports, page numbers for decks, plus the document root — parses the structure into a tree, and creates a synthetic text node for every abstract node, since a section heading has a title but no text of its own. It then walks the tree, writes parent and child relationships onto the nodes, and records the same edges in an IndexStructTree that supports breadth-first and depth-first traversal. The whole thing can be exported to Neo4j, where each node becomes a TreeNode and each edge a HAS_CHILD relationship.

TreeIndex.as_retriever raises NotImplementedError. The index can be built, traversed, persisted and exported, but not queried, which is why the RAG system of Section 2 does not use it. That is a decision rather than an oversight, and the reason is the honest limit of this whole approach.

Retrieving through the tree would mean selecting a section by its title: show the model the table of contents, ask which section answers the question, fetch the nodes underneath. That only works if the titles are stable enough to choose between, and across the six documents they are not. The tax report gives eight named sections that are exactly what one would want to route on — “Customizing Technology for Global Compliance”, “Deciding How to Invest in Technology” — plus an “Other Pages” bucket for the leftovers. The life sciences deck gives seven sections that are not: two of them are the document’s own title, one exactly and one with the vendor prefix stripped, and a third is the vendor’s name on its own, so nothing in the list distinguishes one question from another. The granularity is unstable too. The same prompt returns eight entries for a 17-slide deck, but fifteen for a 15-slide deck and sixty-one for a 62-slide one — sometimes an outline, sometimes one entry per slide.

The portrait side is deterministic, a regular expression over the reformatted headings, so it is exactly as good as the reformatting: 139 headings for a 32-page report, in the same document that came back with 84 page markers for 32 pages.

None of this is broken, exactly. Every page of every document ends up placed somewhere in the tree, no page was dropped across the corpus, and the grouping step recovers genuine sections often enough to be useful. But a retriever built on it would stack a second layer of model judgement — choosing a section — on top of an artifact a model already wrote, at one extra call per document per query, and there is no labelled question set over these documents with which to check whether it retrieves better than embedding similarity does. It would be a bet, not a measurement. So the index stops at construction.

One practical note: export_to_neo4j wipes the target database only when called with clear=True, exposed as neo4j_clear in the configuration file.

# Create index with nodes
index = TreeIndex(
    nodes=document_nodes,
    show_progress=True
)

# Export to Neo4j
config = Neo4jConfig(
    uri="neo4j://localhost:7687",
    username="neo4j",
    password="password",
    database="neo4j"
)
index.export_to_neo4j(config=config)

Figure 3 shows the exported tree for one document.

Neo4j visualisation of TreeIndex
Figure 3: Neo4j visualisation of a TreeIndex export

The ingestion pipeline

scripts/metadata_structure.py runs everything above in order. It reads a YAML configuration file — configs/metadata_structure_example.yaml is a template — holding the data directory, the API keys, the worker count and, optionally, Neo4j credentials, which must be given all together or not at all. Its pipeline_step selects what to run: ingest for the ingestion pipeline, tree for the index, all for both.

Ingestion loads the PDFs with PDFDirectoryReader and pushes them through a llama-index IngestionPipeline whose transformations are exactly the components described above, in order:

  1. ReformatMarkdownComponent
  2. ContextExtractor
  3. TableOfContentsExtractor
  4. TableOfContentsCreator
  5. LandscapePagesExtractor
  6. StructureExtractor

The order is not arbitrary: the table of contents creator needs reformatted text, the page extractor needs a table of contents, and the structure extractor needs both. The enriched documents are persisted to a SimpleDocumentStore on disk, along with the pipeline’s own cache, so an interrupted run picks up where it stopped and an unchanged document is never reprocessed.

The tree step reloads that docstore, re-parses each document into nodes — by heading for reports, by page for decks, with chunking switched off so that a node is a whole page — builds the TreeIndex, writes its structure to tree_index_struct.json, and exports it to Neo4j if the configuration provides it.

uv run scripts/metadata_structure.py --config configs/metadata_structure.yaml

A Shiny app, app/app-metadata.py, is provided to inspect the results: it lists the processed documents, shows each PDF page beside its Markdown, displays the extracted metadata and tables of contents, and prints the parsed structure tree.

uv run shiny run --reload --launch-browser app/app-metadata.py

A standalone copy of it, bundled with the six sample documents and their extracted metadata, runs as a live demo on the HF space demo for PDF metadata, shown in Figure 4.

HF space demo for metadata and structure extraction from PDF
Figure 4: HF space demo for metadata and structure extraction from PDF

Querying a corpus of PDFs

The second half of the code answers questions over several PDFs at once: comparisons between documents, retrieval that spans them, summaries, fact-checking against a set. It is adapted from the multi-document agents notebook of llama-index and lives in src/pdf_rag/react_agent_multi_pdfs.py.

It uses none of the structure extracted in Section 1. The tree index that would connect the two halves cannot be queried yet, so retrieval here is the conventional kind: embeddings over page-sized chunks, with the document boundaries — rather than the document hierarchy — providing the only structure the agent exploits.

How the agent is built

class ReActAgentMultiPdfs:
    def __init__(
        self,
        api_key_gemini: str,
        api_key_mistral: str,
        root_dir: Path,
        pdfs_dir: Path,
        cache_dir: Path,
        storage_dir: Path,
        num_workers: int = 16,
        chunks_top_k: int = 5,
        nodes_top_k: int = 10,
        max_iterations: int = 20,
        verbose: bool = True,
    ) -> None:
        # ... initialization logic ...

root_dir and pdfs_dir locate the corpus, cache_dir holds the Markdown transcriptions and storage_dir the persisted indexes. Of the tuning parameters, chunks_top_k is how many chunks a document’s vector engine retrieves, nodes_top_k how many document tools the top-level agent retrieves for a question, max_iterations bounds the top-level reasoning loop and num_workers the concurrency of the asynchronous build. The language model is Gemini 2.0 Flash and the embeddings are text-embedding-004, reached through a small wrapper in src/pdf_rag/gemini_wrappers.py that calls the current Google SDK directly rather than through the llama-index integration.

The system is built in two levels. At the bottom, build_agent_per_doc gives every PDF its own agent. The document is read, split into page-addressed nodes, and indexed twice: a VectorStoreIndex for retrieval by similarity and a SummaryIndex for questions about the document as a whole. Both are persisted, so the expensive part happens once. The vector query engine retrieves chunks_top_k chunks and then passes them through FullPagePostprocessor (src/pdf_rag/node_postprocessors.py), which replaces every retrieved chunk by the complete page it came from, deduplicating pages hit more than once — a retrieved fragment is rarely enough context, and a slide almost never is. The summary engine answers in tree_summarize mode, and is also used once, at build time, to produce a summary of the document that is cached next to the indexes. The two engines become two tools, vector_tool_<name> and summary_tool_<name>, wrapped in a ReAct agent whose system prompt forbids answering from prior knowledge. File names are sanitised on the way — spaces and parentheses become underscores — because tool names are parsed out of the model’s output and punctuation there causes trouble.

At the top, top_agent wraps each per-document agent as a tool in turn, using that document’s generated summary as the tool description. Those tools are placed in an ObjectIndex and retrieved by embedding similarity, nodes_top_k at a time, so that a question first selects the documents likely to answer it. This is the part that scales: with a large corpus the top-level agent never sees more than a handful of tool descriptions at once.

CustomObjectRetriever adds the piece that makes comparison work. Every time tools are retrieved, it builds a SubQuestionQueryEngine over them and appends it as an extra tool called compare_tool, whose description tells the agent to use it for any question involving more than one document. The sub-question engine decomposes such a question into per-document sub-questions, dispatches each to the right tool and recombines the answers — something a single ReAct loop does poorly on its own.

        sub_question_engine = SubQuestionQueryEngine.from_defaults(
            query_engine_tools=tools,
            llm=self._llm,
            question_gen=LLMQuestionGenerator.from_defaults(llm=self._llm),
        )
        sub_question_description = f"""
        Useful for any queries that involve comparing multiple documents. ALWAYS use this tool for comparison queries - make sure to call this
        tool with the original query. Do NOT use the other tools for any queries involving multiple documents.
        """
        sub_question_tool = QueryEngineTool(
            query_engine=sub_question_engine,
            metadata=ToolMetadata(name="compare_tool", description=sub_question_description),
        )
        retrieved_tools = tools + [sub_question_tool]
        return retrieved_tools

Every stage exists in a synchronous and an asynchronous form; the asynchronous one builds the per-document agents concurrently, which is what makes a corpus of any size tractable. The top-level agent is a cached_property, so it is assembled once and reused across queries.

An example query

The notebook notebooks/query_multi_pdfs_example.ipynb runs the system over the six-document corpus and the list of queries in configs/query_multi_pdfs_example.yaml, which points at the six PDFs shipped in data/pdfs.

import os
from dataclasses import dataclass, field
from pathlib import Path

from omegaconf import OmegaConf, ValidationError

from pdf_rag.react_agent_multi_pdfs import ReActAgentMultiPdfs
from dotenv import load_dotenv

load_dotenv()


@dataclass
class ReActAgentConfig:
    data_dir: Path | str
    api_key_gemini: str | None = None
    api_key_mistral: str | None = None
    num_workers: int = 16
    chunks_top_k: int = 5
    nodes_top_k: int = 10
    max_iterations: int = 20
    verbose: bool = True
    queries: list[str] = field(default_factory=list)

    def __post_init__(self):
        self.data_dir = Path(self.data_dir)
        self.root_dir = self.data_dir / "pdfs"
        self.pdfs_dir = self.data_dir / "pdfs"
        self.cache_dir = self.data_dir / "cache"
        self.storage_dir = self.data_dir / "storage_queries"

        self.api_key_gemini = self.api_key_gemini or os.environ.get("GEMINI_API_KEY")
        self.api_key_mistral = self.api_key_mistral or os.environ.get("MISTRAL_API_KEY")
        if not self.api_key_gemini:
            raise ValueError(
                "Gemini API Key is required. Provide api_key_gemini or set GEMINI_API_KEY environment variable."
            )
        if not self.api_key_mistral:
            raise ValueError(
                "Mistral API Key is required. Provide api_key_mistral or set MISTRAL_API_KEY environment variable."
            )


def load_and_validate_config(config_path: str) -> ReActAgentConfig:
    try:
        config = OmegaConf.load(config_path)
        # A relative data_dir is resolved against the config file itself, so the
        # shipped example config works from the repository root and from notebooks/.
        if config.get("data_dir") and not Path(config.data_dir).is_absolute():
            config.data_dir = str((Path(config_path).parent / config.data_dir).resolve())
        react_agent_schema = OmegaConf.structured(ReActAgentConfig)
        react_agent_config = OmegaConf.merge(react_agent_schema, config)
        react_agent_config = ReActAgentConfig(**react_agent_config)
        print("Configuration loaded and validated successfully:")
        return react_agent_config
    except ValidationError as e:
        raise ValidationError(f"Validation error: {e}")
    except Exception as e:
        raise Exception(f"Error loading configuration: {e}")
config_path = "../configs/query_multi_pdfs_example.yaml"
config = load_and_validate_config(config_path)

react_agent_multi_pdfs = ReActAgentMultiPdfs(
    api_key_gemini=config.api_key_gemini,
    api_key_mistral=config.api_key_mistral,
    root_dir=config.root_dir,
    pdfs_dir=config.pdfs_dir,
    cache_dir=config.cache_dir,
    storage_dir=config.storage_dir,
    num_workers=config.num_workers,
    chunks_top_k=config.chunks_top_k,
    nodes_top_k=config.nodes_top_k,
    max_iterations=config.max_iterations,
    verbose=config.verbose,
)

responses = react_agent_multi_pdfs.process_queries(queries=config.queries)
for q, r in zip(config.queries, responses):
    print(30 * "-")
    print(f"Query: {q}")
    print(f"Response: {r}")
Configuration loaded and validated successfully:
> Running step 0dc45634-70c7-4656-9b12-fc2b086848ce. Step input: What are the vulnerabilities introduced by relying on application programming interfaces (APIs) in Banking as a Service (BaaS)?

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: tool_deloitte-tech-risk-sector-banking

Action Input: {'input': 'vulnerabilities of APIs in Banking as a Service (BaaS)'}

> Running step b574597e-591e-42f5-b2fe-075603369f1c. Step input: vulnerabilities of APIs in Banking as a Service (BaaS)

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: vector_tool_deloitte-tech-risk-sector-banking

Action Input: {'input': 'API vulnerabilities in Banking as a Service (BaaS)'}

Observation: BaaS increasingly relies on application programming interfaces, introducing vulnerabilities that can pose risks for banks, such as customers' sensitive data and funds being at risk from phishing and social engineering attacks, flawed APIs providing a back door for hackers to penetrate banks' systems and noncompliance with data privacy rules by BaaS providers exposing partner banks to reputational risks.



> Running step ab6397c0-d075-499f-8d74-ce5ef25de495. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: Banking as a Service (BaaS) relies heavily on APIs, which introduces vulnerabilities. These vulnerabilities can lead to risks for banks, including customer data and funds being at risk from phishing and social engineering, flawed APIs providing a backdoor for hackers, and noncompliance with data privacy rules by BaaS providers exposing partner banks to reputational risks.

Observation: Banking as a Service (BaaS) relies heavily on APIs, which introduces vulnerabilities. These vulnerabilities can lead to risks for banks, including customer data and funds being at risk from phishing and social engineering, flawed APIs providing a backdoor for hackers, and noncompliance with data privacy rules by BaaS providers exposing partner banks to reputational risks.

> Running step 8b2c762a-4a21-47ad-81f9-5dba4bb5e0f3. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: Relying on application programming interfaces (APIs) in Banking as a Service (BaaS) introduces vulnerabilities that can put customer data and funds at risk from phishing and social engineering. Flawed APIs can also provide a backdoor for hackers. Furthermore, noncompliance with data privacy rules by BaaS providers can expose partner banks to reputational risks.

> Running step 17a33cea-70cf-4150-98a9-73d9e08299cf. Step input: What mitigation opportunities are there to ensure strong security for BaaS platforms and API connectivity?

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: tool_deloitte-tech-risk-sector-banking

Action Input: {'input': 'mitigation strategies for BaaS platforms and API security'}

> Running step 0cde1ce4-d18b-4957-b0a9-0e8526141ad8. Step input: mitigation strategies for BaaS platforms and API security

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: vector_tool_deloitte-tech-risk-sector-banking

Action Input: {'input': 'mitigation strategies for BaaS platforms and API security'}

Observation: To ensure strong security for BaaS platforms and API connectivity, the industry can use input validation protocols and apply network segmentation and access control measures. They can also improve due diligence on BaaS providers and help BaaS and other fintech providers get better at risk management and compliance through institutional knowledge transfer from banks to BaaS partners.



> Running step 176b5919-f695-4091-8e2b-7ccc379b4dd0. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: To ensure strong security for BaaS platforms and API connectivity, the industry can use input validation protocols and apply network segmentation and access control measures. They can also improve due diligence on BaaS providers and help BaaS and other fintech providers get better at risk management and compliance through institutional knowledge transfer from banks to BaaS partners.

Observation: To ensure strong security for BaaS platforms and API connectivity, the industry can use input validation protocols and apply network segmentation and access control measures. They can also improve due diligence on BaaS providers and help BaaS and other fintech providers get better at risk management and compliance through institutional knowledge transfer from banks to BaaS partners.

> Running step bf56f882-81b4-4053-9376-1dd9a231b405. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: To ensure strong security for BaaS platforms and API connectivity, the industry can use input validation protocols and apply network segmentation and access control measures. Improving due diligence on BaaS providers and facilitating institutional knowledge transfer from banks to BaaS partners for better risk management and compliance are also beneficial mitigation strategies.

> Running step 69fc5519-d8d6-4ea3-ab8f-6ee9d32adcb7. Step input: How can the industry best improve due diligence on BaaS providers in this landscape?

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: tool_deloitte-tech-risk-sector-banking

Action Input: {'input': 'due diligence on BaaS providers'}

> Running step 57cce3c7-58b1-46a5-ae23-684437434197. Step input: due diligence on BaaS providers

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: vector_tool_deloitte-tech-risk-sector-banking

Action Input: {'input': 'due diligence on BaaS providers'}

Observation: Improving due diligence on BaaS providers is a mitigation opportunity for the risk exposure that comes from Banking as a Service offerings.



> Running step fa50b051-1a5f-4068-bbe5-0ace2f8b0a20. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: Improving due diligence on BaaS providers is a mitigation opportunity for the risk exposure that comes from Banking as a Service offerings.

Observation: Improving due diligence on BaaS providers is a mitigation opportunity for the risk exposure that comes from Banking as a Service offerings.

> Running step a835048a-e05e-4c02-b3bd-32f47024b7b4. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: The industry can improve due diligence on BaaS providers by implementing strong security measures for BaaS platforms and thoroughly vetting BaaS partners.

> Running step 23143917-1992-4bf2-b67d-d81cb14b7fdc. Step input: What are the common objectives of the Open Data ecosystem?

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: tool_gx-iif-open-data

Action Input: {'input': 'common objectives of Open Data ecosystem'}

> Running step ac79ff95-9ad1-4e03-a0ea-f75ff7b28194. Step input: common objectives of Open Data ecosystem

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: vector_tool_gx-iif-open-data

Action Input: {'input': 'common objectives of Open Data ecosystem'}

Observation: Open Data ecosystems share common objectives, including promoting innovation to increase consumer choice, creating more secure methods of data sharing, improving consumer data privacy and portability, and fostering cross-sectoral collaboration and interoperability.



> Running step 674ae599-801a-4725-8ea7-5ffe05a0a371. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: Open Data ecosystems generally aim to promote innovation to increase consumer choice, create more secure methods of data sharing, improve consumer data privacy and portability, and foster cross-sectoral collaboration and interoperability.

Observation: Open Data ecosystems generally aim to promote innovation to increase consumer choice, create more secure methods of data sharing, improve consumer data privacy and portability, and foster cross-sectoral collaboration and interoperability.

> Running step 46685aec-07d0-46f4-b8ad-4424cfc72ebd. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: The common objectives of the Open Data ecosystem are to promote innovation, create secure data sharing methods, improve consumer data privacy and portability, and foster cross-sectoral collaboration and interoperability.

> Running step 537f15c8-4be9-4f96-be10-6d63a2959001. Step input: What are key strategic decisions to be made by ecosystem participants?

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: tool_gx-iif-open-data

Action Input: {'input': 'strategic decisions for open data ecosystem participants'}

> Running step 4f1f9e8c-aca3-4b46-8546-f4584318dc4c. Step input: strategic decisions for open data ecosystem participants

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: summary_tool_gx-iif-open-data

Action Input: {'input': 'strategic decisions for open data ecosystem participants'}

Observation: When looking at the key strategic decisions to be made by ecosystem participants, the following hypotheses are of particular interest:



- Ecosystems are built on symbiotic relationships and generate value in standard ways;

- Data sharing is (and will continue to be) critical to ecosystems, but client consent and permission are priorities;

- Interoperability will likely be key to increasing the value capture in ecosystems;

- Broadening the set of data used by Fls and non-Fls could realize significant benefits for consumers, authorities, and the private sector; and

- Cyber-security and operational resilience will likely play a key role in building trust in Open Data ecosystems.



> Running step 3c89568b-6983-4a14-ac6b-bb1d53104325. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: The key strategic decisions for open data ecosystem participants revolve around symbiotic relationships, data sharing with client consent, interoperability, broadening data usage, and ensuring cyber-security and operational resilience to build trust.

Observation: The key strategic decisions for open data ecosystem participants revolve around symbiotic relationships, data sharing with client consent, interoperability, broadening data usage, and ensuring cyber-security and operational resilience to build trust.

> Running step 106b85da-5fee-4418-9a40-1bea7d6f56cc. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: Key strategic decisions for ecosystem participants involve establishing symbiotic relationships, facilitating data sharing with client consent, ensuring interoperability, broadening data usage, and prioritizing cyber-security and operational resilience to foster trust.

> Running step 54f9c69d-a738-4028-bc14-10b1efec857a. Step input: How can the public and private sectors collaborate to promote innovation, secure data sharing, and data privacy within the Open Data ecosystem?

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: tool_gx-iif-open-data

Action Input: {'input': 'collaboration between public and private sectors in Open Data ecosystem to promote innovation, secure data sharing, and data privacy'}

> Running step c8953756-0575-4165-9a6e-a29c23a8bbd1. Step input: collaboration between public and private sectors in Open Data ecosystem to promote innovation, secure data sharing, and data privacy

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: vector_tool_gx-iif-open-data

Action Input: {'input': 'collaboration between public and private sectors in Open Data ecosystem to promote innovation, secure data sharing, and data privacy'}

Observation: Open Data ecosystems promote innovation to increase consumer choice, create more secure methods of data sharing, improve consumer data privacy and portability, and foster cross-sectoral collaboration and interoperability. To leverage the potential of Open Data, data from different industries can be merged through sector-specific approaches that bring together private entities, the public sector, and consumers to create common data spaces for certain industries, while a holistic approach to data would help develop more customer-centric solutions.



> Running step be48c51d-9b67-4dfe-adf7-11b0591c0d09. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: Open Data ecosystems foster cross-sectoral collaboration between private entities, the public sector, and consumers to create common data spaces for certain industries, promoting innovation, secure data sharing, and data privacy.

Observation: Open Data ecosystems foster cross-sectoral collaboration between private entities, the public sector, and consumers to create common data spaces for certain industries, promoting innovation, secure data sharing, and data privacy.

> Running step 5d9dd1d3-8e6e-4291-b0aa-f5ba27b3c62a. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: The public and private sectors can collaborate within the Open Data ecosystem by fostering cross-sectoral partnerships to create common data spaces. This collaboration promotes innovation, secure data sharing methods, and improvements in consumer data privacy.

> Running step 54dc5bbe-979a-435f-871c-c2c4dc733b26. Step input: What are the key characteristics that define the Leaders, Major Contenders, and Aspirants within the Life Sciences Smart Manufacturing Services PEAK Matrix?

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: tool_life-sciences-smart-manufacturing-services-peak-matrix-assessment-2023

Action Input: {'input': 'key characteristics of Leaders, Major Contenders, and Aspirants in Life Sciences Smart Manufacturing Services PEAK Matrix'}

> Running step f6a15c99-4121-4b3d-a5ed-3024171d1e1e. Step input: key characteristics of Leaders, Major Contenders, and Aspirants in Life Sciences Smart Manufacturing Services PEAK Matrix

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: vector_tool_life-sciences-smart-manufacturing-services-peak-matrix-assessment-2023

Action Input: {'input': 'key characteristics of Leaders, Major Contenders, and Aspirants in Life Sciences Smart Manufacturing Services PEAK Matrix'}

Observation: **Leaders:** They act as digital transformation partners, providing end-to-end capabilities and a balanced set of offerings across the life sciences manufacturing value chain. They demonstrate flexibility and innovation in engagement models, possess a specialized talent pool, and have strong partnerships and investments in areas like digital twins and cybersecurity. They also have a clear roadmap for enhancing their capabilities through IP development and strategic initiatives.



**Major Contenders:** This group includes a mix of midsize and large firms with a less balanced portfolio than Leaders, often specializing in specific areas of the value chain. They may have limited solutions for high-growth areas like specialty drugs or sustainable manufacturing. They address smart manufacturing use cases by leveraging cross-industry resources and focus on the mid-tier client segment.



**Aspirants:** Aspirants have a restricted focus on specific areas within the life sciences manufacturing value chain and limited digital service capabilities. They have a limited partnership ecosystem and focus on leveraging horizontal capabilities rather than developing domain-specific services. They concentrate on capturing market share in the small and midsize buyer segment.



> Running step 2b6e54f6-31a9-4178-92e2-1c4a3efb5561. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: Here are the key characteristics of Leaders, Major Contenders, and Aspirants in the Life Sciences Smart Manufacturing Services PEAK Matrix:



**Leaders:** Act as digital transformation partners, providing end-to-end capabilities and a balanced set of offerings across the life sciences manufacturing value chain. They demonstrate flexibility and innovation in engagement models, possess a specialized talent pool, and have strong partnerships and investments in areas like digital twins and cybersecurity. They also have a clear roadmap for enhancing their capabilities through IP development and strategic initiatives.



**Major Contenders:** Include a mix of midsize and large firms with a less balanced portfolio than Leaders, often specializing in specific areas of the value chain. They may have limited solutions for high-growth areas like specialty drugs or sustainable manufacturing. They address smart manufacturing use cases by leveraging cross-industry resources and focus on the mid-tier client segment.



**Aspirants:** Have a restricted focus on specific areas within the life sciences manufacturing value chain and limited digital service capabilities. They have a limited partnership ecosystem and focus on leveraging horizontal capabilities rather than developing domain-specific services. They concentrate on capturing market share in the small and midsize buyer segment.

Observation: Here are the key characteristics of Leaders, Major Contenders, and Aspirants in the Life Sciences Smart Manufacturing Services PEAK Matrix:



**Leaders:** Act as digital transformation partners, providing end-to-end capabilities and a balanced set of offerings across the life sciences manufacturing value chain. They demonstrate flexibility and innovation in engagement models, possess a specialized talent pool, and have strong partnerships and investments in areas like digital twins and cybersecurity. They also have a clear roadmap for enhancing their capabilities through IP development and strategic initiatives.



**Major Contenders:** Include a mix of midsize and large firms with a less balanced portfolio than Leaders, often specializing in specific areas of the value chain. They may have limited solutions for high-growth areas like specialty drugs or sustainable manufacturing. They address smart manufacturing use cases by leveraging cross-industry resources and focus on the mid-tier client segment.



**Aspirants:** Have a restricted focus on specific areas within the life sciences manufacturing value chain and limited digital service capabilities. They have a limited partnership ecosystem and focus on leveraging horizontal capabilities rather than developing domain-specific services. They concentrate on capturing market share in the small and midsize buyer segment.

> Running step 5d2cea8b-eee1-4ee4-a8ab-98b0d453474a. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: The key characteristics are:



*   **Leaders:** Act as digital transformation partners with end-to-end capabilities, balanced offerings, flexible engagement models, specialized talent, strong partnerships, and a clear roadmap for enhancing capabilities.

*   **Major Contenders:** Have a less balanced portfolio, often specializing in specific areas, with limited solutions for high-growth areas. They leverage cross-industry resources and focus on the mid-tier client segment.

*   **Aspirants:** Have a restricted focus, limited digital service capabilities and partnership ecosystem, and concentrate on capturing market share in the small and midsize buyer segment.

> Running step 423c986e-395b-403b-afe0-8acada1ae7f1. Step input: What are some of the solutions that can assist biopharma and MedTech manufacturers with insights that help optimize manufacturing processes and improve product quality?

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: tool_life-sciences-smart-manufacturing-services-peak-matrix-assessment-2023

Action Input: {'input': 'solutions for biopharma and MedTech manufacturers to optimize manufacturing processes and improve product quality'}

> Running step bccdeb0c-a589-460a-b810-59927dee9e0e. Step input: solutions for biopharma and MedTech manufacturers to optimize manufacturing processes and improve product quality

Thought: The current language of the user is: english. I need to use a tool to help me answer the question.

Action: summary_tool_life-sciences-smart-manufacturing-services-peak-matrix-assessment-2023

Action Input: {'input': 'solutions for biopharma and MedTech manufacturers to optimize manufacturing processes and improve product quality'}

Observation: CognitiveSpark for manufacturing is a cloud-based, AI-powered solution designed to assist biopharma and MedTech manufacturers with insights that help optimize manufacturing processes and improve product quality.

> Running step 2d287b00-2e7d-474e-94fe-75e04853131d. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: CognitiveSpark for manufacturing is a cloud-based, AI-powered solution designed to assist biopharma and MedTech manufacturers with insights that help optimize manufacturing processes and improve product quality.

Observation: CognitiveSpark for manufacturing is a cloud-based, AI-powered solution designed to assist biopharma and MedTech manufacturers with insights that help optimize manufacturing processes and improve product quality.

> Running step a8339752-282e-4d96-861c-339fe81db351. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: CognitiveSpark for manufacturing is a cloud-based, AI-powered solution designed to assist biopharma and MedTech manufacturers with insights that help optimize manufacturing processes and improve product quality.

> Running step e3b4b9cd-9da2-4737-9c43-662051410718. Step input: How are different areas of a manufacturing line benefiting from AI?

Thought: The current language of the user is: English. I need to find information about how AI is benefiting manufacturing lines. I don't have a specific tool that directly addresses this, but the "tool_life-sciences-smart-manufacturing-services-peak-matrix-assessment-2023" tool seems most relevant as it discusses smart manufacturing in the life sciences, which likely involves AI applications.

Action: tool_life-sciences-smart-manufacturing-services-peak-matrix-assessment-2023

Action Input: {'input': 'AI applications in life sciences manufacturing'}

> Running step 8285ebfe-60e4-4c07-b369-84bf63a817a8. Step input: AI applications in life sciences manufacturing

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: vector_tool_life-sciences-smart-manufacturing-services-peak-matrix-assessment-2023

Action Input: {'input': 'AI applications in life sciences manufacturing'}

Observation: Life sciences enterprises are investing in critical use cases, including digital twins and predictive maintenance, and exploring opportunities such as sustainable and personalized medicine manufacturing. Service providers are becoming end-to-end digital transformation partners, co-developing solutions to assist enterprises in their digital journeys. One solution enables visibility of multi-tier supply networks and senses upcoming risks to mitigate disruptions. Another platform solution enables a comprehensive view of manufacturing operations across the organization with connected data, creating dynamic data visualizations that provide useful insights and recommended actions, assisting in predictive analytics and quality analytics.



> Running step 2dc34498-25fe-491a-9487-ea77a5562c2b. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: Life sciences companies are investing in AI applications like digital twins and predictive maintenance, and exploring opportunities in sustainable and personalized medicine manufacturing. Service providers are offering end-to-end digital transformation partnerships, co-developing solutions for digital journeys. These solutions include providing visibility into multi-tier supply networks to mitigate disruptions and offering platforms for a comprehensive view of manufacturing operations with connected data, dynamic data visualizations, predictive analytics, and quality analytics.

Observation: Life sciences companies are investing in AI applications like digital twins and predictive maintenance, and exploring opportunities in sustainable and personalized medicine manufacturing. Service providers are offering end-to-end digital transformation partnerships, co-developing solutions for digital journeys. These solutions include providing visibility into multi-tier supply networks to mitigate disruptions and offering platforms for a comprehensive view of manufacturing operations with connected data, dynamic data visualizations, predictive analytics, and quality analytics.

> Running step 3cd8ceec-02a0-4544-95a6-673923dca8b5. Step input: None

Thought: The current language of the user is: English. The tool provided some information about AI applications in life sciences manufacturing, including digital twins, predictive maintenance, supply chain visibility, and platforms for comprehensive views of manufacturing operations with connected data, dynamic data visualizations, predictive analytics, and quality analytics. This gives a good overview of how AI is benefiting different areas of a manufacturing line.

Answer: AI is benefiting different areas of manufacturing lines through applications like digital twins and predictive maintenance. It also provides better visibility into supply chains and offers platforms for a comprehensive view of manufacturing operations with connected data, dynamic data visualizations, predictive analytics, and quality analytics.

> Running step b23d31dd-3e78-4d90-bbe9-0c17280967db. Step input: What are ConocoPhillips' key financial priorities for the next 10 years?

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: tool_2023-conocophillips-aim-presentation

Action Input: {'input': "ConocoPhillips' 10-year financial plan"}

> Running step c1216a19-59b1-4f3e-ba31-3e5bc2653a3c. Step input: ConocoPhillips' 10-year financial plan

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: summary_tool_2023-conocophillips-aim-presentation

Action Input: {'input': "ConocoPhillips' 10-year financial plan"}

Observation: ConocoPhillips has a compelling 10-year plan that includes the following:



*   Peer-leading ROCE improving through time

*   Top quartile ordinary dividend growth

*   >90% market cap distributed

*   ~$35/BBL WTI FCF Breakeven

*   ~6% CFO CAGR, ~11% FCF CAGR

*   Unhedged for price upside



> Running step 85f186e1-6701-49c4-9ede-8877d99b5f7d. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: ConocoPhillips' 10-year financial plan aims for peer-leading ROCE improvement, top quartile ordinary dividend growth, distribution of over 90% of market cap, a ~$35/BBL WTI FCF breakeven, ~6% CFO CAGR, ~11% FCF CAGR, and being unhedged for price upside.

Observation: ConocoPhillips' 10-year financial plan aims for peer-leading ROCE improvement, top quartile ordinary dividend growth, distribution of over 90% of market cap, a ~$35/BBL WTI FCF breakeven, ~6% CFO CAGR, ~11% FCF CAGR, and being unhedged for price upside.

> Running step ec8ff47a-d551-4907-93fb-d325380bc4ba. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: ConocoPhillips' key financial priorities for the next 10 years include: peer-leading ROCE improvement, top quartile ordinary dividend growth, distribution of over 90% of market cap, a ~$35/BBL WTI FCF breakeven, ~6% CFO CAGR, ~11% FCF CAGR, and remaining unhedged for price upside.

> Running step 296a9b6f-5116-4992-8417-a98b9ecf7e52. Step input: How does ConocoPhillips plan to meet it's Net-Zero and Emissions targets?

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: tool_2023-conocophillips-aim-presentation

Action Input: {'input': 'ConocoPhillips Net-Zero and Emissions targets'}

> Running step b2a1e6ee-2120-498d-b83d-bfaa372b0646. Step input: ConocoPhillips Net-Zero and Emissions targets

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: vector_tool_2023-conocophillips-aim-presentation

Action Input: {'input': 'ConocoPhillips Net-Zero and Emissions targets'}

Observation: ConocoPhillips is progressing toward its 2050 net-zero ambition and accelerating its 2030 GHG emissions intensity reduction target. They plan to reduce GHG intensity 50-60% by 2030 and have a near-zero methane intensity target of <1.5 kg CO2e/BOE. They are also aiming for zero routine flaring by 2025.



> Running step 9b83e468-2f60-431e-940d-646ae3abca87. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: ConocoPhillips is working towards its 2050 net-zero ambition. They are accelerating their 2030 GHG emissions intensity reduction target to 50-60% and have a near-zero methane intensity target of <1.5 kg CO2e/BOE. They also aim for zero routine flaring by 2025.

Observation: ConocoPhillips is working towards its 2050 net-zero ambition. They are accelerating their 2030 GHG emissions intensity reduction target to 50-60% and have a near-zero methane intensity target of <1.5 kg CO2e/BOE. They also aim for zero routine flaring by 2025.

> Running step 52cb3db4-88f0-4e6c-98a2-85289b0dd630. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: ConocoPhillips plans to meet its Net-Zero ambition by 2050. They are accelerating their 2030 GHG emissions intensity reduction target to 50-60% and have a near-zero methane intensity target of <1.5 kg CO2e/BOE. They also aim for zero routine flaring by 2025.

> Running step a9a3e10f-d4aa-4e20-afd1-fb3b6a6f4cb2. Step input: What is ConocoPhillips strategy to grow production?

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: tool_2023-conocophillips-aim-presentation

Action Input: {'input': 'ConocoPhillips production growth strategy'}

> Running step 379518d2-dcd9-4126-96b0-6b262201571f. Step input: ConocoPhillips production growth strategy

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: vector_tool_2023-conocophillips-aim-presentation

Action Input: {'input': 'ConocoPhillips production growth strategy'}

Observation: ConocoPhillips has a strategy for capital-efficient production growth that underpins growing distribution capacity. They have a material low cost of supply resource base, leveraging existing infrastructure, with an average cost of supply of ~$30/BBL. Their production mix consists of approximately 60% oil, 5% NGL, 5% North American Gas, and 30% International Gas. They anticipate a 4% CAGR at ~40% reinvestment rate over the next 10 years at $60/BBL WTI.



> Running step 36765352-5b93-4eac-b04d-c74a685229f3. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: ConocoPhillips' production growth strategy focuses on capital-efficient growth to support increasing distribution capacity. They leverage a substantial, low-cost supply resource base, utilizing existing infrastructure, with an average supply cost of approximately $30 per barrel. Their production is composed of roughly 60% oil, 5% NGL, 5% North American Gas, and 30% International Gas. They project a 4% compound annual growth rate (CAGR) with about a 40% reinvestment rate over the next decade, assuming a West Texas Intermediate (WTI) crude oil price of $60 per barrel.

Observation: ConocoPhillips' production growth strategy focuses on capital-efficient growth to support increasing distribution capacity. They leverage a substantial, low-cost supply resource base, utilizing existing infrastructure, with an average supply cost of approximately $30 per barrel. Their production is composed of roughly 60% oil, 5% NGL, 5% North American Gas, and 30% International Gas. They project a 4% compound annual growth rate (CAGR) with about a 40% reinvestment rate over the next decade, assuming a West Texas Intermediate (WTI) crude oil price of $60 per barrel.

> Running step 4fb25291-2915-4d64-b88a-2eba67a1f58d. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: ConocoPhillips' strategy to grow production involves capital-efficient growth supported by a substantial, low-cost resource base and existing infrastructure. They aim for a 4% compound annual growth rate (CAGR) over the next decade, with a reinvestment rate of about 40%, assuming a WTI crude oil price of $60 per barrel.

> Running step 271b97c5-318f-4709-9689-2efaa1692bfc. Step input: What are the key features and capabilities of the XC9500 In-System Programmable CPLD family?

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: tool_XC9500_CPLD_Family

Action Input: {'input': 'key features and capabilities of XC9500 CPLD family'}

> Running step 38da0c2b-6f77-4b3e-998d-22dec2f0435f. Step input: key features and capabilities of XC9500 CPLD family

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: vector_tool_XC9500_CPLD_Family

Action Input: {'input': 'key features and capabilities of XC9500 CPLD family'}

Observation: The XC9500 CPLD family offers in-system programmability and testing for general purpose logic integration. Devices are in-system programmable for a minimum of 10,000 program/erase cycles and include IEEE 1149.1 (JTAG) boundary-scan support.



Key features include:



*   High-performance with 5 ns pin-to-pin logic delays and fCNT to 125 MHz.

*   A density range of 36 to 288 macrocells, equating to 800 to 6,400 usable gates.

*   5V in-system programmability with 10,000 program/erase cycle endurance.

*   Enhanced pin-locking architecture.

*   Flexible 36V18 Function Block with 90 product terms driving up to 18 macrocells.

*   Global and product term clocks, output enables, set and reset signals.

*   Extensive IEEE Std 1149.1 boundary-scan (JTAG) support.

*   Programmable power reduction mode in each macrocell.

*   Slew rate control on individual outputs.

*   User programmable ground pin capability.

*   Extended pattern security features for design protection.

*   High-drive 24 mA outputs.

*   3.3V or 5V I/O capability.

*   Advanced CMOS 5V FastFLASH™ technology.

*   Support for parallel programming of multiple devices.



The architecture includes features such as enhanced pin-locking, an expanded JTAG instruction set, and in-system programming across the full device operating range. Additional system features include output slew rate control, user-programmable ground pins, and configurable I/Os for 3.3V or 5V operation. All outputs provide 24 mA drive. The devices also offer a low-power mode for individual or all macrocells.



> Running step ad6a2bf8-8a03-4f32-a6f9-fae02d7d9e56. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: The XC9500 CPLD family provides in-system programmability and testing. Key features include high performance (5 ns pin-to-pin delays, 125 MHz fCNT), densities from 36 to 288 macrocells (800 to 6,400 gates), 5V in-system programmability (10,000 cycles), enhanced pin-locking, flexible function blocks, global/product term clocks, JTAG support, programmable power reduction, slew rate control, user-programmable ground pins, extended pattern security, high-drive 24 mA outputs, 3.3V/5V I/O capability, and advanced CMOS FastFLASH technology. It also supports parallel programming, expanded JTAG, and configurable I/Os.

Observation: The XC9500 CPLD family provides in-system programmability and testing. Key features include high performance (5 ns pin-to-pin delays, 125 MHz fCNT), densities from 36 to 288 macrocells (800 to 6,400 gates), 5V in-system programmability (10,000 cycles), enhanced pin-locking, flexible function blocks, global/product term clocks, JTAG support, programmable power reduction, slew rate control, user-programmable ground pins, extended pattern security, high-drive 24 mA outputs, 3.3V/5V I/O capability, and advanced CMOS FastFLASH technology. It also supports parallel programming, expanded JTAG, and configurable I/Os.

> Running step 125f1de5-aa3e-48fa-b445-a0a836de904e. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: The key features and capabilities of the XC9500 In-System Programmable CPLD family include: high performance with 5 ns pin-to-pin delays and 125 MHz fCNT, densities ranging from 36 to 288 macrocells (800 to 6,400 gates), 5V in-system programmability with 10,000 program/erase cycles, enhanced pin-locking architecture, flexible Function Blocks, global and product term clocks, extensive JTAG support, programmable power reduction, slew rate control, user-programmable ground pins, extended pattern security, high-drive 24 mA outputs, 3.3V/5V I/O capability, advanced CMOS FastFLASH technology, support for parallel programming, expanded JTAG, and configurable I/Os.

> Running step 7813cb38-11bb-41dd-b88b-5c5b044ba777. Step input: How does the Fast CONNECT switch matrix enable flexible signal routing and logic implementation within the XC9500 devices?

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: tool_XC9500_CPLD_Family

Action Input: {'input': 'Fast CONNECT switch matrix'}

> Running step 5de85ea0-fe67-49a5-a791-1ee39c77be35. Step input: Fast CONNECT switch matrix

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: vector_tool_XC9500_CPLD_Family

Action Input: {'input': 'Fast CONNECT switch matrix'}

Observation: The Fast CONNECT switch matrix connects signals to the Function Block (FB) inputs. All I/O Block (IOB) outputs (corresponding to user pin inputs) and all FB outputs drive the Fast CONNECT matrix. Any of these signals (up to a FB fan-in limit of 36) may be selected, through user programming, to drive each FB with a uniform delay. The Fast CONNECT switch matrix can combine multiple internal connections into a single wired-AND output before driving the destination FB. This provides additional logic capability and increases the effective logic fan-in of the destination FB without any additional timing delay. This capability is available for internal connections originating from FB outputs only and is automatically invoked by the development software where applicable.



> Running step 7e74704f-8e13-4efd-bf1d-d2d80fc9a54e. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: The Fast CONNECT switch matrix connects signals to the Function Block (FB) inputs. All I/O Block (IOB) outputs (corresponding to user pin inputs) and all FB outputs drive the Fast CONNECT matrix. Any of these signals (up to a FB fan-in limit of 36) may be selected, through user programming, to drive each FB with a uniform delay. The Fast CONNECT switch matrix can combine multiple internal connections into a single wired-AND output before driving the destination FB. This provides additional logic capability and increases the effective logic fan-in of the destination FB without any additional timing delay. This capability is available for internal connections originating from FB outputs only and is automatically invoked by the development software where applicable.

Observation: The Fast CONNECT switch matrix connects signals to the Function Block (FB) inputs. All I/O Block (IOB) outputs (corresponding to user pin inputs) and all FB outputs drive the Fast CONNECT matrix. Any of these signals (up to a FB fan-in limit of 36) may be selected, through user programming, to drive each FB with a uniform delay. The Fast CONNECT switch matrix can combine multiple internal connections into a single wired-AND output before driving the destination FB. This provides additional logic capability and increases the effective logic fan-in of the destination FB without any additional timing delay. This capability is available for internal connections originating from FB outputs only and is automatically invoked by the development software where applicable.

> Running step 6bfc34d0-b396-4ee0-aafe-6d14f487229b. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: The Fast CONNECT switch matrix enables flexible signal routing by allowing any I/O Block (IOB) output (corresponding to user pin inputs) and all Function Block (FB) outputs to drive the matrix. User programming can select up to 36 of these signals to drive each FB with a uniform delay. It also increases logic implementation flexibility by combining multiple internal connections into a single wired-AND output before driving the destination FB, increasing the effective logic fan-in of the destination FB without additional timing delay.

> Running step 1d68eac4-1bf1-439d-a3d5-ede073dd7907. Step input: What design security options are available in the XC9500 family, and how do they protect programming data?

Thought: The current language of the user is: English. I need to find information about design security options in the XC9500 family.

Action: tool_XC9500_CPLD_Family

Action Input: {'input': 'design security'}

> Running step dca71de5-ce54-4035-81af-13b0d874fda6. Step input: design security

Thought: The current language of the user is: english. I need to use a tool to help me answer the question.

Action: vector_tool_XC9500_CPLD_Family

Action Input: {'input': 'design security'}

Observation: XC9500 devices have advanced data security features that protect programming data against unauthorized reading or accidental erasure/reprogramming. There are four security settings available. The read security bits can be set to prevent the internal programming pattern from being read or copied, which also inhibits further program operations but allows device erasure. The write security bits provide added protection against accidental device erasure or reprogramming when the JTAG pins are subject to noise. Once set, the write-protection may be deactivated when the device needs to be reprogrammed with a valid pattern.



> Running step 8d883c8c-aaa2-4dc0-874e-625773179440. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: XC9500 devices offer advanced data security features to safeguard programming data from unauthorized access or accidental erasure/reprogramming. These devices provide four security settings, including read security bits to prevent internal programming pattern reading or copying (while still allowing device erasure) and write security bits for added protection against accidental device erasure or reprogramming, which can be deactivated for reprogramming with a valid pattern.

Observation: XC9500 devices offer advanced data security features to safeguard programming data from unauthorized access or accidental erasure/reprogramming. These devices provide four security settings, including read security bits to prevent internal programming pattern reading or copying (while still allowing device erasure) and write security bits for added protection against accidental device erasure or reprogramming, which can be deactivated for reprogramming with a valid pattern.

> Running step d27647c5-3477-4090-82b9-09ce5c02f89f. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: The XC9500 family offers advanced data security features to protect programming data. It provides four security settings, including read security bits to prevent internal programming pattern reading or copying (while still allowing device erasure) and write security bits for added protection against accidental device erasure or reprogramming, which can be deactivated for reprogramming with a valid pattern.

> Running step 10dc49fa-9fbd-40d4-a72e-1d84eda84d54. Step input: What strategies are companies implementing to address tax transformation in a data-driven world?

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: tool_dttl-tax-technology-report-2023

Action Input: {'input': 'strategies for tax transformation in a data-driven world'}

> Running step 9819b07e-37da-4fd9-9dac-a93d8b6e7e18. Step input: strategies for tax transformation in a data-driven world

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: vector_tool_dttl-tax-technology-report-2023

Action Input: {'input': 'strategies for tax transformation in a data-driven world'}

Observation: To meet complex tax obligations, real-time reporting requirements, and increasing expectations of tax transparency, firms need immediate access to reliable, accurate, and fit-for-purpose tax data. Businesses should consider customizing existing ERP systems and identifying appropriate issues, involving the right stakeholders internally, obtaining budget when there are competing demands, and devising a robust schedule of maintenance. Tax departments are encouraged to develop a road map to use available technology, identify future needs, and then make build-or-buy decisions. Embedding tax into everyday processes and operations will lead to tax considerations in transformation efforts becoming "business as usual," making building the business case for technology investment less onerous.



> Running step a498dc3f-6f71-44cc-9add-db894c222e83. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: To transform tax in a data-driven world, businesses should focus on:



*   Ensuring immediate access to reliable, accurate, and fit-for-purpose tax data to meet complex obligations, real-time reporting, and transparency expectations.

*   Customizing existing ERP systems and addressing relevant issues.

*   Involving the right internal stakeholders.

*   Securing budget despite competing demands.

*   Creating a robust maintenance schedule.

*   Developing a technology roadmap to address current and future needs, guiding build-or-buy decisions.

*   Embedding tax into everyday processes to make tax considerations routine in transformation efforts, simplifying the justification for technology investments.

Observation: To transform tax in a data-driven world, businesses should focus on:



*   Ensuring immediate access to reliable, accurate, and fit-for-purpose tax data to meet complex obligations, real-time reporting, and transparency expectations.

*   Customizing existing ERP systems and addressing relevant issues.

*   Involving the right internal stakeholders.

*   Securing budget despite competing demands.

*   Creating a robust maintenance schedule.

*   Developing a technology roadmap to address current and future needs, guiding build-or-buy decisions.

*   Embedding tax into everyday processes to make tax considerations routine in transformation efforts, simplifying the justification for technology investments.

> Running step f859adbd-5e63-4539-89f0-c13f01b9f2d2. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: Companies are implementing strategies such as ensuring immediate access to reliable and accurate tax data, customizing ERP systems, involving internal stakeholders, securing budgets, creating maintenance schedules, developing technology roadmaps, and embedding tax into everyday processes to address tax transformation in a data-driven world.

> Running step 913a33a5-23de-43aa-a220-b71d419a6011. Step input: How can tax departments effectively invest in technology to meet compliance and strategic goals?

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: tool_dttl-tax-technology-report-2023

Action Input: {'input': 'How can tax departments effectively invest in technology to meet compliance and strategic goals?'}

> Running step 11574750-b6fa-48a0-b5c2-90b73fc01b01. Step input: How can tax departments effectively invest in technology to meet compliance and strategic goals?

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: vector_tool_dttl-tax-technology-report-2023

Action Input: {'input': 'effective technology investment for tax compliance and strategic goals'}

Observation: To effectively invest in technology, tax departments should first secure a budget and create a roadmap that leverages existing technology, identifies future needs, and guides build-or-buy decisions. Taking a top-down approach and explaining the impact of tax authority digitalization to the C-suite, as well as collaborating with the IT department, can help build a strong value case for budget. It's important to consider the long-term potential requirements, as finding a short-term solution without considering future needs may prevent the tax department from becoming a strategic advisor.



When choosing technology, tax departments can implement using internal resources, appoint an implementation partner, or outsource the entire function requiring the technology. If using in-house resources, developing professional teams with data management and technology expertise is essential, especially in data analytics, strategic insights, and data management.



> Running step cf222cb7-a4c1-4012-9c72-6e32be1215b5. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: To effectively invest in technology for tax compliance and strategic goals, tax departments should:



1.  **Secure a budget and create a roadmap:** This roadmap should leverage existing technology, identify future needs, and guide build-or-buy decisions. A top-down approach, explaining the impact of tax authority digitalization to the C-suite, and collaboration with the IT department can help build a strong value case for budget.

2.  **Consider long-term potential requirements:** Avoid short-term solutions that may hinder the tax department's ability to become a strategic advisor.

3.  **Choose an implementation approach:** Options include using internal resources, appointing an implementation partner, or outsourcing the entire function.

4.  **Develop professional teams:** If using in-house resources, create teams with data management and technology expertise, especially in data analytics, strategic insights, and data management.

Observation: To effectively invest in technology for tax compliance and strategic goals, tax departments should:



1.  **Secure a budget and create a roadmap:** This roadmap should leverage existing technology, identify future needs, and guide build-or-buy decisions. A top-down approach, explaining the impact of tax authority digitalization to the C-suite, and collaboration with the IT department can help build a strong value case for budget.

2.  **Consider long-term potential requirements:** Avoid short-term solutions that may hinder the tax department's ability to become a strategic advisor.

3.  **Choose an implementation approach:** Options include using internal resources, appointing an implementation partner, or outsourcing the entire function.

4.  **Develop professional teams:** If using in-house resources, create teams with data management and technology expertise, especially in data analytics, strategic insights, and data management.

> Running step 62f00f19-9819-4183-a8d5-52fac1c5a514. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: To effectively invest in technology for tax compliance and strategic goals, tax departments should secure a budget and create a roadmap that leverages existing technology and identifies future needs. They should also consider long-term potential requirements, choose an appropriate implementation approach (internal resources, partner, or outsourcing), and develop professional teams with data management and technology expertise.

> Running step cf14f83c-b67b-49a2-9429-4e9180ce5411. Step input: How can tax departments collaborate internally to secure budget and ensure technology alignment?

Thought: The current language of the user is: English. I need to use a tool to help me answer the question.

Action: tool_dttl-tax-technology-report-2023

Action Input: {'input': 'internal collaboration in tax departments to secure budget and ensure technology alignment'}

> Running step 7f6e4001-7126-4e9b-87fd-e2713553240b. Step input: internal collaboration in tax departments to secure budget and ensure technology alignment

Thought: The current language of the user is: English. I need to use a tool to find information about internal collaboration in tax departments to secure budget and ensure technology alignment.

Action: vector_tool_dttl-tax-technology-report-2023

Action Input: {'input': 'internal collaboration in tax departments to secure budget and ensure technology alignment'}

Observation: To make a case for budget, tax departments need to show the value they bring to the company, explain how tax authority digitalization impacts the C-suite, and work with the IT department. Companies that have taken a top-down approach have been more successful in building this value case.



When seeking technology, best practice includes securing a budget and creating a road map to utilize available technology, identify future needs, and then decide whether to build or buy. A holistic view of the tax department's operating model is useful at this point to increase speed and accuracy, and free up tax professionals for more strategic business activity.



When asked about the greatest need for skills over the next three to five years, respondents most often named data analytics, data-driven strategic insights, and data management.



> Running step 55db2b52-becf-4e0f-a00e-299c4a5048bb. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: To secure budget for tax technology, tax departments need to demonstrate their value to the company, explain the impact of tax authority digitalization on the C-suite, and collaborate with the IT department. Companies adopting a top-down approach have seen more success in building this value case. Best practices include creating a roadmap to utilize available technology, identifying future needs, and deciding whether to build or buy, all while maintaining a holistic view of the tax department's operating model.

Observation: To secure budget for tax technology, tax departments need to demonstrate their value to the company, explain the impact of tax authority digitalization on the C-suite, and collaborate with the IT department. Companies adopting a top-down approach have seen more success in building this value case. Best practices include creating a roadmap to utilize available technology, identifying future needs, and deciding whether to build or buy, all while maintaining a holistic view of the tax department's operating model.

> Running step e35d23b0-83b9-4d79-b225-c08ea46ecec1. Step input: None

Thought: I can answer without using any more tools. I'll use the user's language to answer

Answer: Tax departments can collaborate internally to secure budget and ensure technology alignment by demonstrating their value to the company, explaining the impact of tax authority digitalization to the C-suite, and collaborating with the IT department. Creating a roadmap to utilize available technology, identifying future needs, and deciding whether to build or buy, all while maintaining a holistic view of the tax department's operating model are best practices. Companies adopting a top-down approach have seen more success in building this value case.

------------------------------

Query: What are the vulnerabilities introduced by relying on application programming interfaces (APIs) in Banking as a Service (BaaS)?

Response: Relying on application programming interfaces (APIs) in Banking as a Service (BaaS) introduces vulnerabilities that can put customer data and funds at risk from phishing and social engineering. Flawed APIs can also provide a backdoor for hackers. Furthermore, noncompliance with data privacy rules by BaaS providers can expose partner banks to reputational risks.

------------------------------

Query: What mitigation opportunities are there to ensure strong security for BaaS platforms and API connectivity?

Response: To ensure strong security for BaaS platforms and API connectivity, the industry can use input validation protocols and apply network segmentation and access control measures. Improving due diligence on BaaS providers and facilitating institutional knowledge transfer from banks to BaaS partners for better risk management and compliance are also beneficial mitigation strategies.

------------------------------

Query: How can the industry best improve due diligence on BaaS providers in this landscape?

Response: The industry can improve due diligence on BaaS providers by implementing strong security measures for BaaS platforms and thoroughly vetting BaaS partners.

------------------------------

Query: What are the common objectives of the Open Data ecosystem?

Response: The common objectives of the Open Data ecosystem are to promote innovation, create secure data sharing methods, improve consumer data privacy and portability, and foster cross-sectoral collaboration and interoperability.

------------------------------

Query: What are key strategic decisions to be made by ecosystem participants?

Response: Key strategic decisions for ecosystem participants involve establishing symbiotic relationships, facilitating data sharing with client consent, ensuring interoperability, broadening data usage, and prioritizing cyber-security and operational resilience to foster trust.

------------------------------

Query: How can the public and private sectors collaborate to promote innovation, secure data sharing, and data privacy within the Open Data ecosystem?

Response: The public and private sectors can collaborate within the Open Data ecosystem by fostering cross-sectoral partnerships to create common data spaces. This collaboration promotes innovation, secure data sharing methods, and improvements in consumer data privacy.

------------------------------

Query: What are the key characteristics that define the Leaders, Major Contenders, and Aspirants within the Life Sciences Smart Manufacturing Services PEAK Matrix?

Response: The key characteristics are:



*   **Leaders:** Act as digital transformation partners with end-to-end capabilities, balanced offerings, flexible engagement models, specialized talent, strong partnerships, and a clear roadmap for enhancing capabilities.

*   **Major Contenders:** Have a less balanced portfolio, often specializing in specific areas, with limited solutions for high-growth areas. They leverage cross-industry resources and focus on the mid-tier client segment.

*   **Aspirants:** Have a restricted focus, limited digital service capabilities and partnership ecosystem, and concentrate on capturing market share in the small and midsize buyer segment.

------------------------------

Query: What are some of the solutions that can assist biopharma and MedTech manufacturers with insights that help optimize manufacturing processes and improve product quality?

Response: CognitiveSpark for manufacturing is a cloud-based, AI-powered solution designed to assist biopharma and MedTech manufacturers with insights that help optimize manufacturing processes and improve product quality.

------------------------------

Query: How are different areas of a manufacturing line benefiting from AI?

Response: AI is benefiting different areas of manufacturing lines through applications like digital twins and predictive maintenance. It also provides better visibility into supply chains and offers platforms for a comprehensive view of manufacturing operations with connected data, dynamic data visualizations, predictive analytics, and quality analytics.

------------------------------

Query: What are ConocoPhillips' key financial priorities for the next 10 years?

Response: ConocoPhillips' key financial priorities for the next 10 years include: peer-leading ROCE improvement, top quartile ordinary dividend growth, distribution of over 90% of market cap, a ~$35/BBL WTI FCF breakeven, ~6% CFO CAGR, ~11% FCF CAGR, and remaining unhedged for price upside.

------------------------------

Query: How does ConocoPhillips plan to meet it's Net-Zero and Emissions targets?

Response: ConocoPhillips plans to meet its Net-Zero ambition by 2050. They are accelerating their 2030 GHG emissions intensity reduction target to 50-60% and have a near-zero methane intensity target of <1.5 kg CO2e/BOE. They also aim for zero routine flaring by 2025.

------------------------------

Query: What is ConocoPhillips strategy to grow production?

Response: ConocoPhillips' strategy to grow production involves capital-efficient growth supported by a substantial, low-cost resource base and existing infrastructure. They aim for a 4% compound annual growth rate (CAGR) over the next decade, with a reinvestment rate of about 40%, assuming a WTI crude oil price of $60 per barrel.

------------------------------

Query: What are the key features and capabilities of the XC9500 In-System Programmable CPLD family?

Response: The key features and capabilities of the XC9500 In-System Programmable CPLD family include: high performance with 5 ns pin-to-pin delays and 125 MHz fCNT, densities ranging from 36 to 288 macrocells (800 to 6,400 gates), 5V in-system programmability with 10,000 program/erase cycles, enhanced pin-locking architecture, flexible Function Blocks, global and product term clocks, extensive JTAG support, programmable power reduction, slew rate control, user-programmable ground pins, extended pattern security, high-drive 24 mA outputs, 3.3V/5V I/O capability, advanced CMOS FastFLASH technology, support for parallel programming, expanded JTAG, and configurable I/Os.

------------------------------

Query: How does the Fast CONNECT switch matrix enable flexible signal routing and logic implementation within the XC9500 devices?

Response: The Fast CONNECT switch matrix enables flexible signal routing by allowing any I/O Block (IOB) output (corresponding to user pin inputs) and all Function Block (FB) outputs to drive the matrix. User programming can select up to 36 of these signals to drive each FB with a uniform delay. It also increases logic implementation flexibility by combining multiple internal connections into a single wired-AND output before driving the destination FB, increasing the effective logic fan-in of the destination FB without additional timing delay.

------------------------------

Query: What design security options are available in the XC9500 family, and how do they protect programming data?

Response: The XC9500 family offers advanced data security features to protect programming data. It provides four security settings, including read security bits to prevent internal programming pattern reading or copying (while still allowing device erasure) and write security bits for added protection against accidental device erasure or reprogramming, which can be deactivated for reprogramming with a valid pattern.

------------------------------

Query: What strategies are companies implementing to address tax transformation in a data-driven world?

Response: Companies are implementing strategies such as ensuring immediate access to reliable and accurate tax data, customizing ERP systems, involving internal stakeholders, securing budgets, creating maintenance schedules, developing technology roadmaps, and embedding tax into everyday processes to address tax transformation in a data-driven world.

------------------------------

Query: How can tax departments effectively invest in technology to meet compliance and strategic goals?

Response: To effectively invest in technology for tax compliance and strategic goals, tax departments should secure a budget and create a roadmap that leverages existing technology and identifies future needs. They should also consider long-term potential requirements, choose an appropriate implementation approach (internal resources, partner, or outsourcing), and develop professional teams with data management and technology expertise.

------------------------------

Query: How can tax departments collaborate internally to secure budget and ensure technology alignment?

Response: Tax departments can collaborate internally to secure budget and ensure technology alignment by demonstrating their value to the company, explaining the impact of tax authority digitalization to the C-suite, and collaborating with the IT department. Creating a roadmap to utilize available technology, identifying future needs, and deciding whether to build or buy, all while maintaining a holistic view of the tax department's operating model are best practices. Companies adopting a top-down approach have seen more success in building this value case.
Source: ReAct agent: querying multiple PDFs

Here is the trace for one of them: What are the vulnerabilities introduced by relying on application programming interfaces (APIs) in Banking as a Service (BaaS)?

> Running step 0dc45634-70c7-4656-9b12-fc2b086848ce. Step input: What are the vulnerabilities introduced by relying on application programming interfaces (APIs) in Banking as a Service (BaaS)?
Thought: The current language of the user is: English. I need to use a tool to help me answer the question.
Action: tool_deloitte-tech-risk-sector-banking
Action Input: {'input': 'vulnerabilities of APIs in Banking as a Service (BaaS)'}
> Running step b574597e-591e-42f5-b2fe-075603369f1c. Step input: vulnerabilities of APIs in Banking as a Service (BaaS)
Thought: The current language of the user is: English. I need to use a tool to help me answer the question.
Action: vector_tool_deloitte-tech-risk-sector-banking
Action Input: {'input': 'API vulnerabilities in Banking as a Service (BaaS)'}
Observation: BaaS increasingly relies on application programming interfaces, introducing vulnerabilities that can pose risks for banks, such as customers' sensitive data and funds being at risk from phishing and social engineering attacks, flawed APIs providing a back door for hackers to penetrate banks' systems and noncompliance with data privacy rules by BaaS providers exposing partner banks to reputational risks.

> Running step ab6397c0-d075-499f-8d74-ce5ef25de495. Step input: None
Thought: I can answer without using any more tools. I'll use the user's language to answer
Answer: Banking as a Service (BaaS) relies heavily on APIs, which introduces vulnerabilities. These vulnerabilities can lead to risks for banks, including customer data and funds being at risk from phishing and social engineering, flawed APIs providing a backdoor for hackers, and noncompliance with data privacy rules by BaaS providers exposing partner banks to reputational risks.
Observation: Banking as a Service (BaaS) relies heavily on APIs, which introduces vulnerabilities. These vulnerabilities can lead to risks for banks, including customer data and funds being at risk from phishing and social engineering, flawed APIs providing a backdoor for hackers, and noncompliance with data privacy rules by BaaS providers exposing partner banks to reputational risks.
> Running step 8b2c762a-4a21-47ad-81f9-5dba4bb5e0f3. Step input: None
Thought: I can answer without using any more tools. I'll use the user's language to answer
Answer: Relying on application programming interfaces (APIs) in Banking as a Service (BaaS) introduces vulnerabilities that can put customer data and funds at risk from phishing and social engineering. Flawed APIs can also provide a backdoor for hackers. Furthermore, noncompliance with data privacy rules by BaaS providers can expose partner banks to reputational risks.

Read from the top, the trace shows the two levels at work. The top-level agent first retrieves its tools — with six documents and nodes_top_k at ten, all of them — then picks tool_deloitte-tech-risk-sector-banking, the one whose summary description matches the question, and calls it with a reformulated query. That call enters the per-document agent, which runs its own ReAct loop, chooses the vector tool over the summary tool since the question is about a specific fact, and gets back a passage on API risks in BaaS. It answers from that passage, and its answer is returned to the top-level agent as an observation, which then produces the final answer.

That nesting explains the apparent repetition. The block that looks like the agent answering twice is in fact the inner agent’s answer becoming the outer agent’s observation, one level up; it is the price of the two-level architecture rather than a quirk of the reasoning loop.

Two other things are worth noting. The routing works because the tool descriptions at the top level are the generated document summaries, which carry enough signal to match a question to a document; inside a document, by contrast, the tool descriptions are generic (“useful for questions related to specific facts”), and the choice between vector and summary tool rests entirely on the agent’s reading of the question. And compare_tool never fires here: the question concerns a single document, so the sub-question engine is not needed. It earns its place only on questions that genuinely span the corpus.

Conclusion

The structure extraction half of this works. A vision language model transcribes pages faithfully enough, a second pass rebuilds a heading hierarchy that page-by-page conversion cannot produce, and reports and decks end up with the two different representations they need: headings and line numbers for one, sections and page numbers for the other. The parsers turn those into trees that can be traversed or exported to a graph database, and the pipeline caches enough at each step that reprocessing a corpus is cheap.

The retrieval half works too, but separately. A per-document agent with a vector tool and a summary tool, a top-level agent routing on document summaries, and a sub-question engine for comparisons is a reasonable architecture, and the trace above shows it selecting the right document and the right tool. The join between the two halves is what is missing: TreeIndex cannot be queried, so the extracted hierarchy never reaches retrieval, and a question that a reader would answer from the contents page is still answered by embedding similarity over chunks. Section 1.4.2 gives the reason and the route forward is short — section labels stable enough to choose between, and a set of questions with known answers over these documents.

What the exercise settles, and what I would carry into the next system, is the format split. A report and a slide deck are not the same kind of object, and processing them alike throws away whichever structure each one has: a deck’s meaning is page-shaped, a report’s is heading-shaped. Deciding which is which costs one comparison on the first page’s media box, and that single bit pays for itself at every subsequent stage — reformatting, table of contents, parsing, retrieval.

The other thing worth keeping is the measurements. That a model told to preserve page markers keeps 62 of 62 in one document and invents 52 in another, or that one prompt returns an eight-entry outline for one deck and one entry per slide for the next, is not a detail: it is what tells you which stages of a pipeline like this can be trusted with a downstream dependency and which need a deterministic fallback underneath them. None of it is visible from the code, and all of it is sitting in the cache directory once you go and look.

Citation

BibTeX citation:
@online{brosse2025,
  author = {Brosse, Nicolas},
  title = {PDF {RAG:} Recovering Document Structure and Querying a
    Corpus},
  date = {2025-03-20},
  url = {https://nbrosse.github.io/posts/pdf-rag/pdf-rag.html},
  langid = {en}
}
For attribution, please cite this work as:
Brosse, Nicolas. 2025. “PDF RAG: Recovering Document Structure and Querying a Corpus.” March 20. https://nbrosse.github.io/posts/pdf-rag/pdf-rag.html.