We use cookies to enhance your experience on the site
CodeWorlds
Back to collections
Guide11 min read

Semantic Kernel, a library that gained a successor

Semantic Kernel has a successor: Microsoft Agent Framework 1.0. What that means for existing projects, how migration looks, and when to stay put.

Semantic Kernel, a library that gained a successor

Semantic Kernel began as Microsoft's answer to how you wire language models into applications in the .NET ecosystem without abandoning what enterprise software demands: dependency injection, telemetry, typing, and middleware.

In April 2026 Microsoft released Agent Framework version 1.0 and named it the successor, merging the work of two of its own projects. Semantic Kernel still ships releases and has a large community, but the direction is clear and a new project must account for it.

This text covers both: what the older library offers, what the successor changes, and when migration makes sense.

The conceptual model

The base is a kernel, meaning a container joining models, plugins, and supporting services. It resembles the dependency injection container familiar from this ecosystem, and that is no accident.

Code
C#
var builder = Kernel.CreateBuilder();
builder.AddAzureOpenAIChatCompletion(deployment, endpoint, apiKey);
builder.Plugins.AddFromType<OrdersPlugin>();

var kernel = builder.Build();

A plugin is a class with attribute marked methods a model can call. The method and parameter descriptions come from attributes, so the schema derives from code rather than from a separate file.

Code
C#
public class OrdersPlugin
{
    [KernelFunction, Description("Returns the status of the order with the given number.")]
    public async Task<string> GetStatus(
        [Description("order number")] string number)
        => await _db.StatusAsync(number);
}

The attribute description is not a comment for a developer but text the model reads. A sentence saying when to call the method improves accuracy more than any change to the system instruction, and it is the cheapest optimisation this library offers.

What the successor changes

The new framework simplifies what the older library required ceremony for, while keeping what enterprise software needs.

The largest change concerns tools. Rather than a plugin class with attributes you can pass an ordinary method, and the schema derives from its signature. Across three tools that is the difference between one line and a separate file.

The second change simplifies the conceptual model. A kernel as a separate container stops being mandatory, since an agent is created directly and dependencies are injected through the ecosystem's standard mechanism.

The third merges the work of two projects. Previously Microsoft developed a library for wiring in models alongside a separate project for multi agent conversations, forcing a choice or a combination. Now it is one thing.

The fourth is long term support. A release marked production ready with a commitment to interface stability is an argument in itself in this ecosystem, since enterprise applications live for years.

Migration

The move is not an application rewrite and it is not a dependency swap either.

Code calling the model ports over easily, since the concepts are close: an agent with instructions, a conversation thread, tools. Plugin code needs changing, though in the direction of simplification, since an attributed class becomes ordinary methods.

What needs most attention is whatever was built around the kernel: custom services registered in the container, filters intercepting calls, and configuration passed through the container. Those need thinking through in the new arrangement.

The practical order runs like this. First port one agent to the new framework and run it beside the existing one, since both libraries can live in the same application. Then port the rest, checking behaviour against the same case set. Finally remove the old dependency.

Microsoft publishes a migration guide mapping the concepts, so start there rather than guessing.

When to stay put

Not every project must migrate, and that deserves saying plainly.

An application running stably with a closed scope of changes gains nothing but work. The older library still ships releases and will not vanish overnight, so deferring the decision another year is defensible.

Migration makes sense when you plan expansion, when the ceremony around plugins chafes, or when you need something available only in the new framework. It also makes sense on a project starting now, since writing new code on a library with a named successor is debt taken on knowingly.

The third factor is the team. If nobody knows either library, the successor is the obvious choice. If the team knows the older one and has working deployments on it, weigh the learning cost.

Set a date to revisit the decision rather than deferring it indefinitely. A calendar entry six months out, at which you check the state of both libraries, costs nothing and guards against the case where migration only becomes urgent once a dependency stops working.

Tool calling in practice

Whichever library you pick, the same rules apply, since they follow from how a model works rather than from a particular solution.

A tool's description drives accuracy more than anything else. The model sees only the name, description, and parameter schema, so a sentence stating plainly when to call the tool matters more than a description of the implementation.

Tool count matters. A model choosing among four errs less often than one choosing among twenty, so splitting into several specialised agents often beats one holding the full set.

Enforce permissions in tool code rather than in instructions. The user identifier should come from call context rather than from a parameter the model may fill freely. That is the same principle as with the OpenAI Agents SDK and every other agent library.

Limits are mandatory. An agent without a step cap can call the same tool in a loop, and without a timeout can hang on a call that never returns.

Middleware and telemetry

This is where libraries from this ecosystem beat the alternatives, since they answer needs enterprise software raises from day one.

Middleware lets you intercept a model or tool call and do something with it: record, measure, reject, retry. It is the same pattern as a server request pipeline, so a team knows it without learning.

Code
C#
public class CostLimitMiddleware : IFunctionInvocationFilter
{
    public async Task OnFunctionInvocationAsync(
        FunctionInvocationContext context, Func<FunctionInvocationContext, Task> next)
    {
        if (_counter.DailyExceeded())
            throw new InvalidOperationException("Daily limit exceeded");

        await next(context);
        _counter.Add(context.Result.Metadata?["Usage"]);
    }
}

Three uses recur most. The first is cost limits, so a looping bug does not drain the budget. The second is approving irreversible actions, where the layer pauses the call and asks for consent. The third is recording to an observability system.

Telemetry here rests on the standard used across this ecosystem, so model call traces land where you already collect data about the rest of the application. That beats a separate tool, since diagnosing a slow request needs no cross referencing between two systems.

Enable telemetry from day one. Token usage, call duration, and retry count are three numbers whose absence is noticed only at the first surprising invoice.

Cloud deployment

Deploying on Microsoft's platform brings a few things that simplify the work and deserve knowing before you configure everything your own way.

A managed identity removes keys from configuration entirely. The application authenticates with the identity the platform assigns it, so there is nothing to keep in a file and nothing to rotate.

Code
C#
builder.AddAzureOpenAIChatCompletion(
    deploymentName: deployment,
    endpoint: endpoint,
    credentials: new DefaultAzureCredential());

The second thing is content filtering enabled by default on the service side. It sometimes helps and sometimes hinders, when your domain contains vocabulary judged sensitive. Check how it behaves on your data before declaring readiness.

The third is throughput limits tied to a model deployment. Exceeding them returns an error rather than queuing, so retries with growing delay are mandatory here rather than advisable.

A separate decision is whether the agent should run inside your process at all. Foundry Agent Service runs it on the vendor's side and offers two routes: an agent defined by configuration alone, with no code to maintain, or your own container image, to which the platform adds an endpoint, scaling, identity, and trace collection. The first route lifts maintenance off you but removes the option of plugging in the middleware described above, so anything beyond trivial run control leaves the container variant.

Against the alternatives

OptionStrengthWeaknessPick it when
Agent FrameworkSupported successor, simpler tools, .NET ecosystemYounger, less materialNew .NET project
Semantic KernelMaturity, large community, many examplesA named successor existsExisting deployment with no expansion plans
LangChainLargest integration setMainly Python and TypeScriptProject outside the .NET ecosystem
PydanticAITyped output, tests without a modelPython onlyResult feeding straight into code

For a team working in .NET the choice comes down to the first two rows, since the alternatives would mean a separate service in another language. That is sometimes justified with a back end already split into services, and on a monolith it adds a boundary that was not there.

Note that these libraries solve the same problem similarly, since all rest on the tool calling model vendors expose. The differences concern convenience and ecosystem rather than capability.

The practical conclusion is that the library choice rarely decides whether a deployment succeeds. What decides it is tool descriptions, the boundaries in the instruction, and whether you hold a case set to measure changes against. Those three carry across libraries almost unchanged, so the work put into them does not perish in a migration.

The second conclusion concerns the order of work. Start with one task and three tools, and bring it to a state where it behaves predictably before building a system with five agents. Expanding on unproven foundations multiplies problems whose source cannot later be identified.

Search over your own data

The commonest corporate use of these libraries is answering questions from internal documentation rather than building agents that act.

The library exposes a vector store abstraction, so the code does not depend on a particular database. That helps when prototyping on a built in option and moving to something more serious later.

Code
C#
var collection = store.GetCollection<string, Fragment>("documentation");
var results = collection.SearchAsync(questionVector, top: 5);

Note, though, that the abstraction simplifies choosing a database rather than the task itself. Answer quality depends on document splitting, embedding model choice, and filtering, meaning things no intermediate layer settles.

When working with documents outside English, embedding model choice matters more than database choice. A model trained mainly on English data returns worse matched fragments, and diagnosing that is misleading, since it looks like a retrieval fault.

At larger scale, reach for a specialised database, Qdrant for instance, and measure accuracy with a dedicated tool rather than judging it from an impression across a few questions.

Common mistakes

The first is tool descriptions written for a developer. The model reads the same text and needs a sentence about when to call the method, not a description of the implementation.

The second is passing a user identifier in tool parameters. The model can supply somebody else's, so identity should come from call context.

The third is no step cap. An agent in a loop burns as many tokens as you allow, and on a top tier model that is an expensive discovery.

The fourth is starting a new project on a library with a named successor. It works and it means a migration scheduled for later rather than a decision made now.

The fifth is having no test case set before migrating. Without one you cannot tell whether behaviour after the move matches, and the differences are sometimes subtle.

The sixth is keeping keys in application configuration. In this ecosystem the right place is a secret store, and for cloud deployments a managed identity, which removes keys entirely.

FAQ

Is Semantic Kernel obsolete?

Not withdrawn, but Microsoft named a successor and that is where the main development effort goes. The older library still ships releases and has a large community, so existing deployments keep working, while a new project is better started on the successor.

How does Agent Framework differ from Semantic Kernel?

It simplifies tool definitions, since an ordinary method suffices in place of an attributed plugin class. It also merges the work of two Microsoft projects previously developed separately and shipped as a production release with a commitment to interface stability.

How long does migration take?

It depends how much logic was built around the kernel. Model calling code and tool definitions port quickly, while custom services in the container and call intercepting filters take time. Both libraries can run side by side, so it can be staged.

Does it work with models other than Microsoft's?

Yes, models from various vendors are supported, Claude and local models through a popular format compatible interface included. Integration with Microsoft's cloud services runs deepest, which for deployments in that ecosystem is sometimes decisive.

Does it suit multi agent systems?

Yes, and that is one reason the two projects merged. Integrations also exist with protocols for exchange between agents built on different platforms, which matters on larger deployments where not everything comes from one team.

The successor's documentation sits in Microsoft's learning centre, and the migration guide in a separate article.