Thousands of documents, one honest agent.
Ground it
The Warranty Desk agent again, but answering from three thousand documents through a Foundry IQ knowledge base on Azure AI Search, with a hit rate you measured instead of a feeling.
- build time
- 5 to 7 hours
- cost
- Under $12 if torn down the same day3
- services
- Foundry Agent Service, Foundry IQ, Azure AI Search, Blob Storage, Entra ID, Application Insights
- assumes
- Project 01. Keep its agent and its instructions file; you replace one tool.
- exams
- Overlaps AI-103, AI-200
- vocabulary
- Knowledge base, knowledge source, agentic retrieval, chunk, groundedness, hit rate, citation
The problem
Three policy PDFs was the demo. Campux Retail actually has 3,000 documents: manuals, recall notices, regional policies, supplier warranties, most of them PDFs nobody has opened since they were uploaded.
File search was right for three files and wrong for three thousand. The head of support has two new requirements. First, when the agent quotes a policy it has to say which document and which page, so a person can check it. Second, she wants a number: out of a hundred real customer questions, how many did the agent answer from the right document. Not "it seems good." A number, and a way to get it again next month after the documents change.
- definition
- Agentic retrieval. Instead of one search for the user's words, the knowledge base plans several searches, runs them, checks whether the results are good enough, and searches again if not. Foundry IQ is that engine, running inside Azure AI Search, exposed to your agent as one tool.
The architecture
One tool swapped. The agent does not read 3,000 documents; it asks a knowledge base that does.
- Sign in. The customer opens the same Streamlit app and signs in with Microsoft Entra ID.
- Call the agent. The app calls the Warranty Desk agent as the customer.
- Reason. The model decides the question needs the knowledge tool.
- Ask the knowledge base. The Foundry IQ tool passes the customer's question, not a search query.
- Agentic retrieval. Azure AI Search plans several searches, runs them, checks relevance, reranks.
- Read the documents. Chunks come back from the indexed Blob source with document and page references.
- Score it. The cited document is compared with the expected one; groundedness is scored.
- Trace it. Hit rate and groundedness are recorded per run in Application Insights.
| Job | AWS version | This build | Same idea? |
|---|---|---|---|
| Knowledge base | Bedrock Knowledge Base | Foundry IQ knowledge base on Azure AI Search | Yes. Foundry IQ plans and re-runs queries itself |
| Documents | S3 data source | Blob Storage knowledge source | Yes |
| Index and ranking | OpenSearch Serverless | Azure AI Search, hybrid plus semantic ranking | Yes |
| Retrieval tool | Agent action group | Foundry IQ tool on the agent1 | Yes |
| Quality number | Bedrock evaluations | Foundry evaluators: groundedness, retrieval | Yes. Project 03 goes deep |
| Identity | IAM | Managed identity, Search Index Data Reader | Different |
The build
In this order. Step 2 is where most of the time goes; step 7 is the number she asked for.
-
Start from Project 01
Same Foundry project, same agent, same instructions file. Create an Azure AI Search service (Basic tier is enough) and a Blob Storage container called
The Project 01 agent still answers from its three PDFs. Nothing is broken yet.policies. -
The documents
Generate 3,000 synthetic policy documents from a script: 40 product lines, 5 regions, 3 years of revisions, and a handful of deliberate contradictions where a newer document supersedes an older one. Upload them to the container.
3,000 blobs. You can name three that contradict each other and say which one is current. -
Knowledge source and knowledge base
In Azure AI Search, create a knowledge source pointing at the container (indexed, with the indexer's execution environment left default for now) and a knowledge base over it. Give the Search service a system-assigned identity with Storage Blob Data Reader on the container.
The index reports about 3,000 documents and the indexer run shows zero failures. -
Swap the tool
Remove file search from the agent. Add the Foundry IQ knowledge tool pointing at the knowledge base.1 Give the agent's identity Search Index Data Reader on the service. Change one line of the instructions: "cite the document title and page for every policy statement."
"Is water damage covered on an AquaGuard washer sold in Ohio in 2025?" returns an answer with a document title and page, and the document is the current one. -
Make it refuse
Ask about a product that does not exist. Then ask about a real product with a question none of the 3,000 documents answers. Add to the instructions: "if the knowledge base returns nothing relevant, say so and offer a person; never answer from general knowledge."
Both questions get "I could not find that in our policies" and a handoff offer, not a guess. -
Evaluation set
Write 100 questions with the expected document for each, including 15 that should get a refusal. Half from the support team's real inbox, rewritten; half adversarial: superseded policies, near-duplicate product names, a region that does not exist.
A CSV with 100 rows: question, expected document, expected behaviour. -
Measure the hit rate
Run all 100 through the agent with tracing on. For each, record whether the cited document matched the expected one. Run the Foundry groundedness evaluator over the answers. Write the two numbers down.
You have a hit rate, a groundedness score, and a list of the misses. Now run the identical set a second time. Ours moved from 5/15 to 9/15 with nothing changed, so a single run is not a measurement; two runs of the same set tell you how much of your number is noise before you start attributing changes to your fixes.4 -
Fix the worst miss, measure again
The misses cluster on superseded documents outranking current ones. The filter does not live on the knowledge source, which accepts little more than an index name; it goes on the retrieve call, as
filterAddOninsideknowledgeSourceParams. Index a boolean you can filter on, pass it per request, and rerun the same fifteen questions.4"knowledgeSourceParams": [{ "knowledgeSourceName": "policies-ks", "kind": "searchIndex", "filterAddOn": "superseded eq false" }]Ours went from 5/15 and 9/15 unfiltered to 15/15 twice with the filter, and the average references per question dropped from 13 to 7. Two numbers moved: accuracy up, and the amount of text the model had to read down. -
Tear it down
azd down
Then delete the Search service and the storage account by hand;
The resource group is empty. Today's cost is under $12.azd downonly removes whatazdmade.
python measure_hit_rate.py no filter: current doc ranked first 5/15 ( 33%), avg 13 refs/query no filter, 2nd pass: current doc ranked first 9/15 ( 60%), avg 13 refs/query filterAddOn applied: current doc ranked first 15/15 (100%), avg 7 refs/query filterAddOn, 2nd pass: current doc ranked first 15/15 (100%), avg 6 refs/query 33 then 60 with no change at all: that gap is the noise floor of a single run.
Where it breaks
Cause each one on purpose. Retrieval fails quietly; these make it loud.
The trade-offs
- Foundry IQ, or plain Azure AI Search as a tool?
- A plain search tool runs the query you give it. Foundry IQ plans several, checks the results, and tries again, which is what makes it survive vague customer questions. The cost is more searches per turn and a preview label. This build takes the preview because the hit rate is the point.
- Indexed, or remote knowledge sources?
- Indexing Blob content gives you ranking, filters and version metadata. Remote sources such as SharePoint are queried live and stay where they are. Policies are documents you own; index them.
- Refuse, or answer with a warning?
- "I could not find that" loses a customer who could have been helped. "Here is my best guess, please confirm" invents warranty terms. For warranty, refuse and hand off; the cost of a wrong answer is a refund.
- One run, or several?
- Agentic retrieval plans its own queries, so the same question set does not return the same thing twice. Two identical unfiltered passes scored 33 and 60 per cent for us. Any change smaller than that gap is invisible in a single run, which means a number you took once cannot tell you whether your fix worked.
- Measure with a hundred questions, or a thousand?
- A hundred gives you a number with a wide margin and a list of misses you can read in an afternoon. A thousand gives a tighter number and a list you will not read. Start at a hundred; grow it when the misses stop clustering.
In the interview
"How do you stop a RAG agent making things up?"
- decisionA knowledge base that returns real chunks with references, an instruction to cite only those, and a refusal path when nothing relevant returns.
- reasonThe model cannot hallucinate a citation it was never given, if it is only allowed to cite what it was given.
- watchedA 100-question set with expected documents, scored before and after each change.
"What was your hit rate?"
- decisionMeasured, not estimated: the percentage of questions where the cited document matched the expected one.
- reasonA support lead cannot act on "seems good"; she can act on "82, and the misses are superseded documents."
- watchedThe before and after of one index change.
"Why Foundry IQ over a search call?"
- decisionAgentic retrieval: it rewrites and re-runs queries and ranks across them.
- reasonCustomers do not ask in the words the policy uses.
- watchedCost per question, since it searches more than once.
Evidence
- The number, twice
- Hit rate and groundedness before and after the version filter, with the date.
- One miss, explained
- A question, the wrong document it cited, the right one, and the index change that fixed it.
- The repo
- The document generator, the evaluation CSV, the index definition, and the scoring script.
- One sentence for the résumé
- "Grounded a support agent in 3,000 documents using a Foundry IQ knowledge base on Azure AI Search, with citation enforcement, a refusal path, and a measured retrieval hit rate tracked across index changes."
Next
Notes
- Foundry IQ and its agent tool were in preview when this was written (September 2026), and the tool reaches the knowledge base over MCP. Names and the exact portal steps were checked against Microsoft Learn on 2 September 2026; if they have moved, the Learn page wins.
- Azure AI Search knowledge bases can span several knowledge sources, including Blob Storage, SharePoint and OneLake. This project uses one indexed Blob source so the version filter is yours to control.
- Built and run in a real Azure subscription on 3 September 2026, against Azure AI Search Basic in East US with 50 synthetic policy documents, half of them superseded revisions, using API version
2026-08-01-preview. Findings: a knowledge source of kindsearchIndexaccepts essentially onlysearchIndexName, so the filter belongs on the retrieve call; the knowledge base reference takes a bare{"name": ...}and rejects akind; and retrieval is not deterministic, which is why the check asks for two passes. Preview shapes move, so verify the payload against Learn on the day. - "Under $12" assumes a Basic Search tier, 3,000 small synthetic documents, one 100-question run, and teardown the same day. Search is billed by the hour while it exists; that is the line item that grows if you forget step 9.