← back to knowledge-hub

Scaffold a RAG Chat App with the .NET AI Templates

The last time I wanted a “chat with my own documents” prototype, the boring parts ate the afternoon: chunking files, generating embeddings, standing up a vector store, wiring citations back into the UI. None of it is hard — all of it is plumbing.

The .NET AI templates collapse that plumbing into a single command. dotnet new aichatweb scaffolds a full Blazor app that ingests your documents, embeds them, searches them by vector similarity, and answers questions with citations pointing back to the source. This walks through the Azure OpenAI path, using keyless authentication so there’s no API key to leak.

What you need

  • .NET 9.0 SDKdownload it here
  • An Azure OpenAI resource — with permission to deploy models
  • Optionally, Visual Studio or VS Code with the C# Dev Kit

Install the template

The template ships as a NuGet package. Install it once and dotnet new learns the new project type:

1
dotnet new install Microsoft.Extensions.AI.Templates

Create the app

From an empty directory, scaffold with the Azure OpenAI provider and a local on-disk vector store — perfect for prototyping, no external database to provision:

1
2
dotnet new aichatweb --Framework net9.0 --provider azureopenai --vector-store local
code .

That’s it. You now have a working Blazor Interactive Server app. If you prefer clicking: in Visual Studio, File → New → Project, search AI Chat Web App, and on the Additional information screen pick .NET 9.0, Azure OpenAI, leave Use keyless authentication for Azure services checked, and set the vector store to Local on-disc.

What the template built for you

Open Program.cs and you’ll see the whole RAG stack registered for dependency injection. The template handled every piece I usually hand-write:

  • IChatClient — the abstraction you send messages to (the same seam covered in my note on the core .NET AI building blocks).
  • IEmbeddingGenerator — turns text into vectors so passages can be compared by meaning, not keywords.
  • JsonVectorStore — an on-disk store that holds those vectors and answers similarity queries.
  • A SQLite ingestion context — watches the wwwroot/Data folder and ingests whatever you drop in, including the sample files that ship with the template.
  • A complete Blazor chat UI — rich formatting, streaming responses, and clickable citations that jump to the passage the answer came from.

The retrieval-augmented generation loop is the point here: your question gets embedded, matched against the document vectors, and the top passages are stitched into the prompt so the model answers from your data instead of guessing.

Create and deploy the Azure OpenAI models

The app expects two model deployments in your Azure OpenAI resource. Deploy both, and name the deployments exactly like the models so they match the template defaults:

  • gpt-4o-mini — the chat model
  • text-embedding-3-small — the embedding model

If you’re new to this, follow Create an Azure OpenAI resource and its deploy-a-model steps.

Authenticate without a key

This is the part I like. The template uses DefaultAzureCredential, which picks up the identity you’re already signed in with locally — no key in code, no key in config. Two steps make it work:

  1. Grant your account access. In the Azure portal, open your Azure OpenAI resource → Access control (IAM) → add a role assignment for the Azure AI Developer role to your own account.
  2. Sign in locally with that same account — through Visual Studio, or az login with the Azure CLI.

DefaultAzureCredential finds those signed-in credentials at runtime and authenticates for you.

Point the app at your endpoint

The only thing the app can’t infer is your resource’s endpoint URL. Store it in .NET user secrets so it never touches source control:

1
dotnet user-secrets set AzureOpenAi:Endpoint <your-Azure-OpenAI-endpoint>

If you named your deployments something other than the defaults, update the two lines in Program.cs to match:

1
2
3
// Update these to match your Azure OpenAI deployment names
var chatClient = azureOpenAi.AsChatClient("gpt-4o-mini");
var embeddingGenerator = azureOpenAi.AsEmbeddingGenerator("text-embedding-3-small");

If you hit an authentication error on first run, it’s almost always the role: confirm the signed-in account actually has Azure AI Developer on the resource.

Run it

1
dotnet run

Open the browser, and ask a question about the sample data — something like “What are some essential tools in the survival kit?” The reply streams in, and underneath it you get citations. Click one and it takes you to the exact section of the source file the answer drew from. That citation trail is what separates a demo from something you’d actually trust.

To make it your app, drop your own PDFs or text into wwwroot/Data and restart — the ingestion pipeline picks them up automatically.

Why start here

The template isn’t magic, and it isn’t a black box — it’s the RAG boilerplate you’d have written yourself, already written and already correct. Because it’s all built on Microsoft.Extensions.AI, the provider is a swappable detail: the same dotnet new aichatweb supports GitHub Models, OpenAI, and local Ollama by changing one --provider flag. Prototype against GitHub Models for free, then flip to Azure OpenAI for production without rewriting the app.

If you want to go fully local with your models instead, see my walkthrough on running local AI models with .NET Aspire. And if you’d rather build the chat loop by hand to understand every line, start with building an AI chat app with .NET and OpenAI.

Based on Microsoft’s Create a .NET AI app using the AI app template quickstart.

graph cloud