Generative AI

Microsoft.Extensions.AI explained: the foundation of the .NET AI stack

Microsoft.Extensions.AI is the foundational abstraction layer for building AI applications in .NET: a set of unified interfaces, most importantly IChatClient, that give your code one consistent way to interact with any AI model provider. Instead of coding directly against a specific vendor's SDK (Azure OpenAI's, OpenAI's, Anthropic's, Ollama's), you write against the abstraction, and the provider underneath becomes a swappable implementation detail. It plays the same role for AI that ILogger plays for logging or IDistributedCache plays for caching in .NET: a common interface everyone implements, so your code is not coupled to one vendor. It also provides middleware, standardized telemetry, caching, and tool-calling handling, that works across providers. It sits at the root of the .NET AI stack, and everything above it, including Microsoft Agent Framework, builds on it. This explains what it is, why it matters, and how to use it.

We build .NET AI systems on this foundation, so this is a practitioner's explanation of Microsoft.Extensions.AI and why it is the right layer to depend on.

The problem it solves: provider lock-in

Before a common abstraction, using AI in .NET meant coding against a specific provider's SDK, the Azure OpenAI client, the OpenAI client, each with its own types, methods, and conventions. That worked until you wanted to change something: switch from OpenAI to Azure OpenAI, add a local model for cost or privacy, or support multiple providers in one app. Every such change meant rewriting the code that touched the model, because your logic was welded to one vendor's API shape.

Microsoft.Extensions.AI removes that coupling. It defines a provider-agnostic interface (IChatClient) that every provider implements, so your application talks to the interface and the provider becomes configuration, not code. Want to swap OpenAI for a local Ollama model? Change the registered implementation, not your logic. Want to route some calls to a cheap local model and others to a frontier API? Both are IChatClient. This is the same benefit .NET developers already know from ILogger and IDistributedCache: program against the abstraction, and the concrete choice stays swappable. For AI specifically, where the provider landscape shifts constantly and cost pressure pushes toward mixing models, that portability is worth a lot.

What it actually provides

Microsoft.Extensions.AI is more than one interface, and knowing its pieces helps:

  • IChatClient. The core interface for chat-based interactions, sending messages, getting responses, streaming, across any provider. This is the one you write against most.
  • Embedding abstractions. A parallel interface for generating embeddings (for RAG, search, similarity), again provider-agnostic.
  • Tool/function calling support. A standardized way to define and invoke tools, so function calling works consistently regardless of provider.
  • Middleware pipeline. Composable middleware for cross-cutting concerns, telemetry (OpenTelemetry), caching, logging, and function-invocation handling, that wraps any provider uniformly. You add caching or tracing once and it applies across models.

Together these make it a genuine platform layer, not just a thin wrapper. The middleware in particular matters for production: you get standardized observability and caching, the levers behind prompt caching and cost control, at the abstraction layer, so they apply no matter which provider a given call uses. That is the difference between a convenience interface and a foundation you build a real system on.

Where it sits in the stack

Understanding Microsoft.Extensions.AI means seeing where it sits: at the root. It is the lowest layer of the .NET AI stack, the one that talks to providers, and everything else builds up from it. Microsoft Agent Framework, the agent and orchestration layer that reached GA in 2026, builds agents on top of these abstractions, so an agent's model calls ultimately go through IChatClient. Your own application code, whether a simple chat feature or a complex agent, depends on the same foundation.

This layering is deliberate and worth respecting in your architecture: write your AI logic against Microsoft.Extensions.AI abstractions, add Agent Framework on top when you need agents and orchestration, and keep the provider as a swappable implementation at the bottom. We map the full stack in building AI agents in C# and .NET. The practical rule that falls out: depend on the abstraction, not the provider SDK directly, even for simple features, because it costs nothing now and keeps every future change (new provider, local model, multi-model routing) cheap.

How to use it

Practical guidance for adopting Microsoft.Extensions.AI:

  • Depend on IChatClient, not a provider SDK. Write your feature against the abstraction and register the concrete provider (Azure OpenAI, OpenAI, Ollama) in DI, so swapping providers is a configuration change.
  • Use the middleware for cross-cutting concerns. Add telemetry and caching through the middleware pipeline once, rather than per-provider, so observability and cost control are uniform.
  • Route across models when it pays. Because every provider is an IChatClient, you can send routine work to a cheap or local model and hard work to a frontier one, the model-routing cost lever from our token cost optimization playbook, without provider-specific branching.
  • Build agents on top with Agent Framework. When you need agents, add Agent Framework over the same abstractions rather than switching foundations.

Do this and your .NET AI code is portable, observable, and cost-flexible from the start, because the foundation was built for exactly that.

The takeaway

Microsoft.Extensions.AI is the foundational abstraction layer of the .NET AI stack: a set of provider-agnostic interfaces (chiefly IChatClient) plus middleware that give you one consistent, swappable way to talk to any model provider, the ILogger of AI. It solves provider lock-in, makes model routing and local-model use trivial, and provides standardized telemetry and caching across providers. It sits at the root, everything including Microsoft Agent Framework builds on it, so the practical rule is to write your AI logic against these abstractions rather than a specific vendor SDK. Depend on the foundation, and every future change stays cheap; skip it, and you weld your code to a provider you will eventually want to change.

If you want .NET AI systems built on the right foundation, portable, observable, and cost-flexible, that is where our AI Dev Team work starts.

FAQ

What is Microsoft.Extensions.AI? The foundational abstraction layer for AI in .NET: a set of interfaces (most importantly IChatClient) that give your code one consistent, provider-agnostic way to talk to any AI model provider (Azure OpenAI, OpenAI, Ollama, Anthropic, local models), plus middleware for telemetry, caching, and tool calling.

What is IChatClient? The core interface in Microsoft.Extensions.AI for chat-based model interactions, sending messages, receiving responses, and streaming, that every provider implements. Writing against IChatClient instead of a specific provider SDK means you can swap providers by changing configuration rather than rewriting your logic.

Why use Microsoft.Extensions.AI instead of a provider SDK directly? To avoid lock-in. Coding against a provider's SDK welds your logic to that vendor's API, so switching providers, adding a local model, or routing across models means rewriting code. The abstraction makes the provider a swappable detail, and adds uniform telemetry and caching, the same benefit ILogger gives for logging.

How does Microsoft.Extensions.AI relate to Agent Framework? Microsoft.Extensions.AI is the root abstraction (talking to models via IChatClient); Microsoft Agent Framework builds on top of it to create agents and orchestrate workflows. An agent's model calls ultimately go through the Extensions.AI abstractions, so you write agent logic in Agent Framework against that foundation.

Does Microsoft.Extensions.AI support local models? Yes. Because it is provider-agnostic, local runtimes like Ollama (and others exposed through compatible implementations) are just another IChatClient. This makes it straightforward to use a local model for cost or privacy on some calls and a cloud provider on others, without provider-specific code.

“You can’t monetize pain. You can only monetize value. The moment users feel cared for, they’ll see paying as an investment in themselves — not a cost.”

You know what you want to build. Let's go ship it.

Book a 15-min call
Book a 15-min call
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.