Dela via


Migreringsguide för semantisk kernel till agentramverk

Fördelar med Microsoft Agent Framework

  • Förenklat API: Minskad komplexitet och standardkod.
  • Bättre prestanda: Optimerad objektgenerering och minnesanvändning.
  • Enhetligt gränssnitt: Konsekventa mönster mellan olika AI-leverantörer.
  • Förbättrad utvecklarupplevelse: Mer intuitiva och upptäckbara API:er.

I följande avsnitt sammanfattas de viktigaste skillnaderna mellan Semantic Kernel Agent Framework och Microsoft Agent Framework som hjälper dig att migrera din kod.

1. Namnområdesuppdateringar

Semantisk Kärna

using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;

Agentramverk

Agent Framework-namnområden finns under Microsoft.Agents.AI. Agent Framework använder de viktigaste AI-meddelande- och innehållstyperna från Microsoft.Extensions.AI för kommunikation mellan komponenter.

using Microsoft.Extensions.AI;
using Microsoft.Agents.AI;

2. Förenkla skapande av agent

Semantisk Kärna

Varje agent i semantisk kernel är beroende av en Kernel instans och har en tom Kernel om den inte tillhandahålls.

 Kernel kernel = Kernel
    .AddOpenAIChatClient(modelId, apiKey)
    .Build();

 ChatCompletionAgent agent = new() { Instructions = ParrotInstructions, Kernel = kernel };

Azure AI Foundry kräver att en agentresurs skapas i molnet innan du skapar en lokal agentklass som använder den.

PersistentAgentsClient azureAgentClient = AzureAIAgent.CreateAgentsClient(azureEndpoint, new AzureCliCredential());

PersistentAgent definition = await azureAgentClient.Administration.CreateAgentAsync(
    deploymentName,
    instructions: ParrotInstructions);

AzureAIAgent agent = new(definition, azureAgentClient);

Agentramverk

Agentskapande i Agent Framework blir enklare med tillägg som tillhandahålls av alla huvudprovidrar.

AIAgent openAIAgent = chatClient.CreateAIAgent(instructions: ParrotInstructions);
AIAgent azureFoundryAgent = await persistentAgentsClient.CreateAIAgentAsync(instructions: ParrotInstructions);
AIAgent openAIAssistantAgent = await assistantClient.CreateAIAgentAsync(instructions: ParrotInstructions);

För värdbaserade agentprovidrar kan du också använda GetAIAgent metoden för att hämta en agent från en befintlig värdbaserad agent.

AIAgent azureFoundryAgent = await persistentAgentsClient.GetAIAgentAsync(agentId);

3. Skapa agenttråd

Semantisk Kärna

Anroparen måste känna till trådtypen och skapa den manuellt.

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

Agentramverk

Agenten ansvarar för att skapa tråden.

// New.
AgentThread thread = agent.GetNewThread();

4. Rensning av värdbaserad agenttråd

Det här fallet gäller endast för några AI-leverantörer som fortfarande tillhandahåller värdbaserade trådar.

Semantisk Kärna

Trådar har en self borttagningsmetod.

OpenAI Assistants Provider:

await thread.DeleteAsync();

Agentramverk

Anmärkning

OpenAI-svar introducerade en ny konversationsmodell som förenklar hur konversationer hanteras. Den här ändringen förenklar hantering av värdbaserade trådar jämfört med den nu inaktuella OpenAI Assistants-modellen. Mer information finns i migreringsguiden för OpenAI Assistants.

Agent Framework har inget API för trådborttagning i AgentThread typen eftersom inte alla leverantörer stöder värdbaserade trådar eller trådborttagning. Den här designen blir vanligare när fler leverantörer övergår till svarsbaserade arkitekturer.

Om du behöver trådborttagning och providern tillåter det bör anroparen hålla reda på de skapade trådarna och ta bort dem senare vid behov via providerns SDK.

OpenAI Assistants Provider:

await assistantClient.DeleteThreadAsync(thread.ConversationId);

5. Verktygsregistrering

Semantisk Kärna

Om du vill exponera en funktion som ett verktyg måste du:

  1. Dekorera funktionen med ett [KernelFunction] attribut.
  2. Ha en Plugin klass eller använd KernelPluginFactory för att omsluta funktionen.
  3. Ha en Kernel att lägga till plugin-programmet i.
  4. Kernel Skicka till agenten.
KernelFunction function = KernelFunctionFactory.CreateFromMethod(GetWeather);
KernelPlugin plugin = KernelPluginFactory.CreateFromFunctions("KernelPluginName", [function]);
Kernel kernel = ... // Create kernel
kernel.Plugins.Add(plugin);

ChatCompletionAgent agent = new() { Kernel = kernel, ... };

Agentramverk

I Agent Framework kan du i ett enda anrop registrera verktyg direkt i processen för att skapa agenten.

AIAgent agent = chatClient.CreateAIAgent(tools: [AIFunctionFactory.Create(GetWeather)]);

6. Anrop utan direktuppspelning

Viktiga skillnader kan ses i metodnamnen från Invoke till Run, returtyper och parametrar AgentRunOptions.

Semantisk Kärna

Icke-direktuppspelning använder ett strömningsmönster IAsyncEnumerable<AgentResponseItem<ChatMessageContent>> för att returnera flera agentmeddelanden.

await foreach (AgentResponseItem<ChatMessageContent> result in agent.InvokeAsync(userInput, thread, agentOptions))
{
    Console.WriteLine(result.Message);
}

Agentramverk

Icke-direktuppspelning returnerar en enda AgentRunResponse med agentsvaret som kan innehålla flera meddelanden. Textresultatet för körningen är tillgängligt i AgentRunResponse.Text eller AgentRunResponse.ToString(). Alla meddelanden som skapas som en del av svaret returneras i AgentRunResponse.Messages listan. Detta kan omfatta verktygsanropsmeddelanden, funktionsresultat, resonemangsuppdateringar och slutliga resultat.

AgentRunResponse agentResponse = await agent.RunAsync(userInput, thread);

7. Anrop till agentströmning

De viktigaste skillnaderna finns i metodnamnen från Invoke till Run, returtyper och parametrar AgentRunOptions.

Semantisk Kärna

await foreach (StreamingChatMessageContent update in agent.InvokeStreamingAsync(userInput, thread))
{
    Console.Write(update);
}

Agentramverk

Agent Framework har ett liknande API-mönster för direktuppspelning, där den viktigaste skillnaden är att det returnerar AgentRunResponseUpdate objekt som innehåller mer agentrelaterad information per uppdatering.

Alla uppdateringar som produceras av alla tjänster som ligger bakom AIAgent returneras. Agentens textresultat är tillgängligt genom att AgentRunResponse.Text sammanfoga värdena.

await foreach (AgentRunResponseUpdate update in agent.RunStreamingAsync(userInput, thread))
{
    Console.Write(update); // Update is ToString() friendly
}

8. Verktygsfunktionssignaturer

Problem: Semantiska kernel-plugin-metoder behöver [KernelFunction] attribut.

public class MenuPlugin
{
    [KernelFunction] // Required.
    public static MenuItem[] GetMenu() => ...;
}

Lösning: Agent Framework kan använda metoder direkt utan attribut.

public class MenuTools
{
    [Description("Get menu items")] // Optional description.
    public static MenuItem[] GetMenu() => ...;
}

9. Alternativ konfiguration

Problem: Konfiguration av komplexa alternativ i semantisk kernel.

OpenAIPromptExecutionSettings settings = new() { MaxTokens = 1000 };
AgentInvokeOptions options = new() { KernelArguments = new(settings) };

Lösning: Förenklade alternativ i Agent Framework.

ChatClientAgentRunOptions options = new(new() { MaxOutputTokens = 1000 });

Viktigt!

Det här exemplet visar hur du skickar implementeringsspecifika alternativ till en ChatClientAgent. Alla har inte stöd AIAgents för ChatClientAgentRunOptions. ChatClientAgent tillhandahålls för att skapa agenter baserat på underliggande slutsatsdragningstjänster och stöder därför slutsatsdragningsalternativ som MaxOutputTokens.

10. Beroendeinmatning

Semantisk Kärna

En Kernel registrering krävs i tjänstcontainern för att kunna skapa en agent, eftersom varje agentabstraktion måste initieras med en Kernel egenskap.

Semantisk kernel använder Agent typen som basabstraktionsklass för agenter.

services.AddKernel().AddProvider(...);
serviceContainer.AddKeyedSingleton<SemanticKernel.Agents.Agent>(
    TutorName,
    (sp, key) =>
        new ChatCompletionAgent()
        {
            // Passing the kernel is required.
            Kernel = sp.GetRequiredService<Kernel>(),
        });

Agentramverk

Agent Framework tillhandahåller AIAgent typen som basabstraktionsklass.

services.AddKeyedSingleton<AIAgent>(() => client.CreateAIAgent(...));

11. Konsolidering av agenttyp

Semantisk Kärna

Semantisk kernel tillhandahåller specifika agentklasser för olika tjänster, till exempel:

  • ChatCompletionAgent för användning med chatt-kompletteringsbaserade slutsatsdragningstjänster.
  • OpenAIAssistantAgent för användning med OpenAI Assistants-tjänsten.
  • AzureAIAgent för användning med Azure AI Foundry Agents-tjänsten.

Agentramverk

Agent Framework stöder alla nämnda tjänster via en enda agenttyp, ChatClientAgent.

ChatClientAgent kan användas för att skapa agenter med hjälp av en underliggande tjänst som tillhandahåller en SDK som implementerar IChatClient gränssnittet.

Viktiga skillnader

Här är en sammanfattning av de viktigaste skillnaderna mellan Semantic Kernel Agent Framework och Microsoft Agent Framework som hjälper dig att migrera din kod.

1. Paketera och importera uppdateringar

Semantisk Kärna

Semantiska kernelpaket installeras som semantic-kernel och importeras som semantic_kernel. Paketet har också ett antal som extras du kan installera för att installera de olika beroendena för olika AI-leverantörer och andra funktioner.

from semantic_kernel import Kernel
from semantic_kernel.agents import ChatCompletionAgent

Agentramverk

Agent Framework-paketet installeras som agent-framework och importeras som agent_framework. Agent Framework är uppbyggt på olika sätt, det har ett kärnpaket agent-framework-core som innehåller kärnfunktionerna och sedan finns det flera paket som förlitar sig på kärnpaketet, till exempel agent-framework-azure-ai, agent-framework-mem0, agent-framework-copilotstudioosv. När du kör pip install agent-framework det installeras kärnpaketet och alla paket, så att du snabbt kan komma igång med alla funktioner. När du är redo att minska antalet paket eftersom du vet vad du behöver kan du bara installera de paket du behöver, så om du till exempel bara planerar att använda Azure AI Foundry och Mem0 kan du bara installera dessa två paket: pip install agent-framework-azure-ai agent-framework-mem0, agent-framework-core är ett beroende av dessa två, så installeras automatiskt.

Även om paketen är uppdelade, kommer importen från agent_framework, eller så är det moduler. Så för att till exempel importera klienten för Azure AI Foundry skulle du göra:

from agent_framework.azure import AzureAIAgentClient

Många av de vanligaste typerna importeras direkt från agent_framework:

from agent_framework import ChatMessage, ChatAgent

2. Konsolidering av agenttyp

Semantisk Kärna

Semantisk kernel tillhandahåller specifika agentklasser för olika tjänster, till exempel ChatCompletionAgent, AzureAIAgent, OpenAIAssistantAgent osv. Se Agenttyper i semantisk kernel.

Agentramverk

I Agent Framework skapas majoriteten av agenterna med hjälp av vilka ChatAgent kan användas med alla ChatClient baserade tjänster, till exempel Azure AI Foundry, OpenAI ChatCompletion och OpenAI Responses. Det finns ytterligare två agenter: CopilotStudioAgent för användning med Copilot Studio och A2AAgent för användning med A2A.

Alla inbyggda agenter baseras på BaseAgent (from agent_framework import BaseAgent). Och alla agenter är konsekventa med AgentProtocol (from agent_framework import AgentProtocol) gränssnittet.

3. Förenkla skapande av agent

Semantisk Kärna

Varje agent i semantisk kernel är beroende av en Kernel instans och har en tom Kernel om den inte tillhandahålls.

from semantic_kernel.agents import ChatCompletionAgent
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion

agent = ChatCompletionAgent(
    service=OpenAIChatCompletion(),
    name="Support",
    instructions="Answer in one sentence.",
)

Agentramverk

Agentskapande i Agent Framework kan göras på två sätt, direkt:

from agent_framework.azure import AzureAIAgentClient
from agent_framework import ChatMessage, ChatAgent

agent = ChatAgent(chat_client=AzureAIAgentClient(credential=AzureCliCredential()), instructions="You are a helpful assistant")

Eller med de bekvämlighetsmetoder som tillhandahålls av chattklienter:

from agent_framework.azure import AzureOpenAIChatClient
from azure.identity import AzureCliCredential
agent = AzureOpenAIChatClient(credential=AzureCliCredential()).create_agent(instructions="You are a helpful assistant")

Direktmetoden exponerar alla möjliga parametrar som du kan ange för din agent. Även om bekvämlighetsmetoden har en delmängd kan du fortfarande skicka in samma uppsättning parametrar, eftersom den anropar direktmetoden internt.

4. Skapa agenttråd

Semantisk Kärna

Anroparen måste känna till trådtypen och skapa den manuellt.

from semantic_kernel.agents import ChatHistoryAgentThread

thread = ChatHistoryAgentThread()

Agentramverk

Agenten kan uppmanas att skapa en ny tråd åt dig.

agent = ...
thread = agent.get_new_thread()

En tråd skapas sedan på något av tre sätt:

  1. Om agenten har en thread_id (eller conversation_id något liknande) uppsättning skapar den en tråd i den underliggande tjänsten med det ID:t. När en tråd har en service_thread_idkan du inte längre använda den för att lagra meddelanden i minnet. Detta gäller endast agenter som har ett trådkoncept på tjänstsidan. till exempel Azure AI Foundry Agents och OpenAI Assistants.
  2. Om agenten har en chat_message_store_factory uppsättning använder den fabriken för att skapa ett meddelandearkiv och använder det för att skapa en minnesintern tråd. Den kan sedan inte längre användas med en agent med parametern inställd på storeTrue.
  3. Om ingen av de tidigare inställningarna har angetts beaktas uninitialized den och beroende på hur den används blir den antingen en minnesintern tråd eller en tjänsttråd.

Agentramverk

Anmärkning

OpenAI-svar introducerade en ny konversationsmodell som förenklar hur konversationer hanteras. Detta förenklar hantering av värdbaserade trådar jämfört med den nu inaktuella OpenAI Assistants-modellen. Mer information finns i migreringsguiden för OpenAI Assistants.

Agent Framework har inget API för trådborttagning i AgentThread typen eftersom inte alla leverantörer stöder värdbaserade trådar eller trådborttagning och detta blir vanligare när fler leverantörer övergår till svarsbaserade arkitekturer.

Om du behöver trådborttagning och providern tillåter detta bör anroparen hålla reda på de skapade trådarna och ta bort dem senare vid behov via leverantörens sdk.

OpenAI Assistants Provider:

# OpenAI Assistants threads have self-deletion method in Semantic Kernel
await thread.delete_async()

5. Verktygsregistrering

Semantisk Kärna

Om du vill exponera en funktion som ett verktyg måste du:

  1. Dekorera funktionen med en @kernel_function dekoratör.
  2. Ha en Plugin klass eller använd kernel-plugin-fabriken för att omsluta funktionen.
  3. Ha en Kernel att lägga till plugin-programmet i.
  4. Kernel Skicka till agenten.
from semantic_kernel.functions import kernel_function

class SpecialsPlugin:
    @kernel_function(name="specials", description="List daily specials")
    def specials(self) -> str:
        return "Clam chowder, Cobb salad, Chai tea"

agent = ChatCompletionAgent(
    service=OpenAIChatCompletion(),
    name="Host",
    instructions="Answer menu questions accurately.",
    plugins=[SpecialsPlugin()],
)

Agentramverk

I ett enda anrop kan du registrera verktyg direkt i processen för att skapa agenten. Agent Framework har inte konceptet med ett plugin-program för att omsluta flera funktioner, men du kan fortfarande göra det om du vill.

Det enklaste sättet att skapa ett verktyg är bara att skapa en Python-funktion:

def get_weather(location: str) -> str:
    """Get the weather for a given location."""
    return f"The weather in {location} is sunny."

agent = chat_client.create_agent(tools=get_weather)

Anmärkning

Parametern tools finns både när agenten skapas, run metoderna och run_stream samt get_response metoderna och get_streaming_response , så att du kan ange verktyg både som en lista eller en enda funktion.

Namnet på funktionen blir sedan namnet på verktyget och docstring blir beskrivningen av verktyget. Du kan också lägga till en beskrivning i parametrarna:

from typing import Annotated

def get_weather(location: Annotated[str, "The location to get the weather for."]) -> str:
    """Get the weather for a given location."""
    return f"The weather in {location} is sunny."

Slutligen kan du använda dekoratören för att ytterligare anpassa verktygets namn och beskrivning:

from typing import Annotated
from agent_framework import ai_function

@ai_function(name="weather_tool", description="Retrieves weather information for any location")
def get_weather(location: Annotated[str, "The location to get the weather for."])
    """Get the weather for a given location."""
    return f"The weather in {location} is sunny."

Detta fungerar också när du skapar en klass med flera verktyg som metoder.

När du skapar agenten kan du nu tillhandahålla funktionsverktyget till agenten genom att skicka det till parametern tools .

class Plugin:

    def __init__(self, initial_state: str):
        self.state: list[str] = [initial_state]

    def get_weather(self, location: Annotated[str, "The location to get the weather for."]) -> str:
        """Get the weather for a given location."""
        self.state.append(f"Requested weather for {location}. ")
        return f"The weather in {location} is sunny."

    def get_weather_details(self, location: Annotated[str, "The location to get the weather details for."]) -> str:
        """Get detailed weather for a given location."""
        self.state.append(f"Requested detailed weather for {location}. ")
        return f"The weather in {location} is sunny with a high of 25°C and a low of 15°C."

plugin = Plugin("Initial state")
agent = chat_client.create_agent(tools=[plugin.get_weather, plugin.get_weather_details])

... # use the agent

print("Plugin state:", plugin.state)

Anmärkning

Funktionerna i klassen kan också dekoreras med @ai_function för att anpassa verktygens namn och beskrivning.

Den här mekanismen är också användbar för verktyg som behöver ytterligare indata som inte kan tillhandahållas av LLM, till exempel anslutningar, hemligheter osv.

6. Anrop utan direktuppspelning

Viktiga skillnader kan ses i metodnamnen från invoke till run, returtyper (till exempel AgentRunResponse) och parametrar.

Semantisk Kärna

Anroparen för icke-direktuppspelning använder ett asynkront iteratormönster för att returnera flera agentmeddelanden.

async for response in agent.invoke(
    messages=user_input,
    thread=thread,
):
    print(f"# {response.role}: {response}")
    thread = response.thread

Och det fanns en bekvämlighetsmetod för att få det slutliga svaret:

response = await agent.get_response(messages="How do I reset my bike tire?", thread=thread)
print(f"# {response.role}: {response}")

Agentramverk

Körningen Icke-direktuppspelning returnerar en enda AgentRunResponse med agentsvaret som kan innehålla flera meddelanden. Textresultatet för körningen är tillgängligt i response.text eller str(response). Alla meddelanden som skapas som en del av svaret returneras i response.messages listan. Detta kan omfatta verktygsanropsmeddelanden, funktionsresultat, resonemangsuppdateringar och slutliga resultat.

agent = ...

response = await agent.run(user_input, thread)
print("Agent response:", response.text)

7. Anrop till agentströmning

Viktiga skillnader i metodnamnen från invoke till run_stream, returtyper (AgentRunResponseUpdate) och parametrar.

Semantisk Kärna

async for update in agent.invoke_stream(
    messages="Draft a 2 sentence blurb.",
    thread=thread,
):
    if update.message:
        print(update.message.content, end="", flush=True)

Agentramverk

Liknande API-mönster för direktuppspelning där den viktigaste skillnaden är att det returnerar AgentRunResponseUpdate objekt, inklusive mer agentrelaterad information per uppdatering.

Allt innehåll som skapas av en tjänst som ligger bakom agenten returneras. Det slutliga resultatet av agenten är tillgängligt genom att kombinera update värdena till ett enda svar.

from agent_framework import AgentRunResponse
agent = ...
updates = []
async for update in agent.run_stream(user_input, thread):
    updates.append(update)
    print(update.text)

full_response = AgentRunResponse.from_agent_run_response_updates(updates)
print("Full agent response:", full_response.text)

Du kan till och med göra det direkt:

from agent_framework import AgentRunResponse
agent = ...
full_response = AgentRunResponse.from_agent_response_generator(agent.run_stream(user_input, thread))
print("Full agent response:", full_response.text)

8. Alternativkonfiguration

Problem: Konfiguration av komplexa alternativ i semantisk kernel

from semantic_kernel.connectors.ai.open_ai import OpenAIPromptExecutionSettings

settings = OpenAIPromptExecutionSettings(max_tokens=1000)
arguments = KernelArguments(settings)

response = await agent.get_response(user_input, thread=thread, arguments=arguments)

Lösning: Förenklade alternativ i Agent Framework

Agent Framework tillåter att alla parametrar skickas direkt till relevanta metoder, så att du inte behöver importera något extra eller skapa några alternativobjekt, såvida du inte vill. Internt använder den ett ChatOptions objekt för ChatClients och ChatAgents, som du också kan skapa och skicka in om du vill. Detta skapas också i en ChatAgent för att lagra alternativen och kan åsidosättas per anrop.

agent = ...

response = await agent.run(user_input, thread, max_tokens=1000, frequency_penalty=0.5)

Anmärkning

Ovanstående är specifikt för en ChatAgent, eftersom andra agenter kan ha olika alternativ, bör de alla accepteras messages som en parameter, eftersom det definieras i AgentProtocol.

Nästa steg