AI in .NET has changed more in the last two years than in the previous ten: there is now a unified set of abstractions for talking to models, a production-ready agent framework, a standard protocol for sharing tools, and first-class vector search and evaluation. This guide maps that landscape as of September 2026 for professional C# developers who need to pick the right library for each job, and shows how the pieces fit into a production-grade application.

What Is the AI in .NET Ecosystem?#

The .NET AI ecosystem is not one product but a layered set of libraries, SDKs and services aligned around shared types. Almost everything speaks the same vocabulary: a chat model is an IChatClient, an embedding model is an IEmbeddingGenerator<TInput, TEmbedding>, a tool is an AIFunction, and a message is a ChatMessage. Those types live in Microsoft.Extensions.AI, and the higher-level frameworks build on them instead of inventing their own.

That shared vocabulary lets you mix and match: start with one call to a hosted model, add tool calling, switch to a local model for development, wrap the client in an agent and expose your tools through the Model Context Protocol, without rewriting the core of your application.

At a high level, the ecosystem covers seven concerns:

  • Model access: Microsoft.Extensions.AI plus provider SDKs such as the OpenAI library, the Microsoft Foundry SDK, OllamaSharp and ONNX Runtime GenAI.
  • Orchestration: Microsoft Agent Framework, with Semantic Kernel as its predecessor.
  • Your own data: Microsoft.Extensions.DataIngestion and Microsoft.Extensions.VectorData.
  • Tools: function calling through AIFunctionFactory and the MCP C# SDK.
  • Quality and safety: Microsoft.Extensions.AI.Evaluation, OpenTelemetry and Foundry guardrails.
  • Hosting: Microsoft Foundry, Foundry Local and Aspire.
  • Classic machine learning: ML.NET and ONNX Runtime.

How the .NET AI Stack Fits Together#

The easiest mental model is a stack where each layer depends only on the layers below it. Your application code talks to the top layers, and the provider-specific details stay at the bottom where they are easy to swap.

Text
+------------------------------------------------------------------+
| Your app: ASP.NET Core API, Blazor UI, worker services, MAUI      |
+------------------------------------------------------------------+
| Orchestration: Microsoft Agent Framework (agents, workflows)      |
|                Semantic Kernel (existing apps)                    |
+------------------------------------------------------------------+
| Data: DataIngestion (read, chunk, enrich) -> VectorData (search)  |
| Tools: AIFunction / AIFunctionFactory, MCP clients and servers    |
+------------------------------------------------------------------+
| Abstractions: Microsoft.Extensions.AI                             |
|   IChatClient, IEmbeddingGenerator, middleware (cache, OTel, ...) |
+------------------------------------------------------------------+
| Providers: OpenAI SDK | Microsoft Foundry | Ollama | ONNX GenAI  |
+------------------------------------------------------------------+
| Cross-cutting: Evaluation, OpenTelemetry, Aspire, Entra ID auth   |
+------------------------------------------------------------------+

Three properties make this stack work well in practice. First, the abstractions are small: IChatClient has two request methods, one for a complete response and one for a stream. Second, cross-cutting behavior is added as middleware, so caching, logging, telemetry and automatic tool invocation wrap any provider in the same way. Third, dependency injection is the integration point, which means AI services register and resolve like any other .NET service.

The practical guidance from Microsoft's own documentation is to start at the bottom and climb only as far as you need. Use Microsoft.Extensions.AI for most app-level features, add the data libraries when you need grounding in your own content, adopt MCP when capabilities must cross process or product boundaries, and move to Agent Framework when a single prompt becomes a multi-step, goal-directed process.

Getting Started with AI in .NET#

The fastest way to see the stack in action is a console app that calls a hosted model through IChatClient. Create a project and add the abstractions plus the OpenAI adapter, which brings in the official OpenAI library as a dependency:

Bash
dotnet new console -n HelloAI
cd HelloAI
dotnet add package Microsoft.Extensions.AI
dotnet add package Microsoft.Extensions.AI.OpenAI

Then replace Program.cs with a minimal call. The AsIChatClient() extension adapts the provider-specific ChatClient from the OpenAI library to the provider-neutral IChatClient interface:

C#
using Microsoft.Extensions.AI;
using OpenAI.Chat;

string apiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY")
    ?? throw new InvalidOperationException("Set the OPENAI_API_KEY environment variable.");

IChatClient client = new ChatClient("gpt-5-mini", apiKey).AsIChatClient();

ChatResponse response = await client.GetResponseAsync(
    "Explain dependency injection to a junior developer in one short paragraph.");

Console.WriteLine(response.Text);
Console.WriteLine($"Tokens used: {response.Usage?.TotalTokenCount}");

Everything after the client construction is provider-neutral. Pointing the code at Microsoft Foundry, a local Ollama server or an ONNX model on disk changes only that one line.

If you prefer to start from a working web application, the AI app templates scaffold a Blazor chat app with ingestion, vector search and citations already wired up. The aichatweb template supports Azure OpenAI, OpenAI and Ollama providers, a local JSON vector store or Azure AI Search or Qdrant, and an optional Aspire orchestration project:

Bash
dotnet new install Microsoft.Extensions.AI.Templates
dotnet new aichatweb -n SupportChat --provider azureopenai --vector-store local --aspire

The templates package is still published as a preview, so treat the generated code as a strong starting point rather than a finished architecture.

Microsoft.Extensions.AI: The Foundation Layer#

Microsoft.Extensions.AI (often shortened to MEAI) is the layer almost every other component builds on. The Microsoft.Extensions.AI.Abstractions package defines the exchange types, and the Microsoft.Extensions.AI package adds the middleware and dependency injection helpers that applications use. Both packages reached the 10.x line alongside .NET 10 and ship monthly; version 10.10.0 was published in September 2026.

The key idea is the delegating pipeline. ChatClientBuilder wraps an inner client with any number of decorators, and the order of the Use calls determines the order in which they run. The following registration in an ASP.NET Core app adds response caching, automatic tool invocation, OpenTelemetry tracing and logging around an OpenAI-backed client:

C#
using Microsoft.Extensions.AI;
using OpenAI.Chat;

var builder = WebApplication.CreateBuilder(args);

string apiKey = builder.Configuration["OpenAI:ApiKey"]
    ?? throw new InvalidOperationException("OpenAI:ApiKey is not configured.");

builder.Services.AddDistributedMemoryCache();
builder.Services
    .AddChatClient(_ => new ChatClient("gpt-5-mini", apiKey).AsIChatClient())
    .UseDistributedCache()
    .UseFunctionInvocation()
    .UseOpenTelemetry()
    .UseLogging();

var app = builder.Build();

app.MapPost("/summarize", async (SummarizeRequest request, IChatClient chat,
    CancellationToken cancellationToken) =>
{
    ChatResponse response = await chat.GetResponseAsync(
        $"Summarize the following text in three bullet points:\n{request.Text}",
        cancellationToken: cancellationToken);

    return Results.Ok(new { summary = response.Text });
});

app.Run();

public sealed record SummarizeRequest(string Text);

Beyond chat and embeddings, MEAI also defines experimental abstractions for image generation, speech to text, text to speech and real-time conversations, plus experimental helpers for chat history reduction and routing requests across multiple clients. Experimental APIs produce the MEAI001 diagnostic, so you opt in consciously. For a deeper treatment of the pipeline, custom middleware and testing, see the Microsoft.Extensions.AI guide.

Orchestration: Microsoft Agent Framework and Semantic Kernel#

When a feature must pursue a goal across several steps, choose tools, keep conversation state or coordinate specialized agents, you have moved from calling a model to orchestrating an agent. In .NET that is the job of Microsoft Agent Framework.

Agent Framework is the successor to both Semantic Kernel and AutoGen, built by the same teams. It pairs AutoGen's simple agent abstractions with Semantic Kernel's enterprise features, such as session state, middleware and telemetry, and adds graph-based workflows. The .NET packages reached 1.0 in April 2026 after a February release candidate, and the core Microsoft.Agents.AI packages ship frequent stable updates. Some integration packages, such as hosting and the Foundry connector, are still prerelease.

Because agents are built on IChatClient, any chat client becomes an agent with one call:

C#
using System.ComponentModel;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using OpenAI.Chat;

IChatClient chatClient = new ChatClient("gpt-5-mini",
    Environment.GetEnvironmentVariable("OPENAI_API_KEY")!).AsIChatClient();

AIAgent agent = chatClient.AsAIAgent(
    instructions: "You are an order-support assistant. Always use tools for order data.",
    name: "OrderSupport",
    tools: [AIFunctionFactory.Create(GetOrderStatus)]);

AgentSession session = await agent.CreateSessionAsync();
Console.WriteLine(await agent.RunAsync("Where is order 1042?", session));
Console.WriteLine(await agent.RunAsync("When did it ship?", session));

[Description("Gets the shipping status for an order.")]
static string GetOrderStatus([Description("The order number.")] int orderId) =>
    orderId == 1042 ? "Shipped on 2026-09-20 via parcel service." : "Order not found.";

The AgentSession keeps the conversation, so the second question can refer to the first. On top of single agents, Agent Framework provides sequential, concurrent, handoff, group chat and manager-led orchestrations, checkpointing, human approval for sensitive tools and OpenTelemetry tracing. The Microsoft Agent Framework guide covers these in depth.

Semantic Kernel still ships releases, but its repository now calls Agent Framework its enterprise-ready successor, and new features land there. The Semantic Kernel guide explains where it still fits and how to plan a migration.

Working with Your Own Data: VectorData and DataIngestion#

Most business applications need answers grounded in your own content. The standard pattern is retrieval-augmented generation (RAG), and .NET has two dedicated libraries for it.

Microsoft.Extensions.VectorData (MEVD) is a provider-neutral abstraction over vector databases. You describe a record type with attributes, and the same code runs against an in-memory store, Azure AI Search, PostgreSQL with pgvector, SQL Server, Qdrant, Redis and others. In 2026 the connectors that used to carry Semantic Kernel names were renamed to CommunityToolkit.VectorData.* packages with stable 1.0 releases, which makes their framework independence explicit. MEVD can also call your IEmbeddingGenerator for you, so you can store and search text without generating vectors by hand:

C#
using CommunityToolkit.VectorData.InMemory;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.VectorData;
using OpenAI.Embeddings;

IEmbeddingGenerator<string, Embedding<float>> embeddings =
    new EmbeddingClient("text-embedding-3-small",
        Environment.GetEnvironmentVariable("OPENAI_API_KEY")!).AsIEmbeddingGenerator();

var store = new InMemoryVectorStore(new() { EmbeddingGenerator = embeddings });
var faq = store.GetCollection<int, FaqEntry>("faq");
await faq.EnsureCollectionExistsAsync();

await faq.UpsertAsync(new FaqEntry
{
    Id = 1,
    Question = "How do I reset my password?",
    Answer = "Use the Forgot password link on the sign-in page.",
    SearchText = "How do I reset my password? Use the Forgot password link."
});

await foreach (var hit in faq.SearchAsync("I cannot log in anymore", top: 3))
{
    Console.WriteLine($"{hit.Score:F3}  {hit.Record.Question}");
}

public sealed class FaqEntry
{
    [VectorStoreKey]
    public int Id { get; set; }

    [VectorStoreData]
    public string Question { get; set; } = "";

    [VectorStoreData]
    public string Answer { get; set; } = "";

    // Embedded automatically by the configured IEmbeddingGenerator.
    [VectorStoreVector(1536)]
    public string SearchText { get; set; } = "";
}

Microsoft.Extensions.DataIngestion (MEDI) sits in front of the vector store. It reads documents into a Markdown-centric representation, splits them with header-based, section-based or semantic chunkers built on Microsoft.ML.Tokenizers, optionally enriches chunks with summaries, keywords or classifications produced by an IChatClient, and writes them to any MEVD store. MEDI is still in preview in September 2026, so pin versions and expect API adjustments. The end-to-end patterns, including hybrid search, reranking and citations, are covered in the RAG in .NET guide.

Tools and the Model Context Protocol#

Function calling is how a model asks your code to do something: look up an order, query a database or create a ticket. In MEAI you describe a .NET method with AIFunctionFactory.Create, pass it in ChatOptions.Tools, and the UseFunctionInvocation middleware runs the loop of model request, tool execution and follow-up request for you.

In-process tools are the simplest option when only one application needs them. When several applications, IDE assistants or agents should share the same capabilities, the Model Context Protocol (MCP) is the standard answer. The official MCP C# SDK, maintained by Microsoft together with the MCP project, reached 1.0 in February 2026 and 2.0 in July 2026. A complete HTTP MCP server takes only a few lines:

C#
using System.ComponentModel;
using ModelContextProtocol.Server;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddMcpServer()
    .WithHttpTransport()
    .WithToolsFromAssembly();

var app = builder.Build();
app.MapMcp("/mcp");
app.Run();

[McpServerToolType]
public static class InventoryTools
{
    [McpServerTool, Description("Returns the number of units in stock for a SKU.")]
    public static int GetStock([Description("The product SKU.")] string sku) =>
        sku == "BOOK-42" ? 17 : 0;
}

On the client side, the tools returned by an MCP client derive from AIFunction, so they plug straight into an IChatClient or an Agent Framework agent. A dedicated guide on building MCP servers and clients in C# is part of this series.

Model Providers: OpenAI, Microsoft Foundry and Local Models#

Below the abstractions sit the provider SDKs. Choosing one is mostly about where the model runs and which controls you need.

Provider pathMain packageTypical use
OpenAI platformOpenAI (2.x)Direct access to OpenAI models and the Responses API
Azure OpenAI in Microsoft FoundryOpenAI with the /openai/v1/ endpointEnterprise hosting, Entra ID auth, data residency, quotas
Foundry projects and Agent ServiceAzure.AI.ProjectsProject-level features, prompt agents, hosted agents
OllamaOllamaSharpLocal open-weight models during development
ONNX Runtime GenAIMicrosoft.ML.OnnxRuntimeGenAIIn-process small language models, offline scenarios
Foundry LocalMicrosoft.AI.Foundry.LocalManaged on-device model catalog and runtime

Two changes from earlier years are worth knowing. Azure AI Foundry was renamed Microsoft Foundry in November 2025. And for Azure OpenAI, Microsoft now recommends the plain OpenAI library pointed at the v1 endpoint instead of the Azure-specific wrapper; the Azure.AI.OpenAI changelog itself suggests removing that package, and the older Azure AI Inference SDK has been retired. Keyless authentication with Microsoft Entra ID uses a bearer token policy:

C#
#pragma warning disable OPENAI001
using System.ClientModel.Primitives;
using Azure.Identity;
using Microsoft.Extensions.AI;
using OpenAI;
using OpenAI.Chat;

var tokenPolicy = new BearerTokenPolicy(
    new DefaultAzureCredential(), "https://ai.azure.com/.default");

var chatClient = new ChatClient(
    model: "gpt-5-mini", // the deployment name in your Foundry resource
    authenticationPolicy: tokenPolicy,
    options: new OpenAIClientOptions
    {
        Endpoint = new Uri("https://my-foundry-resource.openai.azure.com/openai/v1/")
    });

IChatClient client = chatClient.AsIChatClient();

The Azure OpenAI and Microsoft Foundry guide explains deployments, quotas, provisioned throughput, guardrails and private networking.

For local inference, OllamaSharp's client implements IChatClient directly (the old Microsoft.Extensions.AI.Ollama adapter is deprecated in its favor), and ONNX Runtime GenAI ships an OnnxRuntimeGenAIChatClient that loads a model from disk. Expect lower quality and less reliable tool calling than frontier hosted models.

Classic Machine Learning with ML.NET and ONNX Runtime#

Not every AI problem needs a large language model. Churn prediction, anomaly detection and classification into fixed categories are often solved better and far more cheaply by a trained model. ML.NET remains the .NET-native library for that work: version 5.0 shipped in November 2025 alongside .NET 10, with 6.0 previews in 2026, covering data loading, training, evaluation and in-process prediction.

ONNX Runtime complements it. Use Microsoft.ML.OnnxRuntime to score models exported from PyTorch or scikit-learn, and Microsoft.ML.OnnxRuntimeGenAI for generative models that run in-process. A pragmatic pattern combines both: a cheap classifier routes requests, and only hard cases reach an LLM.

Templates, Aspire and Developer Tooling#

AI apps have more moving parts than typical CRUD services: model and embedding endpoints, a vector database, ingestion workers and often an MCP server. Beyond aichatweb, the Microsoft.McpServer.ProjectTemplates package provides dotnet new mcpserver, and Agent Framework publishes preview templates.

Aspire (the 13.x line) handles orchestration and observability during development and deployment. Hosting integrations model resources such as Azure OpenAI deployments, Foundry projects and Ollama containers in the AppHost, and client integrations register configured clients, including IChatClient, in each service:

C#
// AppHost/Program.cs
var builder = DistributedApplication.CreateBuilder(args);

var openai = builder.AddAzureOpenAI("openai");
openai.AddDeployment("chat", "gpt-4o-mini", "2024-07-18");

builder.AddProject<Projects.SupportApi>("support-api")
       .WithReference(openai);

builder.Build().Run();
C#
// SupportApi/Program.cs
var builder = WebApplication.CreateBuilder(args);

// Registers an OpenAIClient from the "openai" connection and an IChatClient
// for the "chat" deployment, with OpenTelemetry tracing enabled by default.
builder.AddAzureOpenAIClient("openai").AddChatClient("chat");

The Aspire dashboard then shows traces that follow a request from your API through the chat client to the model, which is invaluable when you debug slow tool loops or unexpected token usage.

Reference Architecture of an AI-Enabled .NET App#

The following architecture reflects how the pieces combine in a typical production system, such as an internal support assistant that answers questions from company documents and can take limited actions.

Text
  Users (Blazor / SPA / Teams)
            |
            v
+------------------------+     +-----------------------------+
| ASP.NET Core API       |---->| Agent Framework agent       |
|  - authn/authz (Entra) |     |  - instructions + session   |
|  - rate limiting       |     |  - tools: AIFunctions, MCP  |
|  - streaming (SSE)     |     |  - approvals for writes     |
+------------------------+     +-------------+---------------+
            |                                |
            | IChatClient pipeline           | retrieval
            v                                v
+------------------------+     +-----------------------------+
| MEAI middleware        |     | VectorData collection       |
|  cache, OTel, logging, |     |  (Azure AI Search/pgvector) |
|  function invocation   |     +-------------^---------------+
+-----------+------------+                   |
            |                                | upserts
            v                                |
+------------------------+     +-------------+---------------+
| Microsoft Foundry      |     | Ingestion worker            |
|  model deployments,    |     |  DataIngestion pipeline     |
|  guardrails, quotas    |     |  (read -> chunk -> embed)   |
+------------------------+     +-----------------------------+

Cross-cutting: Aspire AppHost + dashboard, OpenTelemetry exporter,
managed identity everywhere, evaluation tests in CI.

The API owns security and user experience: authentication, authorization, per-user rate limits and streaming responses. The agent owns reasoning and tool selection, but every tool enforces its own authorization, and state-changing tools require human approval. Retrieval runs against a production vector store that an ingestion worker keeps up to date in the background, so user requests never wait for document processing. All model traffic flows through one MEAI pipeline, which gives you a single place for caching, telemetry and cost controls. Finally, evaluation tests built with Microsoft.Extensions.AI.Evaluation run in CI to catch quality regressions when prompts, models or data change.

Which Library for Which Job?#

Use this decision table as a starting point. Most real applications combine several rows.

Job to be doneRecommended library or serviceStatus (Sept 2026)
Call a chat or embedding model from app codeMicrosoft.Extensions.AI + provider adapterStable (10.x)
Add caching, logging, telemetry or tool loops to model callsMEAI middleware via ChatClientBuilderStable
Get typed JSON back from a modelGetResponseAsync<T> in MEAIStable
Build a goal-directed agent with tools and memoryMicrosoft Agent FrameworkStable 1.x core
Coordinate several agents or add human approval stepsAgent Framework workflowsStable core, some parts experimental
Maintain an existing Semantic Kernel appSemantic Kernel, then migrateMaintained, successor is MAF
Store and search embeddingsMicrosoft.Extensions.VectorData + CommunityToolkit.VectorData connectorsStable
Read, chunk and enrich documents for RAGMicrosoft.Extensions.DataIngestionPreview
Share tools with other apps, IDEs and agentsMCP C# SDK (ModelContextProtocol)Stable 2.x
Host models with enterprise controls in AzureMicrosoft Foundry via the OpenAI SDK v1 endpointGA
Run a managed agent without hosting codeFoundry Agent Service prompt agentsGA
Run a small model locally or offlineOllamaSharp, ONNX Runtime GenAI, Foundry LocalStable packages
Train a model on your own tabular dataML.NET 5Stable
Measure answer quality and safetyMicrosoft.Extensions.AI.EvaluationStable
Orchestrate services and view AI traces locallyAspire 13Stable, some AI integrations preview

Best Practices#

  • Code against IChatClient and IEmbeddingGenerator, not provider types. Provider choice becomes configuration, and unit tests can use fakes.
  • Register one pipeline per purpose. Keyed registrations (AddKeyedChatClient) let a cheap model classify while a stronger model answers.
  • Instrument from day one. UseOpenTelemetry() gives you token counts and tool timings before costs or latency surprise you.
  • Prefer keyless authentication. Use managed identity for Azure resources and a secret store for any API keys.
  • Choose the smallest layer that works. A single prompt does not need an agent, and an in-process tool does not need an MCP server.
  • Pin preview packages. DataIngestion and several Agent Framework and Aspire AI integrations are prerelease and change monthly.
  • Add evaluations before tuning prompts. A small test set with relevance and groundedness scores turns prompt changes into engineering.

Common Pitfalls#

  • Treating model output as trusted input. Validate tool arguments, authorize inside every tool, and never pass generated text straight into SQL, shell commands or HTML.
  • Building on the wrong layer. Older tutorials still steer new projects to Semantic Kernel agents or the Azure-specific OpenAI wrapper. Check current guidance first.
  • Suppressing experimental diagnostics globally. Project-wide MEAI001 or OPENAI001 suppressions hide which code depends on unstable APIs. Suppress narrowly.
  • Unbounded conversation history. Long histories raise cost and latency and crowd out instructions. Summarize or trim deliberately.
  • Testing RAG only against the in-memory store. Filtering and scoring differ across databases, so test against the store you deploy.
  • Staying on an expiring runtime. .NET 8 and .NET 9 both reach end of support on November 10, 2026. Target .NET 10 LTS, supported until November 2028; .NET 11, now at release candidate, is a short-term support release.

Frequently Asked Questions#

Do I need Agent Framework or Semantic Kernel to add AI to a .NET app?#

No. Summarization, classification, extraction or a chat endpoint with a few tools only need Microsoft.Extensions.AI and a provider adapter. Adopt Agent Framework for multi-step planning, long-running sessions, cooperating agents or human approval workflows.

Is Microsoft.Extensions.AI ready for production?#

Yes. The core abstractions and middleware are stable and underpin Agent Framework, the MCP C# SDK and the AI templates. Newer areas such as image generation, speech and chat routing are experimental and require an explicit opt-in.

Should I use the Azure.AI.OpenAI package or the OpenAI package for Azure?#

For new code, use the OpenAI package against your resource's /openai/v1/ endpoint with Entra ID authentication. The Azure SDK team's migration guidance recommends this path for a single SDK surface and faster access to new features. Keep Azure.AI.OpenAI only where you still depend on its Azure-specific extensions.

Can I run AI models entirely locally with .NET?#

Yes. OllamaSharp and ONNX Runtime GenAI both provide IChatClient implementations, and Foundry Local offers a managed on-device runtime with a .NET SDK. Evaluate quality and tool-calling reliability for your tasks before relying on local models in production.

Which .NET version should I target for a new AI project?#

Target .NET 10, the current long-term support release. The AI libraries also target .NET Standard 2.0, so they run on .NET 8 and 9, but both leave support in November 2026. .NET 11 arrives in November 2026 as a short-term support release.

Summary#

  • The ecosystem is layered around shared Microsoft.Extensions.AI types, which is why its components compose well.
  • Start with IChatClient and middleware, add VectorData and DataIngestion for your content, use MCP to share tools, and adopt Agent Framework when orchestration is the real problem.
  • Agent Framework 1.x succeeds Semantic Kernel and AutoGen; Semantic Kernel remains maintained for existing apps.
  • On Azure, call Microsoft Foundry through the OpenAI SDK's v1 endpoint with managed identity, and use Aspire to orchestrate and observe.
  • Keep ML.NET and ONNX Runtime for problems that do not need a large language model.

Further Reading#