BrandGhost
Migrating from Semantic Kernel to Microsoft Agent Framework in C#

Migrating from Semantic Kernel to Microsoft Agent Framework in C#

Migrating from Semantic Kernel to Microsoft Agent Framework in C#

If you have been building AI-powered applications in C# with Semantic Kernel, you have probably heard about Microsoft's newer Agent Framework (MAF). Deciding whether to migrate semantic kernel microsoft agent framework in your own project is not a simple yes-or-no question -- and that is exactly what this guide is for. We will walk through the honest tradeoffs, a concrete API mapping table, side-by-side code comparisons, and the gotchas that are easy to miss the first time through.

A quick note before we dive in: MAF is in public preview at version 1.0.0-rc1. APIs are stable enough to build on, but expect some surface-area changes before GA. Plan accordingly before committing production workloads.

When to Migrate vs. Stay on Semantic Kernel

Not every project should migrate. Semantic Kernel is a mature, feature-rich library with a large community, extensive documentation, and a complete plugin ecosystem. If your SK-based application is working well, migration has a real cost -- and that cost should be weighed carefully.

Good reasons to migrate to MAF:

  • You want to align with the IChatClient abstraction from Microsoft.Extensions.AI, which is becoming the standard surface for AI in .NET
  • Your architecture is relatively simple (single agent, limited tool use) and you want fewer abstractions to manage
  • You are starting a new project and want a lighter starting point with flexibility to grow
  • You are building something that plugs into IChatClient-aware middleware (logging, caching, retries) and want seamless composition

Good reasons to stay on Semantic Kernel:

  • You have significant existing investment in SK plugins, planners, and memory pipelines
  • You rely on SK's KernelMemory, vector store integrations, or embedding pipeline
  • Your team is productive in SK and the ecosystem meets your current needs
  • You need AgentGroupChat orchestration for complex multi-agent workflows

The honest take: for simple agent use cases, MAF is a cleaner entry point. For complex enterprise AI systems with RAG, memory, and multi-step planning, SK still has the richer toolset. If you want a clear picture of where SK's agent model stands before making this call, the Semantic Kernel Agents in C# guide is a solid baseline reference.

What MAF Brings That SK Doesn't

The core value proposition of the Microsoft Agent Framework is a simpler mental model. Rather than wrapping everything in a Kernel object, MAF works directly with IChatClient -- the lightweight abstraction from Microsoft.Extensions.AI. This has a few important downstream effects.

First, composability improves. Because IChatClient is the standard .NET AI interface, you get middleware support out of the box, and any tool that targets IChatClient integrates automatically. SK's IChatCompletionService is SK-specific; you cannot compose it with non-SK middleware without adapter shims.

Second, the learning curve is lower. There is no Kernel to configure, no KernelBuilder to understand, and no SemanticKernelOptions to wire up. You create a client, call .AsAIAgent(), and you are running. For teams new to AI development in C#, that reduced surface area matters.

Third, tool invocation is automatic. In SK, you configure FunctionChoiceBehavior to control when and how functions are called. In MAF, tool invocation is handled automatically when tools are registered -- no extra behavior configuration required.

What SK Still Does Better

MAF is not a full replacement for everything SK offers -- at least not yet. Being clear about that is important before you commit to a migration.

Plugin ecosystem: SK has a rich library of built-in plugins, a standardized KernelPlugin model, and community-contributed integrations. MAF's AIFunction-based tools work well, but they don't have the same breadth of ready-made options. Everything you have done following Semantic Kernel Plugin Best Practices does not translate directly.

Memory and RAG: SK's KernelMemory, vector store integrations, and embedding pipeline are genuinely production-ready. MAF does not yet have a comparable built-in memory system. If you are building retrieval-augmented generation workflows, SK has a significant lead -- the RAG with Semantic Kernel patterns represent real work you would need to replicate elsewhere.

Multi-agent orchestration: SK's AgentGroupChat with selection and termination strategies is a mature feature with documented patterns for Multi-Agent Orchestration with Semantic Kernel. MAF's multi-agent story is still developing.

Larger ecosystem: More documentation, more blog posts, more community Q&A. That counts for something when you are debugging a production issue under time pressure.

API Mapping: SK Concepts to MAF Equivalents

Here is a quick reference for the most common SK to MAF translations:

Semantic Kernel Concept MAF Equivalent
Kernel Direct IChatClient (no container needed)
IChatCompletionService IChatClient
ChatCompletionAgent chatClient.AsAIAgent()
[KernelFunction] attribute AIFunctionFactory.Create()
KernelPlugin AIFunction[] (array of tools)
FunctionChoiceBehavior Automatic (no configuration needed)
ChatHistoryAgentThread AgentSession
KernelArguments Direct method parameters
services.AddKernel() services.AddChatClient(...)

The table covers the 80% case for a typical migration. The Kernel disappearing is the biggest conceptual shift -- MAF trusts you to manage your IChatClient instance directly rather than hiding it behind a container object.

Migrating a Sample SK App to MAF

Enough theory -- let's look at code. The following examples cover the four most common migration scenarios you will encounter when you migrate semantic kernel microsoft agent framework in a real project. Each shows the SK version first, then the MAF equivalent, so you can compare them side by side.

Let's walk through four concrete migration examples.Each shows the SK version first, followed by the MAF equivalent.

Example 1: Simple Chat Agent

The most common starting point is a single agent that responds to messages.

// ── Semantic Kernel ──────────────────────────────────────
var builder = Kernel.CreateBuilder();
builder.AddOpenAIChatCompletion("gpt-4o", apiKey);
var kernel = builder.Build();

var agent = new ChatCompletionAgent
{
    Name = "Assistant",
    Instructions = "You are a helpful C# coding assistant.",
    Kernel = kernel
};

var thread = new ChatHistoryAgentThread();
await foreach (var msg in agent.InvokeAsync("Explain async/await briefly.", thread))
{
    Console.WriteLine(msg.Content);
}
// ── Microsoft Agent Framework ────────────────────────────
IChatClient client = new OpenAIClient(apiKey)
    .GetChatClient("gpt-4o")
    .AsIChatClient();

IAIAgent agent = client.AsAIAgent(
    instructions: "You are a helpful C# coding assistant.");

AgentSession session = await agent.CreateSessionAsync();
AgentResponse response = await agent.RunAsync("Explain async/await briefly.", session);
Console.WriteLine(response.Text);

The structural difference is immediately visible. The Kernel and KernelBuilder are gone. You get an IChatClient from your provider of choice, call .AsAIAgent(), and start a session. Less ceremony for the same basic capability. For more context on what ChatCompletionAgent was doing under the hood in SK, see ChatCompletionAgent vs AssistantAgent in Semantic Kernel.

Example 2: Function/Tool Registration

Registering custom tools is where the migration gets more involved.

// ── Semantic Kernel ──────────────────────────────────────
public class WeatherPlugin
{
    [KernelFunction("get_weather")]
    [Description("Gets the current weather for a city")]
    public string GetWeather(string city)
        => $"The weather in {city} is 22°C and sunny.";
}

var kernel = Kernel.CreateBuilder()
    .AddOpenAIChatCompletion("gpt-4o", apiKey)
    .Build();

kernel.Plugins.AddFromType<WeatherPlugin>();

var agent = new ChatCompletionAgent
{
    Kernel = kernel,
    Instructions = "You help users with weather queries.",
    Arguments = new KernelArguments(
        new PromptExecutionSettings
        {
            FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
        })
};
// ── Microsoft Agent Framework ────────────────────────────
static string GetWeather(string city)
    => $"The weather in {city} is 22°C and sunny.";

AIFunction weatherFunction = AIFunctionFactory.Create(
    GetWeather,
    name: "get_weather",
    description: "Gets the current weather for a city");

IChatClient client = new OpenAIClient(apiKey)
    .GetChatClient("gpt-4o")
    .AsIChatClient();

IAIAgent agent = client.AsAIAgent(
    instructions: "You help users with weather queries.",
    tools: [weatherFunction]); // tool invocation is automatic

This is the most significant ergonomic change in the migration. In SK, you define a class, decorate methods with [KernelFunction], register a plugin, and configure FunctionChoiceBehavior. In MAF, you pass a delegate to AIFunctionFactory.Create() and add it to the tools list -- no attributes, no plugin class, no behavior configuration needed.

If you have heavily invested in SK's [KernelFunction] plugin pattern, this part of the migration is real work. The Semantic Kernel Function Calling article gives you a clear picture of the function calling mechanics you are replacing.

Example 3: Multi-Turn Conversation

Maintaining conversation history across multiple messages is a first-class concern for any agent.

// ── Semantic Kernel ──────────────────────────────────────
var kernel = Kernel.CreateBuilder()
    .AddOpenAIChatCompletion("gpt-4o", apiKey)
    .Build();

var agent = new ChatCompletionAgent
{
    Kernel = kernel,
    Instructions = "You are a math tutor."
};

var thread = new ChatHistoryAgentThread();

// Turn 1
await foreach (var msg in agent.InvokeAsync("What is 15 multiplied by 4?", thread))
    Console.WriteLine(msg.Content);

// Turn 2 -- thread maintains context automatically
await foreach (var msg in agent.InvokeAsync("Now divide that result by 3.", thread))
    Console.WriteLine(msg.Content);
// ── Microsoft Agent Framework ────────────────────────────
IChatClient client = new OpenAIClient(apiKey)
    .GetChatClient("gpt-4o")
    .AsIChatClient();

IAIAgent agent = client.AsAIAgent(
    instructions: "You are a math tutor.");

// AgentSession manages history automatically
AgentSession session = await agent.CreateSessionAsync();

// Turn 1
AgentResponse r1 = await agent.RunAsync("What is 15 multiplied by 4?", session);
Console.WriteLine(r1.Text);

// Turn 2 -- session maintains context
AgentResponse r2 = await agent.RunAsync("Now divide that result by 3.", session);
Console.WriteLine(r2.Text);

The session abstraction in MAF closely mirrors SK's ChatHistoryAgentThread. Both maintain message history automatically -- the API surface is just more compact. Be deliberate about session lifetime in DI scenarios: a scoped session is appropriate for a single user interaction, while a singleton session would share history across all callers.

Example 4: Dependency Injection Setup

DI wiring is where the Kernel disappears most dramatically.

// ── Semantic Kernel ──────────────────────────────────────
// Program.cs
services.AddKernel()
    .AddOpenAIChatCompletion("gpt-4o", apiKey);

// Service class
public class ChatService
{
    private readonly Kernel _kernel;

    public ChatService(Kernel kernel)
    {
        _kernel = kernel;
    }
}
// ── Microsoft Agent Framework ────────────────────────────
// Program.cs
services.AddOpenAIClient(options =>
    options.Credential = new ApiKeyCredential(apiKey));

services.AddChatClient(sp =>
    sp.GetRequiredService<OpenAIClient>().GetChatClient("gpt-4o").AsIChatClient());

// Service class -- no Kernel dependency
public class ChatService
{
    private readonly IChatClient _client;

    public ChatService(IChatClient client)
    {
        _client = client;
    }
}

The shift from injecting Kernel to injecting IChatClient has real architectural value. IChatClient is defined in Microsoft.Extensions.AI -- a package with no dependency on Semantic Kernel. Your service layer no longer has an implicit hard dependency on SK, and swapping AI providers becomes a configuration concern rather than a code change.

Migration Pitfalls and Gotchas

Even with a clear API mapping, several things tend to catch developers off guard when migrating from Semantic Kernel.

Plugin discovery is manual in MAF: SK can discover [KernelFunction] methods automatically via reflection when you call AddFromType<T>(). MAF's AIFunctionFactory.Create() requires explicit registration of each function. If you have large plugin classes with many methods, this is significant manual work -- plan your inventory before starting.

Streaming differences: SK's InvokeStreamingAsync has a well-documented streaming model. MAF's streaming is available through IChatClient, but the event model differs slightly. Test your streaming paths explicitly -- don't assume they behave identically.

Error handling changes: SK throws KernelException subtypes. MAF surfaces errors as standard HttpRequestException or provider-specific exceptions. Update your catch blocks accordingly, or you will miss errors silently.

No automatic planner: SK has FunctionCallingStepwisePlanner and related planning capabilities. MAF does not include a built-in planner. If you relied on SK planning for multi-step reasoning, you need a different strategy.

Session lifetime in DI: Be deliberate about when you create and dispose AgentSession objects. A scoped session is usually the right choice in a web application context. A singleton session would share conversation history across all requests -- almost certainly not what you want.

Preview API instability: MAF is at 1.0.0-rc1. Breaking changes are still possible before GA. Pin your NuGet versions, review the changelog on each update, and avoid upgrading blindly in production.

What MAF Doesn't Have Yet

Being honest about gaps is important when evaluating any migration. Here is what you would lose by moving away from SK in the current release.

No built-in memory system: SK's KernelMemory and vector store integrations are production-ready. MAF does not yet have a comparable built-in memory system. If your SK app uses memory or embeddings heavily, you would need to bring your own RAG infrastructure -- a meaningful effort.

No AgentGroupChat equivalent: SK's multi-agent orchestration with selection strategies and termination conditions is a mature, documented feature. MAF's multi-agent story is still developing. If you are building workflows where multiple agents collaborate, SK is the stronger choice at 1.0.0-rc1.

No prompt template engine: SK has a dedicated prompt template language with variable substitution and function call syntax. MAF assumes you build prompts programmatically. For simple scenarios this is fine; for complex, parameterized prompt libraries it is a real gap.

Smaller community: Fewer blog posts, fewer community examples, fewer answered questions on forums. For a public preview framework this is expected, but it matters when you hit an edge case and need help fast.

If any of these gaps apply to your project, the Building AI Agents with Semantic Kernel patterns are still the stronger reference for production-grade agent work in .NET.

Frequently Asked Questions

The questions below cover the most common concerns developers raise when evaluating whether to migrate semantic kernel microsoft agent framework -- from compatibility questions to production readiness and what to do about existing plugins.

Is Microsoft Agent Framework a replacement for Semantic Kernel?

Not yet. MAF is a lighter, IChatClient-native option that works well for simpler agent use cases. SK remains the richer option for complex enterprise AI applications with memory, RAG pipelines, and advanced multi-agent orchestration. The two can also coexist in the same solution -- you do not have to choose all-or-nothing.

Can I use Semantic Kernel plugins with MAF?

Not directly. SK plugins use the [KernelFunction] attribute and KernelPlugin registration system, which are SK-specific. To use the same functionality in MAF, you rewrite the registration using AIFunctionFactory.Create(). If your plugin logic is plain C# methods, the migration is straightforward. If it depends on SK-specific types or KernelArguments, budget more time to untangle those dependencies.

Is it safe to use MAF in production?

MAF is at 1.0.0-rc1 -- public preview. The core APIs are stable enough for non-critical production workloads, but pin your NuGet versions and expect possible breaking changes before GA. For mission-critical systems, the pragmatic move is to wait for the GA release or commit to a rigorous testing regimen on each update.

What NuGet packages do I need for MAF?

The core packages are Microsoft.Extensions.AI and a provider adapter such as Microsoft.Extensions.AI.OpenAI. For the agent-specific APIs, look for Microsoft.Extensions.AI.Agents or the relevant agent extensions package. Package naming has shifted during the preview period, so check the official package feed for the latest naming before adding references.

Does MAF support function calling and tool use?

Yes. Register functions via AIFunctionFactory.Create() and pass them in AgentOptions.Tools. Tool invocation is handled automatically -- there is no equivalent to SK's FunctionChoiceBehavior that you need to configure. If you want to understand the underlying mechanics before migrating, the Semantic Kernel Function Calling article explains the function calling model you are replacing.

Can I migrate incrementally rather than all at once?

Yes -- incremental migration is usually the safest approach. Because MAF is built on IChatClient and SK can expose its completion service through adapter shims, you can introduce MAF components alongside existing SK code. Migrate one agent or one workflow at a time, validate behavior at each step, and continue from there. This reduces risk significantly compared to a big-bang rewrite.

What happens to my SK [KernelFunction] plugins if I migrate?

The [KernelFunction] attribute is SK-specific and not recognized by MAF. You will need to re-register those functions using AIFunctionFactory.Create(). For simple functions, this is a few lines of code per function. For large plugin classes with many methods and complex KernelArguments usage, budget real time to do this properly. Inventory your plugins before starting so the scope is clear -- the Semantic Kernel Plugins Complete Guide is a useful reference for understanding what you have.

Wrapping Up

Migrating from Semantic Kernel to Microsoft Agent Framework in C# is a practical option for teams that want a lighter, IChatClient-native agent experience. The API mapping is clean for simple use cases -- Kernel goes away, IChatCompletionService becomes IChatClient, and [KernelFunction] becomes AIFunctionFactory.Create(). For straightforward agents with a small number of tools, the migration is manageable and the resulting code is leaner.

The gaps are real though. No built-in memory, no planner, no AgentGroupChat, and a smaller community mean that teams with deep SK investment in those areas should think carefully before switching. The clearest green light is when you have a simple agent, minimal plugin surface area, and want to align with Microsoft.Extensions.AI as your standard AI abstraction going forward.

Remember -- MAF is still in public preview. Pin your NuGet versions, review the changelog carefully on each update, and migrate incrementally rather than all at once. For a full picture of the SK ecosystem you might be leaving behind, the Semantic Kernel in C# Complete Guide is a useful reference as you plan.

Getting Started with Microsoft Agent Framework in C#

Getting started with Microsoft Agent Framework in C# is fast. Install packages, configure OpenAI or Azure OpenAI, and build your first streaming agent.

Semantic Kernel Agents in C#: Complete Guide to AI Agents

Master Semantic Kernel agents in C# with ChatCompletionAgent, AgentGroupChat orchestration, and Microsoft Agent Framework integration.

Microsoft Agent Framework in C#: Complete Developer Guide

Complete guide to Microsoft Agent Framework in C#. Core abstractions, architecture, tool registration, sessions, and where MAF fits in the .NET AI ecosystem.

An error has occurred. This application may no longer respond until reloaded. Reload