MSAZ-111 · Lesson 5 of 12 · 23 min

Grounding answers with your own data

▶ Video coming soon A video version of this lesson is on the way.

Maya types a test question into her chat client: "Can I return a cut length of chain if I bought too much?" Ask Finch answers confidently that cut items can be returned within 30 days with a receipt. It sounds right. It is wrong. Harrow & Finch's policy says custom-cut products, including chain, rope, carpet and lumber cut to length, are final sale. The model has never seen the policy, so it produced the most plausible-sounding answer from everything it learned in training. Arjun calls this the most important lesson of the course. "A model knows a great deal about the world in general and nothing about us in particular," he says. "Grounding is how we tell it about us."

What grounding means

Grounding means giving the model the specific information it should use to answer, at the time it answers, and instructing it to rely on that information. The most common way to do it is retrieval-augmented generation, usually shortened to RAG. When a question arrives, the application first retrieves the passages from its own documents that are most likely to contain the answer, then sends those passages to the model along with the question and an instruction to answer from them. The model's job changes from remembering facts to reading and summarizing the facts it has been handed.

Grounding does three useful things at once. It makes answers accurate for information the model never saw, such as Harrow & Finch's policies. It keeps answers current, because updating a document updates the answers without retraining anything. And it makes answers checkable, because the application can show which passages the answer came from, which supports the transparency principle Maya studied in the first course.

A pipeline in two rows. Top row, prepared in advance: documents such as the return policy and product manuals are split into chunks, turned into vectors by an embedding model and stored in a search index. Bottom row, for each question: the question is turned into a vector, the index returns the closest chunks, the chunks and question go to the chat model with grounding instructions, and the answer comes back with citations.
Retrieval-augmented generation: prepare the index once, then retrieve and generate for every question.

Step one: preparing the documents

Retrieval only works if the documents are ready to be searched. Preparation has three parts.

First, gather and clean the sources. For Ask Finch, that means the return policy, the store hours list, the warranty terms and a few hundred product manuals, stored in the Blob Storage account that Arjun connected to the project in lesson 1. Out-of-date versions are removed, because a model grounded in last year's policy will quote last year's policy.

Second, split the documents into chunks. A whole manual is far too long to send with every question, and most of it is irrelevant to any one question. Chunks of a few hundred words, often overlapping slightly so that a sentence split across a boundary still appears whole in one chunk, give the retriever pieces small enough to be precise and large enough to make sense on their own. Each chunk keeps a note of the document and section it came from, which later becomes the citation.

Python Example
# Split a document into overlapping chunks of words, keeping the source for citations.
policy = ("Most items can be returned within 30 days with proof of purchase. "
          "Custom-cut products, including chain, rope, carpet and lumber cut to length, are final sale. "
          "Special orders can be returned only if they arrive damaged. "
          "Opened power tools can be returned within 30 days if all parts are included. "
          "Gift cards cannot be returned or exchanged for cash.")
def chunk(text, size=20, overlap=5, source="return-policy"):
    words = text.split()
    step = size - overlap
    out = []
    for start in range(0, len(words), step):
        piece = words[start:start + size]
        out.append({"source": source, "part": len(out) + 1, "text": " ".join(piece)})
        if start + size >= len(words):
            break
    return out
for c in chunk(policy):
    print(c["source"], c["part"], "|", c["text"])
Output
return-policy 1 | Most items can be returned within 30 days with proof of purchase. Custom-cut products, including chain, rope, carpet and lumber
return-policy 2 | chain, rope, carpet and lumber cut to length, are final sale. Special orders can be returned only if they arrive
return-policy 3 | returned only if they arrive damaged. Opened power tools can be returned within 30 days if all parts are included.
return-policy 4 | if all parts are included. Gift cards cannot be returned or exchanged for cash.

What this code does

Splits a returns policy into overlapping chunks of about 20 words and labels each chunk with its source and part number. The overlap keeps ideas that cross a boundary intact, and the labels let the assistant cite where an answer came from. This is the first step in grounding answers in company documents.

Third, index the chunks. A search index is a store built for fast lookup. For RAG on Azure, the usual index is Azure AI Search. Each chunk is stored with its text, its source and, for semantic search, a vector produced by an embedding model.

An embedding model, introduced in lesson 2, turns a piece of text into a list of numbers, often hundreds or thousands long, called a vector. Texts with similar meanings get vectors that point in similar directions, even when they share few words. "Can I bring back chain I had cut?" and "Are custom-cut products returnable?" use different words but mean much the same, and their vectors are close. Vector search finds the chunks whose vectors are closest to the question's vector, usually by measuring the angle between them, a calculation called cosine similarity.

Python Example
# Cosine similarity between tiny made-up "embedding" vectors.
import math
def cosine(a, b):
    dot = sum(x * y for x, y in zip(a, b))
    return dot / (math.sqrt(sum(x * x for x in a)) * math.sqrt(sum(y * y for y in b)))
question = [0.9, 0.1, 0.8, 0.0]          # "Can I return chain that was cut for me?"
chunks = {
    "custom-cut items are final sale": [0.8, 0.2, 0.9, 0.1],
    "store hours on holidays":          [0.0, 0.9, 0.1, 0.7],
    "returning opened power tools":     [0.7, 0.1, 0.3, 0.2],
}
for name, vec in sorted(chunks.items(), key=lambda kv: -cosine(question, kv[1])):
    print(f"{cosine(question, vec):.3f}  {name}")
Output
0.987  custom-cut items are final sale
0.918  returning opened power tools
0.123  store hours on holidays

What this code does

Measures cosine similarity between a question's tiny made-up embedding and the embeddings of several document chunks, then ranks the chunks by score. The chunk about custom-cut products scores highest, so it is the one that would be retrieved. This shows how vector search finds the most relevant text by meaning.

Real embeddings have far more numbers, but the principle is the same: the closest chunk, here the one about custom-cut items, is retrieved first. Keyword search still has a place, because exact terms such as product codes and store names are matched more reliably by words than by meaning. Azure AI Search supports hybrid search, which runs keyword and vector search together and merges the results, and an optional semantic ranker that re-orders the top results using a language model. For most RAG solutions, hybrid search with semantic ranking is a sensible default.

Step two: retrieving and generating

With the index built, each question follows the same path. The application turns the question into a vector, asks the index for the best few chunks, and builds a prompt that contains the grounding instructions, the retrieved chunks with their sources, and the question. The model answers from what it has been given, and the application shows the answer with links or labels for the sources.

Python Example
# Build a grounded prompt from retrieved chunks (the model call itself is not shown).
retrieved = [
    {"source": "return-policy", "part": 2, "text": "Custom-cut products, including chain, rope, carpet and lumber cut to length, are final sale."},
    {"source": "return-policy", "part": 1, "text": "Most items can be returned within 30 days with proof of purchase."},
]
question = "Can I return a cut length of chain if I bought too much?"
sources = "\n".join(f"[{c['source']} {c['part']}] {c['text']}" for c in retrieved)
prompt = ("Answer the customer using only the sources below. "
          "Cite the source in brackets after each fact. "
          "If the sources do not contain the answer, say you are not sure and offer a person.\n\n"
          f"Sources:\n{sources}\n\nQuestion: {question}")
print(prompt)
Output
Answer the customer using only the sources below. Cite the source in brackets after each fact. If the sources do not contain the answer, say you are not sure and offer a person.

Sources:
[return-policy 2] Custom-cut products, including chain, rope, carpet and lumber cut to length, are final sale.
[return-policy 1] Most items can be returned within 30 days with proof of purchase.

Question: Can I return a cut length of chain if I bought too much?

What this code does

Builds a grounded prompt from chunks that have already been retrieved: it lists each chunk with its source label and tells the model to answer only from those sources and cite them. The printed prompt is what would be sent to the model. The model call itself is left out.

The instruction to answer only from the sources and to admit when they do not contain the answer is as important as the retrieval itself. Without it, a model may blend retrieved facts with remembered ones. With it, Ask Finch now replies that custom-cut chain is final sale and cites the return policy, which is exactly what a trained contact-center agent would say.

Grounding options in Foundry

Foundry offers several ways to add grounding without building every step by hand, and the right one depends on how much control is needed.

Ways to ground a solution in Foundry.
OptionWhat it doesWhen to use it
File search tool for an agentUpload files to an agent; Foundry chunks, embeds and indexes them for the agent to searchSmall, simple collections and quick prototypes
Azure AI Search indexConnect an index you build and control, with keyword, vector, hybrid and semantic searchLarge collections, custom chunking, security trimming and full control
Foundry IQ knowledge baseA managed knowledge layer over Azure AI Search that plans queries, searches several sources and returns cited results with permissions appliedAgents that need several sources, such as storage, SharePoint and the web, with permission-aware answers
Your own codeRetrieve from any store, such as a database, and add the results to the promptData that changes by the second, such as order status

Foundry IQ deserves a note because it is new. Microsoft's documentation describes it as a managed knowledge layer: you create a knowledge base that points at one or more knowledge sources, such as Blob Storage, SharePoint or OneLake, and agents query the knowledge base. Behind the scenes, Azure AI Search does the indexing and retrieval, can break a complex question into several searches, applies the caller's permissions and returns passages with citations. Some of its features were still in preview when this course was written, so check the current status before relying on them.

Order status is different from policy text. It changes constantly and belongs to one customer, so it should not be copied into a search index at all. Ask Finch will look it up through a tool that calls the StockLine order system with the customer's verified identity, which is the subject of lesson 6. Grounding is not only search over documents; it is any way of handing the model the right facts at the right moment.

Security and privacy in grounding

Whatever the model can read, it can repeat. If the index contains documents a customer should not see, a cleverly worded question may surface them. Carmen Ortiz sets two rules for Ask Finch. Only public, customer-facing documents go into its index; internal procedures and staff notes stay out. And any personal information, such as an order history, is fetched only for the verified customer in the current session, never from a shared index. For internal assistants that do need restricted documents, Azure AI Search and Foundry IQ can filter results by the user's permissions, so a person sees only passages they are already allowed to open.

Worked problem

How much does grounding add to each request?

Ask Finch retrieves the top 4 chunks for each question. Each chunk is about 180 tokens, the grounding instructions are 60 tokens, and the question and recent history average 300 tokens. How many input tokens does a typical grounded request use, and what share of it is retrieved text?

Show solution
  1. Retrieved text: 4 × 180 = 720 tokens.
  2. Total input: 720 + 60 + 300 = 1,080 tokens.
  3. Share that is retrieved text: 720 ÷ 1,080 ≈ 0.67, about two thirds.

Answer: About 1,080 input tokens, two thirds of them retrieved text. Retrieving fewer, better chunks is the most direct way to cut cost, which is one reason semantic ranking is worth its small extra charge.

Testing grounded answers

Maya reruns the fifty test questions with grounding switched on. Answers about policy are now almost all correct, and each comes with a citation she can check. Two kinds of failure remain, and both are retrieval problems rather than model problems. When a question uses words the documents never use, such as "refund my wood" for lumber, the right chunk is sometimes missed; hybrid search with semantic ranking fixes most of those. And when two documents disagree, because an old store-hours page was never deleted, the model sometimes quotes the wrong one; removing the old page fixes that. Lesson 12 shows how to measure groundedness and retrieval quality formally.

Common mistakes

  • MistakeGrounding retrains the model on your documents.

    InsteadGrounding supplies relevant passages with each request; the model itself is not changed.

  • MistakePutting every document into the prompt is the best way to ground a model.

    InsteadRetrieve only the most relevant chunks; whole documents waste tokens and can bury the answer.

  • MistakeAnything in the search index is safe to expose through a public assistant.

    InsteadA model can repeat whatever it reads; keep private documents out or filter by the user's permissions.

Summary and key terms

  • Grounding gives the model the specific information to answer from, at the time it answers.
  • Retrieval-augmented generation retrieves relevant passages and sends them with the question and grounding instructions.
  • Prepare documents by cleaning them, splitting them into chunks with sources, and indexing them.
  • Embedding models turn text into vectors; vector search finds chunks with similar meaning; hybrid search adds keyword matching.
  • Azure AI Search is the usual index; Foundry also offers an agent file search tool and Foundry IQ knowledge bases.
  • Instruct the model to answer only from sources, cite them and admit when they lack the answer.
  • Keep private data out of shared indexes or filter results by the user's permissions.
Grounding
Supplying a model with specific information to base its answer on.
Retrieval-augmented generation (RAG)
Retrieving relevant passages and adding them to the prompt before the model generates an answer.
Chunk
A short section of a document stored and retrieved as a unit.
Vector
A list of numbers representing the meaning of a piece of text.
Vector search
Finding stored items whose vectors are closest to the query's vector.
Hybrid search
Combining keyword and vector search and merging the results.
Foundry IQ
A managed knowledge layer over Azure AI Search that agents query through knowledge bases.

Practice problems

Work each problem on paper first, then reveal the answer to check.

  1. What problem does grounding solve?

    Show answer

    The model does not know an organization's own, current information, so it may invent plausible answers.

  2. Why are documents split into chunks?

    Show answer

    So retrieval can return small, relevant pieces instead of whole documents.

  3. What does an embedding model produce?

    Show answer

    A vector of numbers that represents the meaning of text.

  4. Why combine keyword and vector search?

    Show answer

    Vectors match meaning, while keywords match exact terms such as product codes and names.

  5. Which Azure service is the usual search index for RAG?

    Show answer

    Azure AI Search.

  6. Why should order status not be stored in a shared index?

    Show answer

    It changes constantly and belongs to one customer; it should be fetched for the verified customer when needed.

Lesson quiz · 5 questions

Score 60% or more to complete this lesson.

Take the quiz