---
# 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
    /// <summary>
    /// Retrieves an existing server side agent, wrapped as a <see cref="ChatClientAgent"/> using the provided <see cref="PersistentAgentsClient"/>.
    /// </summary>
    /// <param name="persistentAgentsClient">The <see cref="PersistentAgentsClient"/> to create the <see cref="ChatClientAgent"/> with.</param>
    /// <returns>A <see cref="ChatClientAgent"/> for the persistent agent.</returns>
    /// <param name="agentId"> The ID of the server side agent to create a <see cref="ChatClientAgent"/> for.</param>
    /// <param name="chatOptions">Options that should apply to all runs of the agent.</param>
    /// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
    /// <returns>A <see cref="ChatClientAgent"/> instance that can be used to perform operations on the persistent agent.</returns>
    public static async Task<ChatClientAgent> GetAIAgentAsync(
        this PersistentAgentsClient persistentAgentsClient,
        string agentId,
        ChatOptions? chatOptions = null,
        CancellationToken cancellationToken = default)
    ```
- Create an `AIAgent`
    ```csharp
    /// <summary>
    /// Creates a new server side agent using the provided <see cref="PersistentAgentsClient"/>.
    /// </summary>
    /// <param name="persistentAgentsClient">The <see cref="PersistentAgentsClient"/> to create the agent with.</param>
    /// <param name="model">The model to be used by the agent.</param>
    /// <param name="name">The name of the agent.</param>
    /// <param name="description">The description of the agent.</param>
    /// <param name="instructions">The instructions for the agent.</param>
    /// <param name="tools">The tools to be used by the agent.</param>
    /// <param name="toolResources">The resources for the tools.</param>
    /// <param name="temperature">The temperature setting for the agent.</param>
    /// <param name="topP">The top-p setting for the agent.</param>
    /// <param name="responseFormat">The response format for the agent.</param>
    /// <param name="metadata">The metadata for the agent.</param>
    /// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
    /// <returns>A <see cref="ChatClientAgent"/> instance that can be used to perform operations on the newly created agent.</returns>
    public static async Task<ChatClientAgent> CreateAIAgentAsync(
        this PersistentAgentsClient persistentAgentsClient,
        string model,
        string? name = null,
        string? description = null,
        string? instructions = null,
        IEnumerable<ToolDefinition>? tools = null,
        ToolResources? toolResources = null,
        float? temperature = null,
        float? topP = null,
        BinaryData? responseFormat = null,
        IReadOnlyDictionary<string, string>? metadata = null,
        CancellationToken cancellationToken = default)
    ```
- Additional overload using the M.E.AI types:
    ```csharp
    /// <summary>
    /// Creates a new server side agent using the provided <see cref="PersistentAgentsClient"/>.
    /// </summary>
    /// <param name="persistentAgentsClient">The <see cref="PersistentAgentsClient"/> to create the agent with.</param>
    /// <param name="model">The model to be used by the agent.</param>
    /// <param name="name">The name of the agent.</param>
    /// <param name="description">The description of the agent.</param>
    /// <param name="instructions">The instructions for the agent.</param>
    /// <param name="tools">The tools to be used by the agent.</param>
    /// <param name="temperature">The temperature setting for the agent.</param>
    /// <param name="topP">The top-p setting for the agent.</param>
    /// <param name="responseFormat">The response format for the agent.</param>
    /// <param name="metadata">The metadata for the agent.</param>
    /// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
    /// <returns>A <see cref="ChatClientAgent"/> instance that can be used to perform operations on the newly created agent.</returns>
    public static async Task<ChatClientAgent> CreateAIAgentAsync(
        this PersistentAgentsClient persistentAgentsClient,
        string model,
        string? name = null,
        string? description = null,
        string? instructions = null,
        IEnumerable<AITool>? tools = null,
        float? temperature = null,
        float? topP = null,
        BinaryData? responseFormat = null,
        IReadOnlyDictionary<string, string>? 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);
```