Semantic Kernel is Microsoft's open-source SDK for integrating large language models into C#, Python and Java applications through plugins, prompt templates, automatic function calling and filters. It powers a large number of production systems, and in 2026 it sits in an unusual position: still maintained and still shipping releases, but officially succeeded by Microsoft Agent Framework. This guide shows how to use Semantic Kernel well in practice, explains where it stands today, and helps you decide when it is still the right fit and how to plan a migration.
What Is Semantic Kernel?#
At its core, Semantic Kernel is a lightweight dependency injection container, the Kernel, that holds two kinds of components: services, such as chat completion, embedding generation, logging and HTTP clients, and plugins, which are named groups of functions the model can call or that prompts can reference. Around that core it adds prompt templating, automatic function calling, filters for cross-cutting control, agent abstractions and connectors for many model providers.
The .NET packages are versioned together. Microsoft.SemanticKernel is the convenience package that brings in the core and the OpenAI connectors, and version 1.80.1 shipped in September 2026. Some areas, notably the agent orchestration and in-process runtime packages, are still published with a -preview suffix, and individual experimental APIs carry SKEXP diagnostic IDs.
Semantic Kernel also shaped the rest of the .NET AI stack. The IChatClient and IEmbeddingGenerator abstractions in Microsoft.Extensions.AI were extracted from it, and its vector store abstractions became Microsoft.Extensions.VectorData. Modern Semantic Kernel builds on those shared types, so you can register an IChatClient in a kernel with AddOpenAIChatClient or use the classic IChatCompletionService registered by AddOpenAIChatCompletion.
Where Semantic Kernel Stands in 2026#
The most important fact for any team evaluating Semantic Kernel today is that the project's own README now states that Microsoft Agent Framework is its enterprise-ready successor. Agent Framework was built by the Semantic Kernel and AutoGen teams, reached 1.0 in April 2026, and receives the new features. Semantic Kernel continues to publish releases, but you should read those releases as maintenance of a mature product rather than a signal of where investment is going.
Two concrete changes illustrate the shift:
- Vector store connectors moved out. The packages that used to be named
Microsoft.SemanticKernel.Connectors.InMemory,.AzureAISearch,.PgVector,.Qdrant,.SqlServerand others are deprecated on NuGet. They were renamed toCommunityToolkit.VectorData.*packages with stable 1.0 releases, because they implement Microsoft.Extensions.VectorData and have no dependency on Semantic Kernel. - Agent features converged in Agent Framework. Semantic Kernel's agent orchestration APIs remained experimental, while Agent Framework shipped stable workflows with sequential, concurrent, handoff, group chat and Magentic patterns.
The practical guidance follows directly. Start new projects on Agent Framework or, for simpler features, directly on Microsoft.Extensions.AI. Keep existing Semantic Kernel applications running, keep them patched, and plan a migration on your own schedule. For the official statement about the support window, check the Semantic Kernel and Agent Framework announcement linked from the Semantic Kernel repository, since support terms are the kind of detail that should come from the source.
How Semantic Kernel Works#
When you invoke a prompt or function through the kernel, a predictable sequence runs:
- The kernel selects the AI service that should run the prompt, optionally using a service ID.
- The prompt template is rendered with
KernelArguments, which can call other kernel functions inline. - Prompt render filters can inspect or rewrite the rendered prompt.
- The rendered prompt goes to the model with
PromptExecutionSettings, including the function choice behavior that advertises plugins as tools. - If the model requests tool calls, the kernel invokes the matching
KernelFunctions, running auto function invocation filters and function invocation filters around each call. - The final result comes back as a
FunctionResultor chat message content.
| Concept | What it is | Typical API |
|---|---|---|
Kernel | Container of services and plugins | Kernel.CreateBuilder(), kernel.Plugins |
KernelFunction | A callable unit, native or prompt-based | [KernelFunction], CreateFunctionFromPrompt |
KernelPlugin | A named group of functions | Plugins.AddFromType<T>(), AddFromObject |
KernelArguments | Variables plus execution settings | new KernelArguments(settings) { ["input"] = text } |
PromptExecutionSettings | Model parameters and tool behavior | FunctionChoiceBehavior.Auto() |
| Filters | Middleware for functions and prompts | IFunctionInvocationFilter, IPromptRenderFilter, IAutoFunctionInvocationFilter |
| Agents | Higher-level conversational wrappers | ChatCompletionAgent, AgentThread |
Getting Started with Semantic Kernel#
Install the core package and, if you plan to use agents, the agents package:
dotnet add package Microsoft.SemanticKernel
dotnet add package Microsoft.SemanticKernel.Agents.CoreThe canonical first program builds a kernel with a chat completion service, registers a plugin and lets the model call it automatically:
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;
IKernelBuilder builder = Kernel.CreateBuilder();
builder.AddOpenAIChatCompletion("gpt-5-mini",
Environment.GetEnvironmentVariable("OPENAI_API_KEY")!);
builder.Plugins.AddFromType<OrderPlugin>("orders");
Kernel kernel = builder.Build();
var chat = kernel.GetRequiredService<IChatCompletionService>();
OpenAIPromptExecutionSettings settings = new()
{
FunctionChoiceBehavior = FunctionChoiceBehavior.Auto(),
};
ChatHistory history = [];
history.AddSystemMessage("You are a support assistant for an online bookstore.");
history.AddUserMessage("Has order 1042 shipped yet?");
ChatMessageContent reply = await chat.GetChatMessageContentAsync(history, settings, kernel);
Console.WriteLine(reply.Content);
history.Add(reply);Passing the kernel into GetChatMessageContentAsync is what makes plugins available as tools and what triggers filters. Forgetting it is the most common reason function calling "does nothing".
Building Plugins with KernelFunction#
A native plugin is an ordinary class whose methods carry [KernelFunction] and [Description] attributes. Descriptions are not decoration: they become the tool schema the model reads, so they directly affect how accurately the model picks and fills functions. Plugin classes support constructor injection, which is one of Semantic Kernel's strengths for enterprise code:
using System.ComponentModel;
using Microsoft.SemanticKernel;
public sealed class OrderPlugin(IOrderRepository orders, TimeProvider clock)
{
[KernelFunction("get_order_status")]
[Description("Gets the shipping status of an order by its number.")]
public async Task<OrderStatus?> GetOrderStatusAsync(
[Description("The numeric order number, for example 1042.")] int orderNumber,
CancellationToken cancellationToken)
{
return await orders.GetStatusAsync(orderNumber, cancellationToken);
}
[KernelFunction("get_business_date")]
[Description("Gets today's date in UTC. Use it to reason about delivery times.")]
public string GetBusinessDate() => clock.GetUtcNow().ToString("yyyy-MM-dd");
}
public sealed record OrderStatus(int OrderNumber, string State, DateOnly? ShippedOn);Plugins.AddFromType<OrderPlugin>() resolves constructor parameters from the kernel's service provider, and AddFromObject registers an instance you created yourself. The documentation recommends snake_case function names because many models are trained on Python-style tool names, and it echoes OpenAI's advice to keep the number of tools per request small, ideally around ten, because selection accuracy degrades as the list grows. Beyond native code, Semantic Kernel can import plugins from OpenAPI specifications and from MCP servers.
Prompt Functions and Prompt Templates#
Prompt functions turn a template into a reusable KernelFunction. The default template syntax uses {{$variable}} for arguments and {{plugin.function}} to call another function and inline its result. Execution settings travel with the function or with the arguments:
KernelFunction summarize = kernel.CreateFunctionFromPrompt(
"""
Summarize the customer email below for a support agent.
Today is {{orders.get_business_date}}.
Respond with at most {{$maxBullets}} bullet points.
Email:
{{$email}}
""",
new OpenAIPromptExecutionSettings { MaxTokens = 300, Temperature = 0.2 },
functionName: "summarize_email",
description: "Summarizes a customer email for triage.");
FunctionResult summary = await kernel.InvokeAsync(summarize, new KernelArguments
{
["email"] = incomingEmail,
["maxBullets"] = 4,
});
Console.WriteLine(summary.GetValue<string>());For one-off prompts, kernel.InvokePromptAsync(template, arguments) renders and runs a template without creating a named function. When you need loops or conditionals, install Microsoft.SemanticKernel.PromptTemplates.Handlebars or .Liquid and pass the matching template format and factory. Prompts can also live in YAML files, loaded through the Microsoft.SemanticKernel.Yaml package, which keeps them out of code and makes them reviewable like any other configuration.
One security note belongs next to templates: any value you insert from users, emails or documents is untrusted. Semantic Kernel HTML-encodes inserted variables and function results by default, so they cannot smuggle extra chat messages into a prompt, and you must opt in with AllowUnsafeContent to trust them. No templating feature, however, can stop a model from following instructions hidden in the content itself. Keep system instructions separate, constrain tools and treat model output as untrusted; the prompt engineering guide covers these techniques in more depth.
Automatic and Manual Function Calling#
FunctionChoiceBehavior controls how plugins are advertised to the model:
FunctionChoiceBehavior.Auto()lets the model decide whether to call functions, and invokes them automatically by default.FunctionChoiceBehavior.Required()forces the model to call at least one of the specified functions, which is useful for extraction.FunctionChoiceBehavior.None()describes functions without letting the model call them.
Each accepts an optional list of functions to restrict what is advertised, which is an easy way to keep the tool list small per request. Passing autoInvoke: false switches to manual invocation, where you inspect each requested call and decide what to run:
PromptExecutionSettings manual = new()
{
FunctionChoiceBehavior = FunctionChoiceBehavior.Auto(autoInvoke: false),
};
while (true)
{
ChatMessageContent result = await chat.GetChatMessageContentAsync(history, manual, kernel);
if (result.Content is not null)
{
Console.WriteLine(result.Content);
break;
}
history.Add(result); // keep the model's tool requests in the history
foreach (FunctionCallContent call in FunctionCallContent.GetFunctionCalls(result))
{
if (!await policy.IsAllowedAsync(call.PluginName, call.FunctionName, call.Arguments))
{
history.Add(new FunctionResultContent(call, "Not permitted.").ToChatMessage());
continue;
}
FunctionResultContent output = await call.InvokeAsync(kernel);
history.Add(output.ToChatMessage());
}
}Manual invocation is the right choice when each call needs its own authorization, auditing or user confirmation, and it is also how you parallelize independent calls under your own control.
Filters: Function Invocation, Prompt Render and Auto Function Invocation#
Filters are Semantic Kernel's middleware. Each receives a context object and a next delegate, and must call next for the operation to proceed. There are three kinds:
- Function invocation filters run around every
KernelFunctioncall, whether the function is native or prompt-based. Use them for logging, caching, exception handling, retries and result overrides. - Prompt render filters run around prompt rendering. Use them to redact personal data, inject retrieved context or short-circuit with a cached answer.
- Auto function invocation filters run inside the automatic tool loop and see the chat history, the list of pending calls and iteration counters. Use them to terminate the loop early or veto calls.
public sealed class ToolAuditFilter(ILogger<ToolAuditFilter> logger) : IAutoFunctionInvocationFilter
{
private static readonly HashSet<string> Blocked = ["delete_order", "issue_refund"];
public async Task OnAutoFunctionInvocationAsync(AutoFunctionInvocationContext context,
Func<AutoFunctionInvocationContext, Task> next)
{
string name = context.Function.Name;
if (Blocked.Contains(name))
{
context.Result = new FunctionResult(context.Function, "This action requires a human agent.");
context.Terminate = true; // stop the tool loop and return to the caller
return;
}
logger.LogInformation("Model called {Plugin}.{Function} (request {Index})",
context.Function.PluginName, name, context.RequestSequenceIndex);
await next(context);
}
}
public sealed class EmailRedactionFilter : IPromptRenderFilter
{
public async Task OnPromptRenderAsync(PromptRenderContext context,
Func<PromptRenderContext, Task> next)
{
await next(context);
context.RenderedPrompt = Regex.Replace(context.RenderedPrompt ?? "",
@"[\w.+-]+@[\w-]+(\.[\w-]+)+", "[email]");
}
}Register filters on the kernel's collections, such as kernel.AutoFunctionInvocationFilters.Add(...) and kernel.PromptRenderFilters.Add(...), or through dependency injection. The documentation notes that the execution order of filters registered through DI is not guaranteed, so add them directly to the kernel when order matters.
Vector Stores and RAG with Semantic Kernel#
Semantic Kernel's vector store support is now provided by Microsoft.Extensions.VectorData, with connectors in the CommunityToolkit.VectorData.* packages. That means retrieval code written for a Semantic Kernel app is plain MEVD code that also works in Agent Framework. The simplest way to use retrieval in a kernel is a plugin that searches a collection and returns formatted snippets with sources:
using System.ComponentModel;
using System.Text;
using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel;
public sealed class PolicySearchPlugin(VectorStoreCollection<string, PolicyChunk> policies)
{
[KernelFunction("search_policies")]
[Description("Searches company policies. Returns excerpts with their source titles.")]
public async Task<string> SearchAsync(
[Description("A natural-language search query.")] string query,
CancellationToken cancellationToken)
{
var sb = new StringBuilder();
await foreach (var hit in policies.SearchAsync(query, top: 4,
new() { Filter = p => p.IsPublished }, cancellationToken))
{
sb.AppendLine($"[{hit.Record.Title}] {hit.Record.Text}");
}
return sb.Length > 0 ? sb.ToString() : "No matching policy found.";
}
}The collection handles embedding generation if you configured an IEmbeddingGenerator on the store, and the Filter expression pushes metadata filtering into the database, provided the property is marked as indexed. Chunking, hybrid search, reranking and evaluation are covered in depth in the RAG in .NET guide.
Agents in Semantic Kernel#
Semantic Kernel's agent framework wraps a kernel in conversational abstractions. ChatCompletionAgent is the general-purpose agent, backed by any chat completion service in the kernel, and AgentThread implementations such as ChatHistoryAgentThread hold the conversation:
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using Microsoft.SemanticKernel.ChatCompletion;
ChatCompletionAgent agent = new()
{
Name = "SupportAgent",
Instructions = "Answer order questions using the available tools. Be concise.",
Kernel = kernel,
Arguments = new KernelArguments(new PromptExecutionSettings
{
FunctionChoiceBehavior = FunctionChoiceBehavior.Auto(),
}),
};
AgentThread thread = new ChatHistoryAgentThread();
await foreach (AgentResponseItem<ChatMessageContent> item in agent.InvokeAsync(
new ChatMessageContent(AuthorRole.User, "Where is order 1042?"), thread))
{
Console.WriteLine(item.Message.Content);
thread = item.Thread;
}Semantic Kernel also offers SequentialOrchestration, ConcurrentOrchestration, HandoffOrchestration, GroupChatOrchestration and MagenticOrchestration, run on an InProcessRuntime. Those packages are still marked as preview and the documentation labels orchestration as experimental, which is a strong reason to build new multi-agent systems on Agent Framework workflows instead.
Best Practices#
- Pass the kernel wherever tools or filters should apply. Chat completion calls made without a kernel skip function calling and filters.
- Write descriptions for the model, not for humans. Explain when to use a function, required formats and units, and keep parameter lists short and primitive.
- Scope tools per request. Pass explicit function lists to
FunctionChoiceBehavior.Autorather than exposing every plugin on every call. - Create kernels per operation. The documentation recommends registering the kernel as transient because its plugin collection is mutable; kernels are cheap containers.
- Put policy in filters. Authorization, redaction and auditing belong in function and prompt filters, where they apply consistently.
- Adopt shared abstractions now. Use
IChatClient,IEmbeddingGeneratorand Microsoft.Extensions.VectorData in new code, which shortens any future migration.
Common Pitfalls#
- Using deprecated connector packages. The
Microsoft.SemanticKernel.Connectors.*vector store packages are deprecated; switch to theCommunityToolkit.VectorData.*equivalents. - Relying on legacy memory APIs. The old memory store connectors are superseded by the vector store abstractions.
- Filter order surprises. Filters registered through DI run in an unspecified order; register order-sensitive filters directly on the kernel.
- Unbounded automatic tool loops. Use an auto function invocation filter to terminate loops that meet their goal early or run too long.
- Building new multi-agent systems on experimental orchestration. Semantic Kernel orchestrations are still preview; Agent Framework workflows are stable.
- Starting greenfield projects on Semantic Kernel. The project points new users to Agent Framework, so new code on Semantic Kernel creates migration work later.
Semantic Kernel vs Microsoft Agent Framework vs Microsoft.Extensions.AI#
| Criterion | Semantic Kernel | Microsoft Agent Framework | Microsoft.Extensions.AI |
|---|---|---|---|
| Status in 2026 | Maintained, successor announced | Stable 1.x, active development | Stable, active development |
| Core abstraction | Kernel with plugins and services | AIAgent, AgentSession, workflows | IChatClient, IEmbeddingGenerator |
| Tools | [KernelFunction] plugins, OpenAPI, MCP | AIFunction tools, MCP, hosted tools | AIFunction with UseFunctionInvocation |
| Prompt templates | Built in, Handlebars and Liquid | Instructions and context providers | Not included |
| Middleware | Filters | Agent, function and chat client middleware | Delegating chat clients |
| Multi-agent orchestration | Preview orchestrations | Stable workflows with checkpoints | Not included |
| Best fit | Existing SK apps, template-heavy prompt pipelines | New agents and multi-agent systems | Direct model features and libraries |
Semantic Kernel is still a good fit when you already run it in production and it meets your needs, when your application relies heavily on its prompt templating and plugin model, or when a team's Java or Python codebases already standardize on it. For everything new, prefer Agent Framework or Microsoft.Extensions.AI.
Frequently Asked Questions#
Is Semantic Kernel deprecated?#
No, it is not marked as deprecated, and it continues to ship releases. However, its repository states that Microsoft Agent Framework is its enterprise-ready successor, and new features are developed there. Treat Semantic Kernel as a maintained platform for existing applications rather than the default for new ones.
Can I use Semantic Kernel and Agent Framework in the same application?#
Yes. Both build on Microsoft.Extensions.AI types, so an IChatClient and a Microsoft.Extensions.VectorData collection can be shared between them. This makes incremental migration practical: new features use Agent Framework while existing plugins keep running until you port them.
What replaced the Semantic Kernel vector store connectors?#
The abstractions are in Microsoft.Extensions.VectorData.Abstractions, and the connectors were renamed to CommunityToolkit.VectorData.* packages, such as CommunityToolkit.VectorData.AzureAISearch and CommunityToolkit.VectorData.PgVector. The APIs are the same abstractions you already use, so the move is mostly a package and namespace change.
Should I use IChatCompletionService or IChatClient with Semantic Kernel?#
Both work. IChatCompletionService is the classic Semantic Kernel interface used by most samples and filters, while IChatClient is the shared Microsoft.Extensions.AI abstraction registered with methods such as AddOpenAIChatClient. Prefer IChatClient in new code because it carries over directly to Agent Framework.
How do I stop a runaway automatic function calling loop?#
Implement an IAutoFunctionInvocationFilter that inspects the request sequence and function names, and set context.Terminate = true when the goal is met or a limit is reached. Restricting the functions passed to FunctionChoiceBehavior.Auto also reduces unnecessary calls.
Summary#
- Semantic Kernel organizes AI apps around a
Kernelof services and plugins, with prompt templates, automatic function calling and filters. - It remains maintained in 2026, but Microsoft Agent Framework is its official successor and receives new features.
- Vector store support now comes from Microsoft.Extensions.VectorData with
CommunityToolkit.VectorData.*connectors. - Filters provide consistent control over function calls, prompt rendering and tool loops.
- Keep stable Semantic Kernel apps running, adopt shared abstractions such as
IChatClient, and migrate to Agent Framework on your own schedule.
Further Reading#
- Semantic Kernel repository on GitHub
- Semantic Kernel and Microsoft Agent Framework (Agent Framework blog)
- Semantic Kernel to Agent Framework migration guide
- CommunityToolkit AI repository (vector data connectors)
- Microsoft Agent Framework: Build AI Agents in C#
- AI in .NET: The Complete Landscape for Developers