About this talk
This talk presents a practical use case from the Banque de France, focusing on the application of large language models (LLMs) and natural language processing (NLP) techniques to automate the extraction of structured data from unstructured financial documents. The speakers detail how they transform lengthy PDFs into manageable information, ensuring data correctness through validation, explainability, and quality evaluation. They explain the construction of a knowledge graph using Neo4j to connect and enrich data from multiple sources like national registries and financial reports. The session explores advanced NLP strategies, including smarter chunking of documents and prompt optimization for improved entity extraction. Finally, the speakers showcase how they integrate a chatbot interface that allows analysts to interact with both structured and unstructured data, providing a comprehensive reasoning system that enhances financial analysis.
Full transcript
Yes, thanks. So, hello everyone. I'm Gabriel Lafitte, and with me is Alex de Cremoux, also machine learning engineer, and we both work in the artificial unit at the Banque de France. So, today at not AI, we wanted to share with you a very concrete use case. Over the past few years, we have been using LLMs and more broadly NLP techniques to automate tasks at the bank. And
one of our most common use case is turning unstructured documents into structured data. So, taking a 400 pages PDF and extract clean and usable information from it. But, extraction alone isn't enough. We need to know whether the data is correct. We need real-time quality, evaluation, explainability, and outputs that domain experts can use straight away. In this talk, we'll show you how we address these challenges using LLM
for extractions, Neo4j for validation and structuring, and a chatbot on top for analysts. Let's get started. Here is our agenda, four parts. So, why a central bank need a knowledge graph for corporate structures? Second, how we extract entities and relationship for PDF reports using LLMs. And third, how do we duplicate and match against the official registries. And fourth, Alex will take over the for the conversational agent.
So, let's go into the business context. Let me set the scene. Here is the landscape we are dealing with as a central bank. On the left, we have structured data coming from multiple sources, national registry, private registry, aggregators, international data sets. So, each of them is responsible of its own data quality. These sources can be linked together. And when you connect them, you get a solid baseline.
Standardized, machine-readable, and accessible via APIs. On the right, you got you have unstructured data. Things like PDF, newspapers, and online publications. So, it's literally text, images, plus a timestamp. So, the challenge now is to build a data processing layer that bring everything So, let's take a concrete example, GLEIF It's a unique identifier. For instance, an ID used to identify entities involved in a financial transactions. But, GLEIF
doesn't cover everything. Not every entity has an LEI. And not every relationship is So, we ask ourselves two key questions. First, how reliable is the data? Can we measure its quality and trust it as a baseline? And second, can we enrich it? Can we connect it with other sources to fill in the gaps and build a more complete pictures? This is where unstructured data become very valuable.
Take annual reports, for example. They're long public documents where company describe their structures, subsidiaries, partnerships, and joint ventures. Often, this often information exists nowhere else. And if we can extract that information and turn it into structured data, then integrate it with GLEIF, we can start comparing, we can start validating, and we can start enriching the data sets. And that's exactly what we've what we have built. how
does we go about this? On screen, you can see the full pipeline. We'll come back to several steps in details on the next slides, but let's list the full pipeline. Think of it as two tracks. The top tracks is our reference We live with a golden copy three times a day, every 8 hours. Each time we pull the delta, so what change, and we reshape the data
into nodes and relationships. And we and and then we'll load it into Neo4j. It's a classic ETL extract, transform, and load process, but the target is a graph, not a table. So, it's lightweight, it's incremental, it's fully automatic. the bottom track is easily lifting. That's batch process batch process. We identify entities we need to investigate. We go find their annual reports. These are public published online, and
we feed them into the document intake. So, then the NLP pipeline kicks in. We chunk the PDFs by chapter, structure way, not sliding window. So, each chunk carried deterministic metadata. Chapter name, page, range position. That's where we add the real value. So, because none of that is stochastic. Then the alarm extractions, entities, and relationships are structured JSON chunk by chunk. Once we have both track, the fresh
baseline and the batch everything's in stage four converge converges in Neo4j. This is where Neo4j's native graph powers really matters. So, we deduplicate. We match. We We match extracted entities against the baseline, and we compare structures not to nodes, relationships to relationships. And it's all those the volumes, millions of entities, thousands of comparisons. It's all those. And by the end of the process, we have built a
validated and rich knowledge graph. From there, in sta- in stage five, you can really start unlocking value through a semantic layer, which Alex will talk about in a few minutes. Let's go into the NLP enrichments. So, um The first step in the pipelines is chunking. And honestly, this is where we learned the most. So, when we started, we did the naive thing, fed the whole document to
the model one shot, and we got about like 15 entities back. Just the big name for chapter headings, everything in the footnotes, the appendices, the extracted lists, gone. The model wasn't bad. Maybe the prompt was bad, but we were just giving it too much. literally, we switched to structural way So, these are digital PDFs. They have a table of contents. Um so, we can read it. We
split by chapters, corporate overview, group structure, partnerships, risk factors, financial statements. Each one becomes its own chunks with its full context window. Same prompt, same model, we went from 15 to 150 entities. 10 times more just for smarter chunking. But there is another benefit people don't always think about. Once you have clean independent chunks, you unlock a lot of your on your infrastructure sites. Each is a
self-contained request. So, you can paralyze massively, you can batch, you can scale. And you don't need the biggest model for every chunk. Some chunks are simple. Some are complex. You can root accordingly. For this demo, we used Gemini 3.5 Pro. But in production, having small independent chunks mean that you could use a lighter model. uh maybe on premise, that matter for cost, for digital sovereignty, and for
not throwing your entire infrastructure um at tasks that don't need. And for private confidential data, you have to use on premise LLMs. And the last one is trustability. Each chunk carries deterministic metadata, chapter names, page range, That doesn't come from the LLMs. It's come from the PDF structure. So, when you we extract something, we always know exactly where it came from where it came from. And in
a supervision context, if you can't explain the providence, the data is useless. On screen, you can see what it looks like in Neo4j. Each node is a chunk linked to the next. On the right, the property field, the property the properties file name, position, length, text contents. That's our foundation. okay. Now, we have our chunks. But what do we actually tell them all? We didn't just write
a prompt and hope for the best. Well, at least we did it the first time. But, we optimize it. The approach is inspired by a method a method called automatic prompt optimizations. It is from a paper from Pritz Salt published in 2023. The core idea is simple. Think it of a gradient descent button You take a prompt. You run it on few labeled examples so paragraph when
you know already already the answer. And you look what the model got wrong. When we And then you rewrite the prompt to fix those mistakes. Did it meet links? Did it meet no property? Did Did he miss some data? You make the instruction clearer. or you just add an example that cover that case. And then you run it again. If it improve, you keep the change. If
it's over fits, you roll back and you repeat. The beauty of fits is that you don't need a huge data training. used training set. You need like 10 to 20 annotated to to do so, not thousands. And they this all thing is modular. The graph schema, the entity types, the relations types, it's a parameter. So, you can um So, actually we used like seven entity types and
seven entity relationships types aligned with life. But, if tomorrow we need to process ECG reports, for example, we swap the schema the schema, we label a few example, and it adapts. you can see left one chunk one extractions, and on right the full graph. It It example of an entire report. So, let's go into the entity resolution. I just want next slide. At this point, we have
two things in Neo4j. The Glyphs data. It is the data we need to check. And the LM extraction coming from the annual report that has been verified and that now we can trust. The question is simple. Does what we extracted actually match Glyphs data? First thing we do is deduplication and create connection between extracted structures and Glyphs. We are making a bridge to see like if same
company, different names across chapters, and we need to find if uh we need to find the entities in the Glyphs uh baseline. So, we merge we merge on normalized data plus jurisdictions. So, that takes us from 150 um extractions down to 80 uh distinct So, now the interesting part. So, we are comparing the extracted structures against the Glyphs data. So, but we don't just check the entity
by entity uh process. We compare at five different levels. So, let me walk you through the key ones. First, entity overlaps. Are this the company present? Are the companies the same uh in both graphs? So, we use Jaccard similarity. And if you find like three common uh entity out of five, that is like 60 of the groups confirmed. Good start. Second, the structure. So, this is where
it gets uh topological. Um we are not just asking are the same node here. We are asking if they share the same. So, the control chains death death the hierarchical. So, we use graph edit distance for this. A score of one means one link is different. The structures are almost identical. Third, centrality. Is the same entity at the top. If entity A is holding company in both
graphs, great. But, if it's a different entity, that's information we need. Something needs to be uh some we need a closer look. But, we also compare links and attributes also. But, you get the idea. So, five levels from the big pictures down to the details. And the key points all of these run in Neo4j. Centrality algorithms, graph comparisons. No need to ex- port anything to like a
relational database. And at the end, we are creating extracted nodes with all the informations about these comparisons to have enriched nodes. And that we can push into the semantic layer. All right. That covers extractions, validations, and a graph. That's my part done. Now, the real questions. You have this beautiful knowledge graph, but how do people actually use it? That's where this gets really cool. So, Alex is
going to show you how we put a chatbot on top of this. Thanks, Gabriel. So, we now have two complementary layers. A trusted corporate graph providing authoritative relationships on a side and a noisy, but valuable enrichment layer from another side, which data extracted from documents. The key question now is how do users reason over both? This is where we move from graph construction to graph construction through
an agent. Before the architecture, let's see what this enables in practice. With a small demo. We start with a question asking for a company and its subsidiaries as we were a business analyst. I think some pause. Sorry. Sorry for the delay. So, at this point, the agent kicks in. It routes the request to the right domain specific path. Because in fact, we have multiple sub agents that
can query either the graph database, but also other database that are based on classical database for classical org. Before we go Okay. Thanks, Amir, from the chats. So, before we go further, there is a key step, human in the loop validation, because in real data, multiple entities can match the same name, and we do not want the system to decide for the user. We want the system
to ask the user to clarify its mind and to confirm whether the found entity is the right one. While the system is reasoning, it is producing a lot of output that could be auditable by the user. For example, the user is able to see the all the steps taken by the agent, also how the human in the loop was taken into account, and also, of course, the
retrieved data from the graph. So, this can be visualized in multiple ways. The user is able to see the Cypher query, but also the retrieved data as a good tab, but also as a graph, of course. Now, let's move to a second question. So, we are going to take a a sub surgery found from the parent and ask for its enriched data. This time, the system go
differently and think in a different way. It goes beyond structure. It retrieves document derived sign offs. So, the chatbot responds with all extracted information from related financial documents. But importantly, we still keep the graph hard context. So, every piece of extracted information is grounded in the graph structure. We also kept the visualization visualization layer, so you the user can still see the graph traversal and the retrieved
entities. We are currently adding one more layer on top of it, a document level visualizer. So, users can open the exact chunk where the signal came from and see directly inside the document for editability purpose. So, what we are building here is not just a chatbot. It's a system that connects questions, graph reasoning, document evidence, and visual traceability. Classical rag works well for local facts, but it
breaks when questions become multi-step, and in finance, they almost always are. The issue is simple. Rag retrieves text, but it does not understand structure, or it does poorly, very poorly. Graph rag changes that in the way that it moved from retrieving text to navigating relationships. Let's take a concrete example. Which subsidiaries show risk signals? To answer this question, we need to go a reasoning path. First, by
identifying the parent, then traversing ownership, and following by collecting subsidiaries, and finally aggregating signals. And this need to combine deterministic structure, the graph, and probabilistic signals with NLP. And importantly here, we are not reconstructing the structure from text. We trust Glyfo the structure and use NLP only for enrichment purposes. Even with graph hugging, queries remain complex and ambiguous. So, we introduce an agent not as a not
as a chatbot, but as a reasoning system. The agent takes a question, breaks breaks it into steps, decide which tool to use, graph traversal, semantic search, it choose. Some Most of the time it's both and it needs to be combined in a meaningful way. Then, it combines all the tools outputs into a structured answer. In fact, the agent doesn't know anything. It only coordinates the tool. Uh
all the tools um some tools some tools can be very simple and generic, but some really depends on the domain domain business. On the business domain, sorry. About explainability, which in finance is highly critical, we need trustable step, explicit tool usage, and reproducible reasoning. We also add human in the loop validation, so users can validate entities and also correct and enrich relationships if they are false or
partially incorrect and also refine synonyms. So, this is not a black box. It's a entirely controllable system that is going to improve through time. And this controllable system is based on a unified data layer that is Neo4j. In fact, we use Neo4j for three purposes. First, to build our domain which is based on corporate structure. Secondly, as a virtual layer to search into documents and evidence. And
thirdly, as an agent memory layer to store the history and the reasoning steps. It's important to distinguish two databases. In fact, we separate domain graph and vector from the agent memory layer. Because the business graph is re-authoritative when the agent memory is dynamic. This improves traceability, debugging, and control. And also, it allow us to deeply manage permissions as we deeply not want our agent to introduce new
nodes or change the structured data that we should trust and not modify at all. There are some random tools like LangChain that allow us to quickly build that kind of agents and workflow. And it's also allow us to have one unified stack instead of multiple system that allow us to go quicker to production. So, let's go to our end-to-end architecture from a consuming side. At the center,
you can see the conversational agent that orchestrates everything. And it relies mostly on two capabilities. On the left, the graph database capabilities of Neo4j, which is mostly for query structured data. And on the right, the vector retrieval capacities of Neo4j. The key idea here is that the two capabilities are highly connected. As Gabriel explained, we linked the entity within the structured data to the document which they
appear in. So we Here we the agent don't have to choose between text and structure. It combine both and leverage each of them separately and together. The agent uses this to build reasoning steps and produce explainable answer. We also kept memory for traceability and human validation for control. So in the end, we move from fragmented systems to a unified reasoning platform. To conclude, we move from fragmented
financial data sources to a unified reasoning system. We combine multiple trusted structured data, document understanding, and agent-based The key idea here is simple. We are not replacing structure with AI. We are augmenting the structure with AI. In order to to add traceability, human validation, and a uniform unified platform like Neo4j. This become deployable in a real financial context with high needs on security, for example. So ultimately,
I would like to emphasize that it's not only a chatbot, it's a highly reasoning system. Thank you very much. We're happy to take your question now. And if you have time, we'd really appreciate your feedback. Let the cure put in the right. So I I saw in chat different questions are already being respond by articles. Mhm. Articles. So, do you have uh other questions? Uh yes, regarding
the Maybe I can take the one regarding the visualization. As Tikus answered, we are using Neo4j and VR. It happens to be the simplest tool to do so. And also, there are a lot of tutorials online. Uh for for the chunks methods, you are absolutely right. Like we we went from this method because we we end those uh financials reports. And those financial reports are uh are
following strict a strict method. Like there is a a table of contents on it. So, it's why we decided to to pass this. But there is a a fallback theoretical back into um a chunking method um really uh based on the number of token your model can handle. Uh so, there are also some questions in the Q&A section. we do not have a good good GitHub now.
Uh as we are in a an institution for and have a very high constraints on security, we cannot share this for now. Okay, how did you get the domain user feedback on the fine-tuning of prompts? But we are working uh at the Banque de France, so we have um we have a user feedbacks for for for the prompts. And I can see Connie About the About the
chat interface, it's custom For now, we are not ready to to deploy this interface in production. It's only for testing purposes. And the we have a dedicated team that is working on building interface compliant to the EU AI Act. And thanks. I think we are done for this session. If you have any further question, feel free to connect either through our mails or LinkedIn.
More from this event
See all 37 talks →
NODES AI 2026 - Agentic GraphRAG: Autonomous Knowledge Graph Construction and Adaptive Retrieval
11:51
NODES AI 2026 - Semiont: A Graph Based, AI Native Wiki and Annotator
29:48
NODES AI 2026 - MemMachine: Agents That Learn, Memory That Lasts
30:03
NODES AI 2026 - Ghost-busting with Neo4j Graph Analytics in Snowflake
28:47