--- # These are optional elements. Feel free to remove any of them. status: accepted contact: markwallace date: 2025-08-06 deciders: markwallace-microsoft, westey-m, quibitron consulted: shawnhenry, elijahstraight informed: --- # Agent Framework / Foundry SDK Alignment Agent Framework and Foundry SDK have overlapping functionality but serve different audiences & scenarios. This specification clarifies the positioning of these SDKs to customers, what goes in each and when to use what. - **Foundry SDK** is a thin-client SDK for accessing everything available in the agent service and is autogenerated from REST APIs in multiple languages - **Agent Framework SDK** is general-purpose framework for agentic application development, where common agent abstractions enable creating and orchestrating heterogenous agent systems (across local & cloud) ## What is the goal of this feature? Goals: - Developers can seamlessly combine Foundry and Agent Framework SDK's and there is no friction when using both SDKs at the same time - Developers can take advantage of the full capabilities supported by the Foundry SDK - Developers can create multi-agent orchestrations using Foundry and other agent types Success Metrics: - Complexity of basic samples is comparable to other agent frameworks - Developers can easily discover how to use Foundry Agents in Agent Framework multi-agent orchestrations ## What is the problem being solved? - In Semantic Kernel the Foundry Agent support isn't integrated into the Foundry SDK so there is a disjointed developer UX - Customers are confused as to when they should use Foundry SDK versus Semantic Kernel ## API Changes The proposed solution is to add helper methods which allow developers to either retrieve or create an `AIAgent` using a `PersistentAgentsClient` - Retrieve an `AIAgent` ```csharp /// /// Retrieves an existing server side agent, wrapped as a using the provided . /// /// The to create the with. /// A for the persistent agent. /// The ID of the server side agent to create a for. /// Options that should apply to all runs of the agent. /// The to monitor for cancellation requests. The default is . /// A instance that can be used to perform operations on the persistent agent. public static async Task GetAIAgentAsync( this PersistentAgentsClient persistentAgentsClient, string agentId, ChatOptions? chatOptions = null, CancellationToken cancellationToken = default) ``` - Create an `AIAgent` ```csharp /// /// Creates a new server side agent using the provided . /// /// The to create the agent with. /// The model to be used by the agent. /// The name of the agent. /// The description of the agent. /// The instructions for the agent. /// The tools to be used by the agent. /// The resources for the tools. /// The temperature setting for the agent. /// The top-p setting for the agent. /// The response format for the agent. /// The metadata for the agent. /// The to monitor for cancellation requests. The default is . /// A instance that can be used to perform operations on the newly created agent. public static async Task CreateAIAgentAsync( this PersistentAgentsClient persistentAgentsClient, string model, string? name = null, string? description = null, string? instructions = null, IEnumerable? tools = null, ToolResources? toolResources = null, float? temperature = null, float? topP = null, BinaryData? responseFormat = null, IReadOnlyDictionary? metadata = null, CancellationToken cancellationToken = default) ``` - Additional overload using the M.E.AI types: ```csharp /// /// Creates a new server side agent using the provided . /// /// The to create the agent with. /// The model to be used by the agent. /// The name of the agent. /// The description of the agent. /// The instructions for the agent. /// The tools to be used by the agent. /// The temperature setting for the agent. /// The top-p setting for the agent. /// The response format for the agent. /// The metadata for the agent. /// The to monitor for cancellation requests. The default is . /// A instance that can be used to perform operations on the newly created agent. public static async Task CreateAIAgentAsync( this PersistentAgentsClient persistentAgentsClient, string model, string? name = null, string? description = null, string? instructions = null, IEnumerable? tools = null, float? temperature = null, float? topP = null, BinaryData? responseFormat = null, IReadOnlyDictionary? metadata = null, CancellationToken cancellationToken = default) ``` ## E2E Code Samples ### 1. Create and retrieve with Foundry SDK, run with Agent Framework - [Foundry SDK] Create a `PersistentAgentsClient` - [Foundry SDK] Create a `PersistentAgent` using the `PersistentAgentsClient` - [Foundry SDK] Retrieve an `AIAgent` using the `PersistentAgentsClient` - [Agent Framework SDK] Invoke the `AIAgent` instance and access response from the `AgentResponse` - [Foundry SDK] Clean up the agent ```csharp // Get a client to create server side agents with. var persistentAgentsClient = new PersistentAgentsClient( TestConfiguration.AzureAI.Endpoint, new AzureCliCredential()); // Create a persistent agent. var persistentAgentMetadata = await persistentAgentsClient.Administration.CreateAgentAsync( model: TestConfiguration.AzureAI.DeploymentName!, name: JokerName, instructions: JokerInstructions); // Get the persistent agent we created in the previous step and expose it as an Agent Framework agent. AIAgent agent = await persistentAgentsClient.GetAIAgentAsync(persistentAgent.Value.Id); // Respond to user input. var input = "Tell me a joke about a pirate."; Console.WriteLine(input); Console.WriteLine(await agent.RunAsync(input)); // Delete the persistent agent. await persistentAgentsClient.Administration.DeleteAgentAsync(agent.Id); ``` ### 2. Create directly with Foundry SDK, run with Agent Framework - [Foundry SDK] Create a `PersistentAgentsClient` - [Foundry SDK] Create a `AIAgent` using the `PersistentAgentsClient` - [Agent Framework SDK] Invoke the `AIAgent` instance and access response from the `AgentResponse` - [Foundry SDK] Clean up the agent ```csharp // Get a client to create server side agents with. var persistentAgentsClient = new PersistentAgentsClient( TestConfiguration.AzureAI.Endpoint, new AzureCliCredential()); // Create a persistent agent and expose it as an Agent Framework agent. AIAgent agent = await persistentAgentsClient.CreateAIAgentAsync( model: TestConfiguration.AzureAI.DeploymentName!, name: JokerName, instructions: JokerInstructions); // Respond to user input. var input = "Tell me a joke about a pirate."; Console.WriteLine(input); Console.WriteLine(await agent.RunAsync(input)); // Delete the persistent agent. await persistentAgentsClient.Administration.DeleteAgentAsync(agent.Id); ``` ### 3. Create directly with Foundry SDK, run with conversation state using Agent Framework - [Foundry SDK] Create a `PersistentAgentsClient` - [Foundry SDK] Create a `AIAgent` using the `PersistentAgentsClient` - [Agent Framework SDK] Optionally create an `AgentThread` for the agent run - [Agent Framework SDK] Invoke the `AIAgent` instance and access response from the `AgentResponse` - [Foundry SDK] Clean up the agent and the agent thread ```csharp // Get a client to create server side agents with. var persistentAgentsClient = new PersistentAgentsClient( TestConfiguration.AzureAI.Endpoint, new AzureCliCredential()); // Create an Agent Framework agent. AIAgent agent = await persistentAgentsClient.CreateAIAgentAsync( model: TestConfiguration.AzureAI.DeploymentName!, name: JokerName, instructions: JokerInstructions); // Start a new thread for the agent conversation. AgentThread thread = agent.GetNewThread(); // Respond to user input. await RunAgentAsync("Tell me a joke about a pirate."); await RunAgentAsync("Now add some emojis to the joke."); // Local function to run agent and display the conversation messages for the thread. async Task RunAgentAsync(string input) { Console.WriteLine( $""" User: {input} Assistant: {await agent.RunAsync(input, thread)} """); } // Cleanup await persistentAgentsClient.Threads.DeleteThreadAsync(thread.ConversationId); await persistentAgentsClient.Administration.DeleteAgentAsync(agent.Id); ``` ### 4. Create directly with Foundry SDK, orchestrate with Agent Framework - [Foundry SDK] Create a `PersistentAgentsClient` - [Foundry SDK] Create multiple `AIAgent` instances using the `PersistentAgentsClient` - [Agent Framework SDK] Create a `SequentialOrchestration` and add all of the agents to it - [Agent Framework SDK] Invoke the `SequentialOrchestration` instance and access response from the `AgentResponse` - [Foundry SDK] Clean up the agents ```csharp // Get a client to create server side agents with. var persistentAgentsClient = new PersistentAgentsClient( TestConfiguration.AzureAI.Endpoint, new AzureCliCredential()); var model = TestConfiguration.OpenAI.ChatModelId; // Define the agents AIAgent analystAgent = await persistentAgentsClient.CreateAIAgentAsync( model, name: "Analyst", instructions: """ You are a marketing analyst. Given a product description, identify: - Key features - Target audience - Unique selling points """, description: "An agent that extracts key concepts from a product description."); AIAgent writerAgent = await persistentAgentsClient.CreateAIAgentAsync( model, name: "copywriter", instructions: """ You are a marketing copywriter. Given a block of text describing features, audience, and USPs, compose a compelling marketing copy (like a newsletter section) that highlights these points. Output should be short (around 150 words), output just the copy as a single text block. """, description: "An agent that writes a marketing copy based on the extracted concepts."); AIAgent editorAgent = await persistentAgentsClient.CreateAIAgentAsync( model, name: "editor", instructions: """ You are an editor. Given the draft copy, correct grammar, improve clarity, ensure consistent tone, give format and make it polished. Output the final improved copy as a single text block. """, description: "An agent that formats and proofreads the marketing copy."); // Define the orchestration SequentialOrchestration orchestration = new(analystAgent, writerAgent, editorAgent) { LoggerFactory = this.LoggerFactory, }; // Run the orchestration string input = "An eco-friendly stainless steel water bottle that keeps drinks cold for 24 hours"; Console.WriteLine($"\n# INPUT: {input}\n"); AgentResponse result = await orchestration.RunAsync(input); Console.WriteLine($"\n# RESULT: {result}"); // Cleanup await persistentAgentsClient.Administration.DeleteAgentAsync(analystAgent.Id); await persistentAgentsClient.Administration.DeleteAgentAsync(writerAgent.Id); await persistentAgentsClient.Administration.DeleteAgentAsync(editorAgent.Id); ```