AI Tutorial
Home All Courses Blog Interview Prep ↗ Export PDF 0%
1
Curious builder 0 XP earned · 300 to level 2
0 days Finish a lesson to begin
Badge collection
0 of 5 unlocked
small wins to finish your path
Next lesson →

RAG with Azure AI Search

Export PDF

Most enterprise AI requests boil down to “answer from our documents, and show where the answer came from”. That is retrieval-augmented generation (RAG). This lesson explains the two ways to do RAG in Foundry — managed file search with vector stores, and Azure AI Search for production-scale knowledge — and covers indexes, hybrid search, semantic ranking, connecting search to a project, and producing cited answers.

Last updated: 01 Nov, 2026 · azure-ai-projects 2.x · Python 3.10+

RAG in one picture

Definition · Retrieval-augmented generation (RAG)

A pattern where, for every question, the system first retrieves relevant passages from a knowledge source and then asks the model to generate an answer using only those passages, ideally with citations. It gives the model private, up-to-date facts without retraining it.

RAG pipeline
INGEST (when documents change)
  PDFs, Word, HTML, SharePoint ─► extract text ─► chunk ─► embed ─► index

QUERY (every question)
  question ─► (rewrite) ─► search index: keyword + vector ─► semantic rerank ─► top passages
                                                                      │
                     instructions + passages + question ─► model ─► answer [cited]

The Building RAG Systems course builds each step by hand. Here we focus on the managed Azure pieces that do the heavy lifting.

Two ways to do RAG in Foundry

File search + vector storesAzure AI Search
What it isA managed tool: upload files, Foundry chunks, embeds, and indexes them for youA separate search service you control: index schema, chunking, scoring, security
Setup effortMinutesHours to days
ScaleGood for hundreds to thousands of files per storeMillions of documents, many indexes
ControlFew knobs (chunk size, max results, filters)Full control: fields, analyzers, vector profiles, scoring, semantic ranker
Security trimmingPer vector storeDocument-level filters (for example, by user group)
Use forPrototypes, per-user uploads, small knowledge basesProduction enterprise knowledge

Option A: file search with a vector store

Definition · Vector store

A managed container in your project that holds files and their embedded chunks. You attach it to an agent through the file search tool, and the agent searches it whenever a question needs it.

Live Azure call

This example calls your Azure resources, so it needs a deployed project and a signed-in identity. Output will differ on every run.

Python
from pathlib import Path

with project.get_openai_client() as client:
    store = client.vector_stores.create(name="support-kb")

    for path in Path("kb").glob("*.md"):           # refund-policy.md, shipping-faq.md, ...
        with path.open("rb") as f:
            client.vector_stores.files.upload_and_poll(vector_store_id=store.id, file=f)

    print(store.id, client.vector_stores.retrieve(store.id).file_counts)
vs_6f1c2a... FileCounts(cancelled=0, completed=4, failed=0, in_progress=0, total=4)

Behind the scenes Foundry extracts text, splits it into overlapping chunks, embeds them, and builds a hybrid (keyword + vector) index. You attach the store to an agent in the next lessons with FileSearchTool(vector_store_ids=[store.id]).

Option B: Azure AI Search

Definition · Azure AI Search

Azure's managed search engine (formerly Azure Cognitive Search). It stores indexes of documents and supports full-text keyword search (BM25), vector search, hybrid search, filters, facets, and a semantic ranker that reorders results with a language model.

Core concepts

ConceptMeaning
IndexThe searchable collection, with a schema of fields (for example id, title, content, content_vector, url, group_ids).
Field attributesWhether a field is searchable, filterable, sortable, facetable, retrievable, or a vector field.
Data source + indexerA connection to Blob Storage, SharePoint, SQL, or Cosmos DB, and a scheduled crawler that pulls documents into the index.
SkillsetEnrichment steps applied during indexing: OCR, chunking (text split), and embedding (integrated vectorization).
VectorizerConfiguration that embeds the query at search time with the same model used for documents.
Semantic configurationTells the semantic ranker which fields hold the title and content.

The easiest path to a working index is the portal's Import and vectorize data wizard: point it at a Blob container, pick your embedding deployment, and it creates the data source, skillset (chunk + embed), index, and indexer for you.

Keyword, vector, hybrid, semantic

Search modeHow it matchesStrengthWeakness
Keyword (BM25)Exact terms, weighted by rarityProduct codes, names, error numbersMisses synonyms and paraphrases
VectorNearest embeddings by meaningParaphrases, natural questionsCan miss exact identifiers
HybridRuns both and merges ranks with Reciprocal Rank FusionBest of both; the recommended defaultSlightly more compute
Hybrid + semantic rankerReranks the top hybrid results with a cross-encoder language modelHighest relevance in Microsoft's benchmarksExtra cost per query
Definition · Reciprocal Rank Fusion (RRF)

A way to merge several ranked lists without comparing their incompatible scores. Each document gets 1 / (k + rank) from every list it appears in (Azure AI Search uses k = 60), and the sums are sorted. Documents ranked well by both keyword and vector search rise to the top.

Python
def rrf(rankings: dict[str, list[str]], k: int = 60) -> list[tuple[str, float]]:
    """Reciprocal Rank Fusion: score(doc) = sum over lists of 1 / (k + rank)."""
    scores: dict[str, float] = {}
    for ranked_ids in rankings.values():
        for rank, doc_id in enumerate(ranked_ids, start=1):
            scores[doc_id] = scores.get(doc_id, 0.0) + 1 / (k + rank)
    return sorted(scores.items(), key=lambda kv: kv[1], reverse=True)


keyword_hits = ["refund-policy", "shipping-faq", "warranty", "returns-portal"]
vector_hits = ["returns-portal", "refund-policy", "store-credit", "warranty"]

for doc_id, score in rrf({"bm25": keyword_hits, "vector": vector_hits}):
    print(f"{doc_id:<15} {score:.5f}")
refund-policy 0.03252 returns-portal 0.03202 warranty 0.03150 shipping-faq 0.01613 store-credit 0.01587

returns-portal was only fourth in keyword search but first in vector search, so fusion lifts it to second. store-credit, found only by vector search, still makes the list. This is exactly why hybrid search beats either method alone.

Query an index from Python

Live Azure call

This example calls your Azure resources, so it needs a deployed project and a signed-in identity. Output will differ on every run.

Python
import os

from azure.identity import DefaultAzureCredential
from azure.search.documents import SearchClient
from azure.search.documents.models import VectorizableTextQuery

search = SearchClient(
    endpoint=os.environ["SEARCH_ENDPOINT"],          # https://<name>.search.windows.net
    index_name="support-kb",
    credential=DefaultAzureCredential(),             # needs Search Index Data Reader
)

question = "Can I get a refund if my parcel arrived damaged?"
results = search.search(
    search_text=question,                                        # keyword half
    vector_queries=[VectorizableTextQuery(text=question,         # vector half (index vectorizer embeds it)
                                          k_nearest_neighbors=50,
                                          fields="content_vector")],
    query_type="semantic",                                       # semantic reranking
    semantic_configuration_name="default",
    select=["title", "content", "url"],
    top=5,
)
passages = [{"title": r["title"], "url": r["url"], "content": r["content"],
             "score": r["@search.reranker_score"]} for r in results]

Generate a cited answer

Python
context = "\n\n".join(
    f"[{i}] {p['title']} ({p['url']})\n{p['content']}" for i, p in enumerate(passages, 1)
)

answer = client.responses.create(
    model=deployment,
    instructions=(
        "Answer only from the numbered sources. Cite sources like [1] after each claim. "
        "If the sources do not contain the answer, say you don't know and suggest contacting support."
    ),
    input=f"Sources:\n{context}\n\nQuestion: {question}",
)
print(answer.output_text)
Yes. Items that arrive damaged qualify for a full refund if you report them within 14 days of delivery [1]. Start the claim from the Returns portal and attach a photo of the damage [2].

Connecting search to your project and agents

To let an agent use an index, create a connection from the project to the search service (portal: Management center → Connected resources → Azure AI Search), and give the project's managed identity Search Index Data Reader on the search service. The agent then uses the Azure AI Search tool:

Python
from azure.ai.projects.models import (
    AISearchIndexResource,
    AzureAISearchTool,
    AzureAISearchToolResource,
)

connection = project.connections.get("search-support")      # the connection name you created

search_tool = AzureAISearchTool(
    azure_ai_search=AzureAISearchToolResource(
        indexes=[AISearchIndexResource(
            project_connection_id=connection.id,
            index_name="support-kb",
            query_type="vector_semantic_hybrid",
            top_k=5,
        )]
    )
)
# pass tools=[search_tool] when creating the agent (next lessons)
Foundry IQ

Microsoft also offers Foundry IQ, a managed knowledge layer built on Azure AI Search that lets several agents share knowledge bases spanning multiple sources (Blob, SharePoint, OneLake, the web) with agentic retrieval — the system plans sub-queries, runs them in parallel, and merges results. It is a good next step once a single index is not enough.

RAG quality checklist

  • Chunking: chunks of a few hundred tokens with some overlap usually work; keep headings with their text.
  • Metadata: store title, URL, date, and access groups with every chunk, for citations and filtering.
  • Security trimming: filter by the user's group IDs so people only retrieve what they may read.
  • Freshness: schedule indexers, and delete chunks when source documents are removed.
  • Grounding instructions: tell the model to answer only from sources and to admit when it does not know.
  • Measure: evaluate retrieval and groundedness on a test set (lesson 9).
Try it
  1. Add a third list "title_match" to the RRF example and see how rankings change.
  2. Change k from 60 to 1 and observe how much more the top rank dominates.
  3. Create a vector store from three Markdown files of your own and note the chunk counts in the portal.
Key takeaways
  • RAG retrieves relevant passages first, then generates an answer from them with citations.
  • File search with vector stores is managed and quick; Azure AI Search gives production control and scale.
  • Hybrid search (BM25 + vector, merged with RRF) plus semantic ranking is the recommended default.
  • Connect search to a project with a connection and give the project's identity Search Index Data Reader.
  • Instruct the model to answer only from sources, cite them, and say when it doesn't know.