Freigeben über


Leitfaden zur Migration des semantischen Kernels zum Agent-Framework

Vorteile von Microsoft Agent Framework

  • Vereinfachte API: Reduzierter Komplexitäts- und Codebausteine.
  • Bessere Leistung: Optimierte Objekterstellung und Speicherauslastung.
  • Einheitliche Schnittstelle: Einheitliche Muster für verschiedene KI-Anbieter.
  • Erweiterte Entwicklerumgebung: Intuitivere und auffindbare APIs.

In den folgenden Abschnitten werden die wichtigsten Unterschiede zwischen semantic Kernel Agent Framework und Microsoft Agent Framework zusammengefasst, um Ihren Code zu migrieren.

1. Namespaceupdates

Semantischer Kernel

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

Agenten-Framework

Agent Framework-Namespaces befinden sich unter Microsoft.Agents.AI. Agent Framework verwendet die wichtigsten KI-Nachrichten und Inhaltstypen für Microsoft.Extensions.AI die Kommunikation zwischen Komponenten.

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

2. Vereinfachung der Agentenerstellung

Semantischer Kernel

Jeder Agent im semantischen Kernel hängt von einer Kernel Instanz ab und hat eine leere Kernel , wenn nicht angegeben.

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

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

Azure AI Foundry erfordert, dass eine Agentressource in der Cloud erstellt wird, bevor eine lokale Agentklasse erstellt wird, die sie verwendet.

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

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

AzureAIAgent agent = new(definition, azureAgentClient);

Agenten-Framework

Die Agent-Erstellung im Agent Framework wird durch Erweiterungen vereinfacht, die von allen Hauptanbietern bereitgestellt werden.

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

Darüber hinaus können Sie für anbieter gehostete Agent auch die GetAIAgent Methode verwenden, um einen Agent von einem vorhandenen gehosteten Agent abzurufen.

AIAgent azureFoundryAgent = await persistentAgentsClient.GetAIAgentAsync(agentId);

3. Agentthreaderstellung

Semantischer Kernel

Der Aufrufer muss den Threadtyp kennen und manuell erstellen.

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

Agenten-Framework

Der Agent ist für das Erstellen des Threads verantwortlich.

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

4. Bereinigung des gehosteten Agent-Threads

Dieser Fall gilt ausschließlich für einige KI-Anbieter, die weiterhin gehostete Threads bereitstellen.

Semantischer Kernel

Threads weisen eine self Löschmethode auf.

OpenAI Assistants Provider:

await thread.DeleteAsync();

Agenten-Framework

Hinweis

OpenAI-Antworten haben ein neues Unterhaltungsmodell eingeführt, das die Behandlung von Unterhaltungen vereinfacht. Diese Änderung vereinfacht die gehostete Threadverwaltung im Vergleich zum jetzt veralteten OpenAI-Assistentenmodell. Weitere Informationen finden Sie im Migrationshandbuch für OpenAI-Assistenten.

Agent Framework verfügt nicht über eine Threadlösch-API im AgentThread Typ, da nicht alle Anbieter gehostete Threads oder Threadlöschung unterstützen. Dieses Design wird häufiger, da mehr Anbieter auf antwortenbasierte Architekturen umstellen.

Wenn Sie Threadlöschung benötigen und der Anbieter dies zulässt, sollte der Aufrufer die erstellten Threads nachverfolgen und später löschen, wenn dies über das SDK des Anbieters erforderlich ist.

OpenAI Assistants Provider:

await assistantClient.DeleteThreadAsync(thread.ConversationId);

5. Toolregistrierung

Semantischer Kernel

Um eine Funktion als Tool verfügbar zu machen, müssen Sie:

  1. Schmücken Sie die Funktion mit einem [KernelFunction] Attribut.
  2. Verwenden Sie eine Plugin Klasse, oder verwenden Sie die KernelPluginFactory Funktion, um die Funktion umzuschließen.
  3. Kernel Sie müssen Ihr Plug-In hinzufügen.
  4. Übergeben Sie den Kernel Agent.
KernelFunction function = KernelFunctionFactory.CreateFromMethod(GetWeather);
KernelPlugin plugin = KernelPluginFactory.CreateFromFunctions("KernelPluginName", [function]);
Kernel kernel = ... // Create kernel
kernel.Plugins.Add(plugin);

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

Agenten-Framework

Im Agent Framework können Sie in einem einzigen Aufruf Tools direkt im Agent-Erstellungsprozess registrieren.

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

6. Agent- und Nicht-Streaming-Aufruf

Wichtige Unterschiede können in den Methodennamen von Invoke zu Run, Rückgabetypen und Parametern AgentRunOptionsangezeigt werden.

Semantischer Kernel

Das Nicht-Streaming verwendet ein Streamingmuster IAsyncEnumerable<AgentResponseItem<ChatMessageContent>> zum Zurückgeben mehrerer Agentnachrichten.

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

Agenten-Framework

Das Nicht-Streaming gibt eine einzelne AgentRunResponse mit der Agentantwort zurück, die mehrere Nachrichten enthalten kann. Das Textergebnis der Ausführung ist verfügbar in AgentRunResponse.Text oder AgentRunResponse.ToString(). Alle nachrichten, die als Teil der Antwort erstellt wurden, werden in der AgentRunResponse.Messages Liste zurückgegeben. Dies kann z. B. Toolaufrufnachrichten, Funktionsergebnisse, Aktualisierungen von Gründen und endende Ergebnisse umfassen.

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

7. Agent Streaming-Aufruf

Die wichtigsten Unterschiede sind die Methodennamen von Invoke zu Run, Rückgabetypen und Parameter AgentRunOptions.

Semantischer Kernel

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

Agenten-Framework

Agent Framework verfügt über ein ähnliches Streaming-API-Muster, wobei der Hauptunterschied darin besteht, dass Objekte zurückgegeben AgentRunResponseUpdate werden, die weitere agentbezogene Informationen pro Update enthalten.

Alle Updates, die von jedem Dienst erstellt werden, der dem AIAgent zugrunde liegt, werden zurückgegeben. Das Textergebnis des Agents steht zur Verfügung, indem die AgentRunResponse.Text Werte verkettet werden.

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

8. Signatur der Toolfunktion

Problem: Methoden des semantischen Kernel-Plug-Ins benötigen [KernelFunction] Attribute.

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

Lösung: Das Agent-Framework kann Methoden direkt ohne Attribute verwenden.

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

9. Konfigurationsoptionen

Problem: Komplexe Optionen einrichten im semantischen Kernel.

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

Lösung: Vereinfachte Optionen im Agent Framework.

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

Von Bedeutung

Dieses Beispiel zeigt das Übergeben von implementierungsspezifischen Optionen an ein ChatClientAgent. Nicht alle AIAgents Unterstützen ChatClientAgentRunOptions. ChatClientAgent wird für die Erstellung von Agents basierend auf zugrunde liegenden Rückschlussdiensten bereitgestellt und unterstützt daher Rückschlussoptionen wie MaxOutputTokensz. B. .

10. Abhängigkeitsinjektion

Semantischer Kernel

Eine Kernel Registrierung ist im Dienstcontainer erforderlich, um einen Agent erstellen zu können, da jede Agent-Abstraktion mit einer Kernel Eigenschaft initialisiert werden muss.

Der semantische Kernel verwendet den Agent Typ als Basisstraktionsklasse für Agents.

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

Agenten-Framework

Agent Framework stellt den AIAgent Typ als Basisstraktionsklasse bereit.

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

11. Agenttypkonsolidierung

Semantischer Kernel

Der semantische Kernel stellt bestimmte Agentklassen für verschiedene Dienste bereit, z. B.:

  • ChatCompletionAgent für die Verwendung mit Chat-Abschluss-basierten Ableitungsdiensten.
  • OpenAIAssistantAgent für die Verwendung mit dem OpenAI Assistants-Dienst.
  • AzureAIAgent für die Verwendung mit dem Azure AI Foundry Agents-Dienst.

Agenten-Framework

Agent Framework unterstützt alle erwähnten Dienste über einen einzelnen Agent-Typ. ChatClientAgent

ChatClientAgent kann zum Erstellen von Agents mit jedem zugrunde liegenden Dienst verwendet werden, der ein SDK bereitstellt, das die IChatClient Schnittstelle implementiert.

Wichtige Unterschiede

Hier ist eine Zusammenfassung der wichtigsten Unterschiede zwischen dem semantischen Kernel-Agent Framework und Dem Microsoft Agent Framework, die Ihnen beim Migrieren ihres Codes helfen.

1. Verpacken und Importieren von Updates

Semantischer Kernel

Semantische Kernelpakete werden als semantic-kernel installiert und importiert als semantic_kernel. Das Paket verfügt außerdem über eine Reihe von extras Komponenten, die Sie installieren können, um die verschiedenen Abhängigkeiten für verschiedene KI-Anbieter und andere Features zu installieren.

from semantic_kernel import Kernel
from semantic_kernel.agents import ChatCompletionAgent

Agenten-Framework

Das Agent Framework-Paket wird wie agent-framework installiert und importiert als agent_framework. Agent Framework ist anders aufgebaut, verfügt über ein Kernpaket agent-framework-core , das die Kernfunktionen enthält, und dann gibt es mehrere Pakete, die auf diesem Kernpaket basieren, z agent-framework-azure-ai. B. , agent-framework-mem0, agent-framework-copilotstudiousw. Wenn Sie es ausführen pip install agent-framework --pre , wird das Kernpaket und alle Pakete installiert, damit Sie schnell mit allen Features beginnen können. Wenn Sie bereit sind, die Anzahl der Pakete zu reduzieren, da Sie wissen, was Sie benötigen, können Sie nur die benötigten Pakete installieren, z. B. wenn Sie nur planen, Azure AI Foundry und Mem0 zu verwenden, können Sie nur diese beiden Pakete installieren: pip install agent-framework-azure-ai agent-framework-mem0 --pre, agent-framework-core ist eine Abhängigkeit von diesen beiden, wird also automatisch installiert.

Obwohl die Pakete aufgeteilt werden, sind die Importe alle von agent_frameworkoder aus Modulen. So würden Sie z. B. den Client für Azure AI Foundry importieren:

from agent_framework.azure import AzureAIAgentClient

Viele der am häufigsten verwendeten Typen werden direkt aus agent_framework:

from agent_framework import ChatMessage, ChatAgent

2. Konsolidierung des Agenttyps

Semantischer Kernel

Der semantische Kernel stellt bestimmte Agentklassen für verschiedene Dienste bereit, z. B. ChatCompletionAgent, AzureAIAgent, OpenAIAssistantAgent usw. Siehe Agenttypen im semantischen Kernel.

Agenten-Framework

Im Agent Framework werden die meisten Agents mit den ChatAgent basierten Diensten erstellt, die mit allen ChatClient basierten Diensten verwendet werden können, z. B. Azure AI Foundry, OpenAI ChatCompletion und OpenAI-Antworten. Es gibt zwei zusätzliche Agents: CopilotStudioAgent für die Verwendung mit Copilot Studio und A2AAgent für die Verwendung mit A2A.

Alle integrierten Agents basieren auf dem BaseAgent (from agent_framework import BaseAgent). Und alle Agents sind mit der AgentProtocol (from agent_framework import AgentProtocol) Schnittstelle konsistent.

3. Vereinfachung der Agentenerstellung

Semantischer Kernel

Jeder Agent im semantischen Kernel hängt von einer Kernel Instanz ab und hat eine leere Kernel , wenn nicht angegeben.

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.",
)

Agenten-Framework

Die Agenterstellung im Agent-Framework kann auf zwei Arten erfolgen:

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")

Oder mit den Komfortmethoden, die von Chatclients bereitgestellt werden:

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

Die direkte Methode macht alle möglichen Parameter verfügbar, die Sie für Ihren Agent festlegen können. Obwohl die Komfortmethode über eine Teilmenge verfügt, können Sie trotzdem dieselbe Gruppe von Parametern übergeben, da sie die direkte Methode intern aufruft.

4. Agentthreaderstellung

Semantischer Kernel

Der Aufrufer muss den Threadtyp kennen und manuell erstellen.

from semantic_kernel.agents import ChatHistoryAgentThread

thread = ChatHistoryAgentThread()

Agenten-Framework

Der Agent kann aufgefordert werden, einen neuen Thread für Sie zu erstellen.

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

Anschließend wird ein Thread auf eine von drei Arten erstellt:

  1. Wenn der Agent einen thread_id Satz (oder conversation_id etwas ähnliches) festgelegt hat, wird ein Thread im zugrunde liegenden Dienst mit dieser ID erstellt. Sobald ein Thread über einen service_thread_idThread verfügt, können Sie ihn nicht mehr zum Speichern von Nachrichten im Arbeitsspeicher verwenden. Dies gilt nur für Agents, die über ein dienstseitiges Threadkonzept verfügen. wie Azure AI Foundry Agents und OpenAI-Assistenten.
  2. Wenn der Agent über einen chat_message_store_factory Satz verfügt, wird diese Factory verwendet, um einen Nachrichtenspeicher zu erstellen und dies zum Erstellen eines In-Memory-Threads zu verwenden. Sie kann dann nicht mehr mit einem Agent verwendet werden, auf den der store Parameter festgelegt ist True.
  3. Wenn keine der vorherigen Einstellungen festgelegt ist, wird sie berücksichtigt uninitialized und abhängig davon, wie sie verwendet wird, entweder zu einem In-Memory-Thread oder zu einem Dienstthread.

Agenten-Framework

Hinweis

OpenAI-Antworten haben ein neues Unterhaltungsmodell eingeführt, das die Behandlung von Unterhaltungen vereinfacht. Dies vereinfacht die gehostete Threadverwaltung im Vergleich zum jetzt veralteten OpenAI-Assistentenmodell. Weitere Informationen finden Sie im Migrationshandbuch für OpenAI-Assistenten.

Agent Framework verfügt nicht über eine Threadlösch-API im AgentThread Typ, da nicht alle Anbieter gehostete Threads oder Threadlöschungen unterstützen. Dies wird häufiger, da mehr Anbieter auf antwortenbasierte Architekturen umsteigen.

Wenn Sie threadlöschen müssen und der Anbieter dies zulässt, sollte der Aufrufer die erstellten Threads nachverfolgen und später löschen, wenn dies über das Sdk des Anbieters erforderlich ist.

OpenAI Assistants Provider:

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

5. Toolregistrierung

Semantischer Kernel

Um eine Funktion als Tool verfügbar zu machen, müssen Sie:

  1. Dekorieren Sie die Funktion mit einem @kernel_function Dekorateur.
  2. Verwenden Sie eine Plugin Klasse, oder verwenden Sie die Kernel-Plug-In-Factory, um die Funktion umzuschließen.
  3. Kernel Sie müssen Ihr Plug-In hinzufügen.
  4. Übergeben Sie den Kernel Agent.
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()],
)

Agenten-Framework

In einem einzigen Aufruf können Sie Tools direkt im Agent-Erstellungsprozess registrieren. Agent Framework verfügt nicht über das Konzept eines Plug-Ins zum Umschließen mehrerer Funktionen, aber Sie können dies bei Bedarf dennoch tun.

Die einfachste Möglichkeit zum Erstellen eines Tools besteht darin, eine Python-Funktion zu erstellen:

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)

Hinweis

Der tools Parameter ist sowohl für die Agenterstellung als auch für die runrun_streamget_response Methoden und get_streaming_response Methoden vorhanden, mit denen Sie Tools sowohl als Liste als auch als einzelne Funktion bereitstellen können.

Der Name der Funktion wird dann zum Namen des Tools, und die Docstring wird zur Beschreibung des Tools, Sie können auch eine Beschreibung zu den Parametern hinzufügen:

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."

Schließlich können Sie den Dekorateur verwenden, um den Namen und die Beschreibung des Tools weiter anzupassen:

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."

Dies funktioniert auch, wenn Sie eine Klasse mit mehreren Tools als Methoden erstellen.

Beim Erstellen des Agents können Sie nun das Funktionstool an den Agent bereitstellen, indem Sie ihn an den tools Parameter übergeben.

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)

Hinweis

Die Funktionen innerhalb der Klasse können auch zum @ai_function Anpassen des Namens und der Beschreibung der Tools eingerichtet werden.

Dieser Mechanismus ist auch nützlich für Tools, die zusätzliche Eingaben benötigen, die nicht vom LLM bereitgestellt werden können, z. B. Verbindungen, geheime Schlüssel usw.

Kompatibilität: Verwenden von KernelFunction als Agent Framework-Tools

Wenn Sie über vorhandenen semantischen Kernelcode mit KernelFunction Instanzen verfügen (entweder von Eingabeaufforderungen oder von Methoden), können Sie sie mithilfe der .as_agent_framework_tool Methode in Agent Framework-Tools konvertieren.

Von Bedeutung

Für dieses Feature ist Version 1.38 oder höher erforderlich semantic-kernel .

Verwenden von KernelFunction aus einer Eingabeaufforderungsvorlage

from semantic_kernel import Kernel
from semantic_kernel.functions import KernelFunctionFromPrompt
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion, OpenAIChatPromptExecutionSettings
from semantic_kernel.prompt_template import KernelPromptTemplate, PromptTemplateConfig
from agent_framework.openai import OpenAIResponsesClient

# Create a kernel with services and plugins
kernel = Kernel()
# will get the api_key and model_id from the environment
kernel.add_service(OpenAIChatCompletion(service_id="default"))

# Create a function from a prompt template that uses plugin functions
function_definition = """
Today is: {{time.date}}
Current time is: {{time.time}}

Answer to the following questions using JSON syntax, including the data used.
Is it morning, afternoon, evening, or night (morning/afternoon/evening/night)?
Is it weekend time (weekend/not weekend)?
"""

prompt_template_config = PromptTemplateConfig(template=function_definition)
prompt_template = KernelPromptTemplate(prompt_template_config=prompt_template_config)

# Create a KernelFunction from the prompt
kernel_function = KernelFunctionFromPrompt(
    description="Determine the kind of day based on the current time and date.",
    plugin_name="TimePlugin",
    prompt_execution_settings=OpenAIChatPromptExecutionSettings(service_id="default", max_tokens=100),
    function_name="kind_of_day",
    prompt_template=prompt_template,
)

# Convert the KernelFunction to an Agent Framework tool
agent_tool = kernel_function.as_agent_framework_tool(kernel=kernel)

# Use the tool with an Agent Framework agent
agent = OpenAIResponsesClient(model_id="gpt-4o").create_agent(tools=agent_tool)
response = await agent.run("What kind of day is it?")
print(response.text)

Verwenden von KernelFunction aus einer Methode

from semantic_kernel.functions import kernel_function
from agent_framework.openai import OpenAIResponsesClient

# Create a plugin class with kernel functions
@kernel_function(name="get_weather", description="Get the weather for a location")
def get_weather(self, location: str) -> str:
    return f"The weather in {location} is sunny."

# Get the KernelFunction and convert it to an Agent Framework tool
agent_tool = get_weather.as_agent_framework_tool()

# Use the tool with an Agent Framework agent
agent = OpenAIResponsesClient(model_id="gpt-4o").create_agent(tools=agent_tool)
response = await agent.run("What's the weather in Seattle?")
print(response.text)

Verwenden von VectorStore mit create_search_function

Sie können auch die VectorStore-Integrationen des semantischen Kernels mit Agent Framework verwenden. Die create_search_function Methode aus einer Vektorspeicherauflistung gibt ein KernelFunction , das in ein Agent Framework-Tool konvertiert werden kann.

from semantic_kernel import Kernel
from semantic_kernel.connectors.ai.open_ai import OpenAITextEmbedding
from semantic_kernel.connectors.azure_ai_search import AzureAISearchCollection
from semantic_kernel.functions import KernelParameterMetadata
from agent_framework.openai import OpenAIResponsesClient

# Define your data model
class HotelSampleClass:
    HotelId: str
    HotelName: str
    Description: str
    # ... other fields

# Create an Azure AI Search collection
collection = AzureAISearchCollection[str, HotelSampleClass](
    record_type=HotelSampleClass,
    embedding_generator=OpenAITextEmbedding()
)

async with collection:
    await collection.ensure_collection_exists()
    # Load your records into the collection
    # await collection.upsert(records)

    # Create a search function from the collection
    search_function = collection.create_search_function(
        description="A hotel search engine, allows searching for hotels in specific cities.",
        search_type="keyword_hybrid",
        filter=lambda x: x.Address.Country == "USA",
        parameters=[
            KernelParameterMetadata(
                name="query",
                description="What to search for.",
                type="str",
                is_required=True,
                type_object=str,
            ),
            KernelParameterMetadata(
                name="city",
                description="The city that you want to search for a hotel in.",
                type="str",
                type_object=str,
            ),
            KernelParameterMetadata(
                name="top",
                description="Number of results to return.",
                type="int",
                default_value=5,
                type_object=int,
            ),
        ],
        string_mapper=lambda x: f"(hotel_id: {x.record.HotelId}) {x.record.HotelName} - {x.record.Description}",
    )

    # Convert the search function to an Agent Framework tool
    search_tool = search_function.as_agent_framework_tool()

    # Use the tool with an Agent Framework agent
    agent = OpenAIResponsesClient(model_id="gpt-4o").create_agent(
        instructions="You are a travel agent that helps people find hotels.",
        tools=search_tool
    )
    response = await agent.run("Find me a hotel in Seattle")
    print(response.text)

Dieses Muster funktioniert mit jedem semantischen Kernel VectorStore-Connector (Azure AI Search, Qdrant, Pinecone usw.), sodass Sie Ihre vorhandene Vektorsuchinfrastruktur mit Agent Framework-Agents nutzen können.

Mit dieser Kompatibilitätsschicht können Sie Ihren Code schrittweise von semantischem Kernel zu Agent Framework migrieren und ihre vorhandenen KernelFunction Implementierungen wiederverwenden und gleichzeitig die vereinfachten Agenterstellungs- und Ausführungsmuster des Agent-Frameworks nutzen.

6. Agent- und Nicht-Streaming-Aufruf

Wichtige Unterschiede können in den Methodennamen von invoke zu run, Rückgabetypen (z. B AgentRunResponse. ) und Parametern angezeigt werden.

Semantischer Kernel

Der Nicht-Streaming-Aufruf verwendet ein asynchrones Iteratormuster zum Zurückgeben mehrerer Agentnachrichten.

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

Und es gab eine Komfortmethode, um die endgültige Antwort zu erhalten:

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

Agenten-Framework

Die Nicht-Streaming-Ausführung gibt eine einzelne AgentRunResponse mit der Agentantwort zurück, die mehrere Nachrichten enthalten kann. Das Textergebnis der Ausführung ist verfügbar in response.text oder str(response). Alle nachrichten, die als Teil der Antwort erstellt wurden, werden in der response.messages Liste zurückgegeben. Dies kann Toolaufrufnachrichten, Funktionsergebnisse, Begründungsaktualisierungen und endende Ergebnisse umfassen.

agent = ...

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

7. Agent Streaming-Aufruf

Wichtige Unterschiede bei den Methodennamen von invoke zu run_stream, Rückgabetypen (AgentRunResponseUpdate) und Parametern.

Semantischer Kernel

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)

Agenten-Framework

Ein ähnliches Streaming-API-Muster mit dem Hauptunterschied besteht darin, dass objekte zurückgegeben AgentRunResponseUpdate werden, einschließlich weiterer agentbezogener Informationen pro Update.

Alle Inhalte, die von jedem Dienst erstellt werden, der dem Agent zugrunde liegt, werden zurückgegeben. Das Endergebnis des Agents steht zur Verfügung, indem die update Werte in einer einzigen Antwort kombiniert werden.

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)

Sie können dies sogar direkt tun:

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. Konfigurationsoptionen

Problem: Komplexe Optionen einrichten im semantischen 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ösung: Vereinfachte Optionen im Agent Framework

Das Agent-Framework ermöglicht die direkte Übergabe aller Parameter an die relevanten Methoden, sodass Sie keine zusätzlichen Objekte importieren oder Optionsobjekte erstellen müssen, es sei denn, Sie möchten. Intern verwendet es ein ChatOptions Objekt für ChatClients und ChatAgents, das Sie auch erstellen und übergeben können, wenn Sie möchten. Dies wird auch in einer ChatAgent Datei erstellt, die die Optionen enthält und pro Aufruf überschrieben werden kann.

agent = ...

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

Hinweis

Die oben genannten Elemente sind spezifisch für einen ChatAgent, da andere Agents möglicherweise unterschiedliche Optionen haben, sollten sie alle als Parameter akzeptiert messages werden, da dies in der AgentProtocol.

Nächste Schritte