Files
agent-framework/docs/specs/001-foundry-sdk-alignment.md
Ren Finlayson 539852f81c
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
dotnet-build-and-test / paths-filter (push) Waiting to run
dotnet-build-and-test / dotnet-build-and-test (Debug, windows-latest, net9.0) (push) Blocked by required conditions
dotnet-build-and-test / dotnet-build-and-test (Release, integration, true, ubuntu-latest, net10.0) (push) Blocked by required conditions
dotnet-build-and-test / dotnet-build-and-test (Release, integration, true, windows-latest, net472) (push) Blocked by required conditions
dotnet-build-and-test / dotnet-build-and-test (Release, ubuntu-latest, net8.0) (push) Blocked by required conditions
dotnet-build-and-test / dotnet-build-and-test-check (push) Blocked by required conditions
test
2026-01-24 03:05:12 +11:00

13 KiB

status, contact, date, deciders, consulted, informed
status contact date deciders consulted informed
accepted markwallace 2025-08-06 markwallace-microsoft, westey-m, quibitron shawnhenry, elijahstraight

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
    /// <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
    /// <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:
    /// <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
// 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
// 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
// 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
// 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);