AutomotiveMulti-agent system and data platform
Dealer service agents
5,000 dealerships across Europe, and everything a dealer needed to know sat in systems they could not query: about 70TB of unstructured pages in a legacy Notes application, and the operational systems behind it. A multi-agent system now takes the question in plain language and routes it to whichever agent can actually answer it, with the asker's scope resolved once and carried into whichever pipeline runs.
The problem
A dealer needing a warranty term, a vehicle specification or an order status had no way to look it up. The records sat in a Notes application holding about 70TB, with no schema and no index.
So they called HQ and waited. An answer that already existed inside the business took hours or days to come back.
Scrolls sideways.
The solution
Retrieval is the obvious answer and only part of it. A question like “how many orders did I close last month” has nothing written down to retrieve, and a retrieval agent asked for it will still return something.
So a LangGraph supervisor resolves who is asking, classifies the question, and routes it to one of four agents: retrieval, text to SQL, an action queued through RPA, or a person.
Scope is resolved once and travels with the request. On the retrieval path the dealer filter goes into the query. On the SQL path it goes into the WHERE clause. Filtering afterwards would still have shown the model data it was not allowed to see.
Scrolls sideways.
How it works
Supervisor
LangGraph orchestrates the whole exchange. It resolves identity, classifies the request, picks the agent, and assembles the reply. It carries no domain knowledge of its own, so when an answer is wrong it is clear which agent produced it.
Scope resolution
Role and dealer identifier come from the authenticated session, never from the question. Scope is resolved once, at the top, and travels with the request into whichever pipeline runs.
Retrieval agent
Answers from the document corpus in pgvector, for specifications, warranty terms, parts and service history. The dealer filter is applied to the query rather than to the results, so out-of-scope records never reach the model. The first release ran on Azure AI Search, and that was deliberate: the fastest way to show the client that 70TB of legacy pages could be queried at all was a managed index, not a bespoke one. Once that was settled the binding requirement changed from speed to governance, and pgvector is what allowed the scope filter to sit inside the retrieval query itself. On a smaller corpus that changes often, AI Search is still the better answer.
Text to SQL agent
Writes SQL against the Synapse gold layer for counts, totals, trends and order status. The dealer identifier is injected into the WHERE clause, so the same scope rule holds on a path where retrieval filtering would not apply.
Action agent
Some requests are not questions. Raising a warranty claim or ordering a part is a transaction, so it is queued against the backend system through RPA rather than answered in conversation, and the queue state is visible and tracked.
Escalation
Anything legal, contractual or genuinely ambiguous is handed to a person with the context already gathered. Knowing when not to answer is a design decision, not a gap.
Ingestion and data platform
A change listener crawls the Notes application and Azure Functions embed in parallel, because 70TB run sequentially would take weeks and keep hitting the rate limit. Four of the engineers on this project worked on nothing but getting data out of that application. In parallel, Data Factory orchestrates the nightly load, Databricks conforms it, and Synapse serves the gold and rpt schemas that both the SQL agent and the Superset dashboards read.
Observability and audit
Every agent run is traced in LangSmith, with the routing decision, the retrieval step and the tool calls. Every query and response is written to the audit log with the user and the time, and thumbs up or down is captured against the run.
Where it runs
Scrolls sideways.

Stack
Orchestration
AI and models
Retrieval
Warehouse and text to SQL
Ingestion
Actions
Hosting and infrastructure
Analytics
Product screens
The Superset and routing screens are real, with client identifiers removed. The agent, widget and trace views are redrawn from the product because the originals carried client branding that cannot be published. Behaviour, fields and controls are as built.
Results
Before
Days per questionA dealer needing a specification, a warranty term or an order status called or emailed HQ, who searched the legacy database and the warehouse by hand.
After
SecondsAsked in plain language and answered from the documents or from the warehouse, scoped to that dealership. The system now carries around 200,000 questions a week that would otherwise have gone to HQ, across 5,000 dealerships.
What did not go to plan
Four of the eight to nine engineers were data engineers working only on extraction. That ratio is the honest shape of a 70TB legacy estate, and it is the number I would give anyone who assumes the model is the hard part.
The connector took far longer than planned, embedding kept hitting the rate limit until it was fanned out across functions, and burst load exposed missing connection pooling. There is still no minimum retrieval score, which is the first thing I would add.
What this demonstrates
- 01Multi-agent routing where retrieval is one of four paths, not the whole system
- 02Governance resolved before retrieval: the dealer filter sits inside the query and the WHERE clause
- 03A 70TB legacy estate made queryable, with the extraction effort planned as the largest line
- 04A full Azure data platform (Data Factory, Databricks, Synapse) serving both the agents and the BI
- 05Operation at around 200,000 questions a week with per-run tracing and an audit log
Next caseRequirement compliance platform