# Semantic Kernel to Agent Framework Migration Guide ## What's Changed? - **Namespace Updates**: From `Microsoft.SemanticKernel.Agents` to `Microsoft.Agents.AI` - **Agent Creation**: Single fluent API calls vs multi-step builder patterns - **Thread Management**: Built-in thread management vs manual thread creation - **Tool Registration**: Direct function registration vs plugin wrapper systems - **Dependency Injection**: Simplified service registration patterns - **Invocation Patterns**: Streamlined options and result handling ## Benefits of Migration - **Simplified API**: Reduced complexity and boilerplate code - **Better Performance**: Optimized object creation and memory usage - **Unified Interface**: Consistent patterns across different AI providers - **Enhanced Developer Experience**: More intuitive and discoverable APIs ## Key Changes ### 1. Namespace Updates #### Semantic Kernel ```csharp using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.Agents; ``` #### Agent Framework Agent Framework namespaces are under `Microsoft.Agents.AI`. Agent Framework uses the core AI message and content types from `Microsoft.Extensions.AI` for communication between components. ```csharp using Microsoft.Extensions.AI; using Microsoft.Agents.AI; ``` ### 2. Agent Creation Simplification #### Semantic Kernel Every agent in Semantic Kernel depends on a `Kernel` instance and will have an empty `Kernel` if not provided. ```csharp Kernel kernel = Kernel .AddOpenAIChatClient(modelId, apiKey) .Build(); ChatCompletionAgent agent = new() { Instructions = ParrotInstructions, Kernel = kernel }; ``` Azure AI Foundry requires an agent resource to be created in the cloud before creating a local agent class that uses it. ```csharp PersistentAgentsClient azureAgentClient = AzureAIAgent.CreateAgentsClient(azureEndpoint, new AzureCliCredential()); PersistentAgent definition = await azureAgentClient.Administration.CreateAgentAsync( deploymentName, instructions: ParrotInstructions); AzureAIAgent agent = new(definition, azureAgentClient); ``` #### Agent Framework Agent creation in Agent Framework is made simpler with extensions provided by all main providers. ```csharp AIAgent openAIAgent = chatClient.CreateAIAgent(instructions: ParrotInstructions); AIAgent azureFoundryAgent = await persistentAgentsClient.CreateAIAgentAsync(instructions: ParrotInstructions); AIAgent openAIAssistantAgent = await assistantClient.CreateAIAgentAsync(instructions: ParrotInstructions); ``` Additionally for hosted agent providers you can also use the `GetAIAgent` to retrieve an agent from an existing hosted agent. ```csharp AIAgent azureFoundryAgent = await persistentAgentsClient.GetAIAgentAsync(agentId); ``` ### 3. Agent Thread Creation #### Semantic Kernel The caller has to know the thread type and create it manually. ```csharp // Create a thread for the agent conversation. AgentThread thread = new OpenAIAssistantAgentThread(this.AssistantClient); AgentThread thread = new AzureAIAgentThread(this.Client); AgentThread thread = new OpenAIResponseAgentThread(this.Client); ``` #### Agent Framework The agent is responsible for creating the thread. ```csharp // New AgentThread thread = agent.GetNewThread(); ``` ### 4. Hosted Agent Thread Cleanup This case applies exclusively to a few AI providers that still provide hosted threads. #### Semantic Kernel Threads have a `self` deletion method i.e: OpenAI Assistants Provider ```csharp await thread.DeleteAsync(); ``` #### Agent Framework > [!NOTE] > OpenAI Responses introduced a new conversation model that simplifies how conversations are handled. This simplifies hosted thread management compared to the now deprecated OpenAI Assistants model. For more information see the [OpenAI Assistants migration guide](https://platform.openai.com/docs/assistants/migration). Agent Framework doesn't have a thread deletion API in the `AgentThread` type as not all providers support hosted threads or thread deletion and this will become more common as more providers shift to responses based architectures. If you require thread deletion and the provider allows this, the caller **should** keep track of the created threads and delete them later when necessary via the provider's sdk. i.e: OpenAI Assistants Provider ```csharp await assistantClient.DeleteThreadAsync(thread.ConversationId); ``` ### 5. Tool Registration #### Semantic Kernel In semantic kernel to expose a function as a tool you must: 1. Decorate the function with a `[KernelFunction]` attribute. 2. Have a `Plugin` class or use the `KernelPluginFactory` to wrap the function. 3. Have a `Kernel` to add your plugin to. 4. Pass the `Kernel` to the agent. ```csharp KernelFunction function = KernelFunctionFactory.CreateFromMethod(GetWeather); KernelPlugin plugin = KernelPluginFactory.CreateFromFunctions("KernelPluginName", [function]); Kernel kernel = ... // Create kernel kernel.Plugins.Add(plugin); ChatCompletionAgent agent = new() { Kernel = kernel, ... }; ``` #### Agent Framework In agent framework in a single call you can register tools directly in the agent creation process. ```csharp AIAgent agent = chatClient.CreateAIAgent(tools: [AIFunctionFactory.Create(GetWeather)]); ``` ### 6. Agent Non-Streaming Invocation Key differences can be seen in the method names from `Invoke` to `Run`, return types and parameters `AgentRunOptions`. #### Semantic Kernel The Non-Streaming uses a streaming pattern `IAsyncEnumerable>` for returning multiple agent messages. ```csharp await foreach (AgentResponseItem result in agent.InvokeAsync(userInput, thread, agentOptions)) { Console.WriteLine(result.Message); } ``` #### Agent Framework The Non-Streaming returns a single `AgentRunResponse` with the agent response that can contain multiple messages. The text result of the run is available in `AgentRunResponse.Text` or `AgentRunResponse.ToString()`. All messages created as part of the response is returned in the `AgentRunResponse.Messages` list. This may include tool call messages, function results, reasoning updates and final results. ```csharp AgentRunResponse agentResponse = await agent.RunAsync(userInput, thread); ``` ### 7. Agent Streaming Invocation Key differences in the method names from `Invoke` to `Run`, return types and parameters `AgentRunOptions`. #### Semantic Kernel ```csharp await foreach (StreamingChatMessageContent update in agent.InvokeStreamingAsync(userInput, thread)) { Console.Write(update); } ``` #### Agent Framework Similar streaming API pattern with the key difference being that it returns `AgentRunResponseUpdate` objects including more agent related information per update. All updates produced by any service underlying the AIAgent is returned. The textual result of the agent is available by concatenating the `AgentRunResponse.Text` values. ```csharp await foreach (AgentRunResponseUpdate update in agent.RunStreamingAsync(userInput, thread)) { Console.Write(update); // Update is ToString() friendly } ``` ### 8. Tool Function Signatures **Problem**: SK plugin methods need `[KernelFunction]` attributes ```csharp public class MenuPlugin { [KernelFunction] // Required for SK public static MenuItem[] GetMenu() => ...; } ``` **Solution**: AF can use methods directly without attributes ```csharp public class MenuTools { [Description("Get menu items")] // Optional description public static MenuItem[] GetMenu() => ...; } ``` ### 9. Options Configuration **Problem**: Complex options setup in SK ```csharp OpenAIPromptExecutionSettings settings = new() { MaxTokens = 1000 }; AgentInvokeOptions options = new() { KernelArguments = new(settings) }; ``` **Solution**: Simplified options in AF ```csharp ChatClientAgentRunOptions options = new(new() { MaxOutputTokens = 1000 }); ``` > [!IMPORTANT] > This example shows passing implementation specific options to a `ChatClientAgent`. Not all `AIAgents` support `ChatClientAgentRunOptions`. > `ChatClientAgent` is provided to build agents based on underlying inference services, and therefore supports inference options like `MaxOutputTokens`. ### 10. Dependency Injection #### Semantic Kernel A `Kernel` registration is required in the service container to be able to create an agent as every agent abstractions needs to be initialized with a `Kernel` property. Semantic Kernel uses the `Agent` type as the base abstraction class for agents. ```csharp services.AddKernel().AddProvider(...); serviceContainer.AddKeyedSingleton( TutorName, (sp, key) => new ChatCompletionAgent() { // Passing the kernel is required Kernel = sp.GetRequiredService(), }); ``` ### 11. **Agent Type Consolidation** #### Semantic Kernel Semantic kernel provides specific agent classes for various services, e.g. - `ChatCompletionAgent` for use with chat-completion-based inference services. - `OpenAIAssistantAgent` for use with the OpenAI Assistants service. - `AzureAIAgent` for use with the Azure AI Foundry Agents service. #### Agent Framework The agent framework supports all the abovementioned services via a single agent type, `ChatClientAgent`. `ChatClientAgent` can be used to build agents using any underlying service that provides an SDK implementing the `Microsoft.Extensions.AI.IChatClient` interface. #### Agent Framework The Agent framework provides the `AIAgent` type as the base abstraction class. ```csharp services.AddKeyedSingleton(() => client.CreateAIAgent(...)); ``` ## Migration Samples This folder contains **separate console application projects** demonstrating how to transition from **Semantic Kernel (SK)** to the new **Agent Framework (AF)**. Each project shows side-by-side comparisons of equivalent functionality in both frameworks and can be run independently. Each sample code contains the following: 1. **SK Agent** (Semantic Kernel before) 2. **AF Agent** (Agent Framework after) ### Running the samples from Visual Studio Open the solution in Visual Studio and set the desired sample project as the startup project. Then, run the project using the built-in debugger or by pressing `F5`. You will be prompted for any required environment variables if they are not already set. ### Prerequisites Before you begin, ensure you have the following: - [.NET 10.0 SDK or later](https://dotnet.microsoft.com/download) - For Azure AI Foundry samples: Azure OpenAI service endpoint and deployment configured - For OpenAI samples: OpenAI API key - For OpenAI Assistants samples: OpenAI API key with Assistant API access ### Environment Variables Set the appropriate environment variables based on the sample type you want to run: **For Azure AI Foundry projects:** ```powershell $env:AZURE_FOUNDRY_PROJECT_ENDPOINT = "https://-resource.services.ai.azure.com/api/projects/" ``` **For OpenAI and OpenAI Assistants projects:** ```powershell $env:OPENAI_API_KEY = "sk-..." ``` **For Azure OpenAI and Azure OpenAI Assistants projects:** ```powershell $env:AZURE_OPENAI_ENDPOINT = "https://.cognitiveservices.azure.com/" $env:AZURE_OPENAI_DEPLOYMENT_NAME = "gpt-4o" # Optional, defaults to gpt-4o ``` **Optional debug mode:** ```powershell $env:AF_SHOW_ALL_DEMO_SETTING_VALUES = "Y" ``` If environment variables are not set, the demos will prompt you to enter values interactively. ### Samples The migration samples are organized into different categories, each demonstrating different AI service integrations and orchestration patterns: |Category|Description| |---|---| |[AzureAIFoundry](./AzureAIFoundry/)|Azure OpenAI service integration samples| |[AzureOpenAI](./AzureOpenAI/)|Direct Azure OpenAI API integration samples| |[AzureOpenAIAssistants](./AzureOpenAIAssistants/)|Azure OpenAI Assistants API integration samples| |[AzureOpenAIResponses](./AzureOpenAIResponses/)|Azure OpenAI Responses API integration samples| |[OpenAI](./OpenAI/)|Direct OpenAI API integration samples| |[OpenAIAssistants](./OpenAIAssistants/)|OpenAI Assistants API integration samples| |[OpenAIResponses](./OpenAIResponses/)|OpenAI Responses API integration samples| |[AgentOrchestrations](./AgentOrchestrations/)|Agent orchestration patterns including concurrent, sequential, and handoff workflows| ## Running the samples from the console To run any migration sample, navigate to the desired sample directory: ```powershell # Azure AI Foundry Examples cd "AzureAIFoundry\Step01_Basics" dotnet run # Azure OpenAI Examples cd "AzureOpenAI\Step01_Basics" dotnet run # Azure OpenAI Assistants Examples cd "AzureOpenAIAssistants\Step01_Basics" dotnet run # Azure OpenAI Responses Examples cd "AzureOpenAIResponses\Step01_Basics" dotnet run # OpenAI Examples cd "OpenAI\Step01_Basics" dotnet run # OpenAI Assistants Examples cd "OpenAIAssistants\Step01_Basics" dotnet run # OpenAI Responses Examples cd "OpenAIResponses\Step01_Basics" dotnet run # Agent Orchestrations Examples cd "AgentOrchestrations\Step01_Concurrent" dotnet run cd "AgentOrchestrations\Step02_Sequential" dotnet run cd "AgentOrchestrations\Step03_Handoff" dotnet run ```