Udostępnij przez


Przewodnik migracji jądra semantycznego do platformy agentów

Zalety programu Microsoft Agent Framework

  • Uproszczony interfejs API: zmniejszona złożoność i standardowy kod.
  • Lepsza wydajność: Zoptymalizowane tworzenie obiektów i użycie pamięci.
  • Ujednolicony interfejs: spójne wzorce dla różnych dostawców sztucznej inteligencji.
  • Ulepszone środowisko deweloperskie: bardziej intuicyjne i wykrywalne interfejsy API.

W poniższych sekcjach podsumowano kluczowe różnice między programem Semantic Kernel Agent Framework i programem Microsoft Agent Framework, aby ułatwić migrację kodu.

1. Aktualizacje przestrzeni nazw

Jądro semantyczne

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

Struktura agenta

Przestrzenie nazw programu Agent Framework znajdują się w obszarze Microsoft.Agents.AI. Struktura agenta używa podstawowego komunikatu sztucznej inteligencji i typów zawartości na Microsoft.Extensions.AI potrzeby komunikacji między składnikami.

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

2. Uproszczenie tworzenia agentów

Jądro semantyczne

Każdy agent w jądrze semantycznym zależy od Kernel wystąpienia i ma puste Kernel , jeśli nie podano.

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

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

Usługa Azure AI Foundry wymaga utworzenia zasobu agenta w chmurze przed utworzeniem lokalnej klasy agenta, która z niej korzysta.

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

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

AzureAIAgent agent = new(definition, azureAgentClient);

Struktura agenta

Tworzenie agenta w programie Agent Framework jest prostsze z rozszerzeniami udostępnianymi przez wszystkich głównych dostawców.

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

Ponadto w przypadku dostawców agentów hostowanych można również użyć GetAIAgent metody w celu pobrania agenta z istniejącego hostowanego agenta.

AIAgent azureFoundryAgent = await persistentAgentsClient.GetAIAgentAsync(agentId);

3. Tworzenie wątku agenta

Jądro semantyczne

Obiekt wywołujący musi znać typ wątku i utworzyć go ręcznie.

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

Struktura agenta

Agent jest odpowiedzialny za tworzenie wątku.

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

4. Oczyszczanie wątku hostowanego agenta

Ten przypadek dotyczy wyłącznie kilku dostawców sztucznej inteligencji, którzy nadal udostępniają hostowane wątki.

Jądro semantyczne

Wątki mają metodę self usuwania.

Dostawca asystentów OpenAI:

await thread.DeleteAsync();

Struktura agenta

Uwaga / Notatka

Odpowiedzi openAI wprowadziły nowy model konwersacji, który upraszcza obsługę konwersacji. Ta zmiana upraszcza zarządzanie hostowanymi wątkami w porównaniu z przestarzałym modelem Asystentów OpenAI. Aby uzyskać więcej informacji, zobacz Przewodnik migracji asystentów OpenAI.

Struktura agenta nie ma interfejsu API usuwania wątków w typie AgentThread , ponieważ nie wszyscy dostawcy obsługują hostowane wątki ani usuwanie wątków. Ten projekt stanie się bardziej powszechny, ponieważ coraz więcej dostawców przechodzi do architektur opartych na odpowiedziach.

Jeśli wymagasz usunięcia wątku, a dostawca go zezwala, obiekt wywołujący powinien śledzić utworzone wątki i usuwać je później, gdy jest to konieczne za pośrednictwem zestawu SDK dostawcy.

Dostawca asystentów OpenAI:

await assistantClient.DeleteThreadAsync(thread.ConversationId);

5. Rejestracja narzędzi

Jądro semantyczne

Aby uwidocznić funkcję jako narzędzie, musisz:

  1. Dekoruj funkcję za pomocą atrybutu [KernelFunction] .
  2. Utwórz klasę Plugin lub użyj klasy KernelPluginFactory , aby opakowować funkcję.
  3. Dodaj wtyczkę Kernel do.
  4. Przekaż element Kernel do agenta.
KernelFunction function = KernelFunctionFactory.CreateFromMethod(GetWeather);
KernelPlugin plugin = KernelPluginFactory.CreateFromFunctions("KernelPluginName", [function]);
Kernel kernel = ... // Create kernel
kernel.Plugins.Add(plugin);

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

Struktura agenta

W środowisku Agent Framework w jednym wywołaniu można rejestrować narzędzia bezpośrednio w procesie tworzenia agenta.

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

6. Wywołanie agenta bez przesyłania strumieniowego

Kluczowe różnice można zobaczyć w nazwach metod z Invoke do Run, zwracanych typów i parametrów AgentRunOptions.

Jądro semantyczne

Funkcja non-Streaming używa wzorca IAsyncEnumerable<AgentResponseItem<ChatMessageContent>> przesyłania strumieniowego do zwracania wielu komunikatów agenta.

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

Struktura agenta

Funkcja Non-Streaming zwraca pojedynczą AgentRunResponse odpowiedź agenta, która może zawierać wiele komunikatów. Wynik tekstowy przebiegu jest dostępny w systemie AgentRunResponse.Text lub AgentRunResponse.ToString(). Wszystkie komunikaty utworzone w ramach odpowiedzi są zwracane na AgentRunResponse.Messages liście. Może to obejmować komunikaty wywołania narzędzi, wyniki funkcji, aktualizacje rozumowania i końcowe wyniki.

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

7. Wywołanie przesyłania strumieniowego agenta

Kluczowe różnice dotyczą nazw metod od Invoke do Run, zwracanych typów i parametrów AgentRunOptions.

Jądro semantyczne

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

Struktura agenta

Struktura agenta ma podobny wzorzec interfejsu API przesyłania strumieniowego, a kluczową różnicą jest zwracanie AgentRunResponseUpdate obiektów zawierających więcej informacji związanych z agentem na aktualizację.

Zwracane są wszystkie aktualizacje generowane przez dowolną usługę bazową dla agenta AIAgent. Tekstowy wynik agenta jest dostępny przez łączenie AgentRunResponse.Text wartości.

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

8. Podpisy funkcji narzędzi

Problem: Metody wtyczki jądra semantycznego wymagają [KernelFunction] atrybutów.

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

Rozwiązanie: Struktura agentów może używać metod bezpośrednio bez atrybutów.

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

9. Konfiguracja opcji

Problem: Konfiguracja opcji złożonych w jądrze semantycznym.

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

Rozwiązanie: Uproszczone opcje w strukturze agentów.

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

Ważne

W tym przykładzie pokazano przekazywanie opcji specyficznych dla implementacji do elementu ChatClientAgent. Nie wszystkie AIAgents obsługują program ChatClientAgentRunOptions. ChatClientAgent program jest dostarczany do tworzenia agentów na podstawie bazowych usług wnioskowania, a w związku z tym obsługuje opcje wnioskowania, takie jak MaxOutputTokens.

10. Wstrzykiwanie zależności

Jądro semantyczne

Rejestracja Kernel jest wymagana w kontenerze usługi, aby móc utworzyć agenta, ponieważ każda abstrakcja agenta musi zostać zainicjowana Kernel za pomocą właściwości .

Semantyczne jądro używa Agent typu jako podstawowej klasy abstrakcji dla agentów.

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

Struktura agenta

Struktura agenta udostępnia typ jako klasę AIAgent abstrakcji podstawowej.

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

11. Konsolidacja typów agentów

Jądro semantyczne

Semantyczne jądro udostępnia określone klasy agentów dla różnych usług, na przykład:

  • ChatCompletionAgent do użytku z usługami wnioskowania opartymi na czacie.
  • OpenAIAssistantAgent do użycia z usługą OpenAI Assistants.
  • AzureAIAgent do użycia z usługą Azure AI Foundry Agents.

Struktura agenta

Struktura agenta obsługuje wszystkie wymienione usługi za pośrednictwem jednego typu agenta. ChatClientAgent

ChatClientAgent Może służyć do kompilowania agentów przy użyciu dowolnej podstawowej usługi, która udostępnia zestaw SDK, który implementuje IChatClient interfejs.

Kluczowe różnice

Poniżej przedstawiono podsumowanie kluczowych różnic między programem Semantic Kernel Agent Framework i programem Microsoft Agent Framework, które ułatwiają migrowanie kodu.

1. Pakowanie i importowanie aktualizacji

Jądro semantyczne

Pakiety jądra semantycznego są instalowane jako semantic-kernel i importowane jako semantic_kernel. Pakiet zawiera również wiele elementów extras , które można zainstalować w celu zainstalowania różnych zależności dla różnych dostawców sztucznej inteligencji i innych funkcji.

from semantic_kernel import Kernel
from semantic_kernel.agents import ChatCompletionAgent

Struktura agenta

Pakiet platformy Agent Framework jest instalowany jako agent-framework i importowany jako agent_framework. Struktura agenta jest kompilowana inaczej, ma podstawowy pakiet agent-framework-core zawierający podstawowe funkcje, a następnie istnieje wiele pakietów, które korzystają z tego podstawowego pakietu, takiego jak agent-framework-azure-ai, agent-framework-mem0, agent-framework-copilotstudioitp. Po uruchomieniu pip install agent-framework --pre zostanie zainstalowany pakiet podstawowy i wszystkie pakiety, dzięki czemu będzie można szybko rozpocząć pracę ze wszystkimi funkcjami. Gdy wszystko będzie gotowe do zmniejszenia liczby pakietów, ponieważ wiesz, czego potrzebujesz, możesz zainstalować tylko potrzebne pakiety, więc na przykład jeśli planujesz używać usługi Azure AI Foundry i Mem0, możesz zainstalować tylko te dwa pakiety: pip install agent-framework-azure-ai agent-framework-mem0 --pre, agent-framework-core jest to zależność do tych dwóch, więc zostanie automatycznie zainstalowana.

Mimo że pakiety są podzielone, importy pochodzą z agent_frameworkmodułów lub modułów. Na przykład w celu zaimportowania klienta dla rozwiązania Azure AI Foundry należy wykonać następujące czynności:

from agent_framework.azure import AzureAIAgentClient

Wiele najczęściej używanych typów jest importowanych bezpośrednio z agent_frameworkprogramu :

from agent_framework import ChatMessage, ChatAgent

2. Konsolidacja typów agentów

Jądro semantyczne

Semantyczne jądro udostępnia określone klasy agentów dla różnych usług, na przykład ChatCompletionAgent, AzureAIAgent, OpenAIAssistantAgent itp. Zobacz Typy agentów w jądrze semantycznym.

Struktura agenta

W środowisku Agent Framework większość agentów jest tworzona przy użyciu elementów ChatAgent , których można używać we wszystkich ChatClient usługach opartych, takich jak Azure AI Foundry, OpenAI ChatCompletion i OpenAI Responses. Istnieją dwa dodatkowe agenty: CopilotStudioAgent do użytku z programem Copilot Studio i A2AAgent do użytku z usługą A2A.

Wszyscy wbudowani agenci bazują na usłudze BaseAgent (from agent_framework import BaseAgent). A wszyscy agenci są zgodni z interfejsem AgentProtocol (from agent_framework import AgentProtocol).

3. Uproszczenie tworzenia agentów

Jądro semantyczne

Każdy agent w jądrze semantycznym zależy od Kernel wystąpienia i będzie miał pusty Kernel , jeśli nie zostanie podany.

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

Struktura agenta

Tworzenie agenta w programie Agent Framework można wykonać na dwa sposoby:

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

Lub z metodami wygody udostępnianymi przez klientów czatu:

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

Metoda bezpośrednia uwidacznia wszystkie możliwe parametry, które można ustawić dla agenta. Chociaż metoda wygody ma podzbiór, nadal można przekazać ten sam zestaw parametrów, ponieważ wywołuje metodę bezpośrednią wewnętrznie.

4. Tworzenie wątku agenta

Jądro semantyczne

Obiekt wywołujący musi znać typ wątku i utworzyć go ręcznie.

from semantic_kernel.agents import ChatHistoryAgentThread

thread = ChatHistoryAgentThread()

Struktura agenta

Agenta można poprosić o utworzenie nowego wątku.

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

Następnie wątek jest tworzony na jeden z trzech sposobów:

  1. Jeśli agent ma thread_id zestaw (lub conversation_id podobny), utworzy wątek w usłudze bazowej o tym identyfikatorze. Gdy wątek ma element service_thread_id, nie można go już używać do przechowywania komunikatów w pamięci. Dotyczy to tylko agentów, którzy mają pojęcie wątku po stronie usługi. takich jak Agenci usługi Azure AI Foundry i Asystenci OpenAI.
  2. Jeśli agent ma chat_message_store_factory zestaw, użyje tej fabryki do utworzenia magazynu komunikatów i użycia go do utworzenia wątku w pamięci. Następnie nie można go używać z agentem z parametrem ustawionym store na True.
  3. Jeśli żadne z poprzednich ustawień nie jest ustawione, jest brane pod uwagę uninitialized i w zależności od sposobu jej użycia, stanie się wątkiem w pamięci lub wątkiem usługi.

Struktura agenta

Uwaga / Notatka

Odpowiedzi openAI wprowadziły nowy model konwersacji, który upraszcza obsługę konwersacji. Upraszcza to zarządzanie hostowanymi wątkami w porównaniu z przestarzałym modelem Asystentów OpenAI. Aby uzyskać więcej informacji, zobacz Przewodnik migracji asystentów OpenAI.

Struktura agenta nie ma interfejsu API usuwania wątków w typie AgentThread , ponieważ nie wszyscy dostawcy obsługują hostowane wątki lub usuwanie wątków i stanie się to bardziej powszechne, ponieważ coraz więcej dostawców przechodzi do architektur opartych na odpowiedziach.

Jeśli potrzebujesz usunięcia wątku, a dostawca zezwala na to, obiekt wywołujący powinien śledzić utworzone wątki i usuwać je później, gdy jest to konieczne za pośrednictwem zestawu SDK dostawcy.

Dostawca asystentów OpenAI:

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

5. Rejestracja narzędzi

Jądro semantyczne

Aby uwidocznić funkcję jako narzędzie, musisz:

  1. Udekoruj funkcję dekoratorem @kernel_function .
  2. Mieć klasę Plugin lub użyć fabryki wtyczki jądra, aby opakowować funkcję.
  3. Dodaj wtyczkę Kernel do.
  4. Przekaż element Kernel do agenta.
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()],
)

Struktura agenta

W jednym wywołaniu można zarejestrować narzędzia bezpośrednio w procesie tworzenia agenta. Struktura agenta nie ma pojęcia wtyczki do opakowania wielu funkcji, ale nadal można to zrobić w razie potrzeby.

Najprostszym sposobem utworzenia narzędzia jest utworzenie funkcji języka Python:

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)

Uwaga / Notatka

Parametr tools jest obecny zarówno w przypadku tworzenia agenta, run metod i run_stream , jak i get_responseget_streaming_response i, umożliwia dostarczanie narzędzi zarówno jako listy, jak i jednej funkcji.

Nazwa funkcji stanie się nazwą narzędzia, a dokument stanie się opisem narzędzia. Można również dodać opis do parametrów:

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

Na koniec możesz użyć dekoratora, aby jeszcze bardziej dostosować nazwę i opis narzędzia:

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

Działa to również podczas tworzenia klasy z wieloma narzędziami jako metodami.

Podczas tworzenia agenta można teraz udostępnić agentowi narzędzie funkcji, przekazując je do parametru 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)

Uwaga / Notatka

Funkcje w klasie można również dekorować za pomocą @ai_function polecenia , aby dostosować nazwę i opis narzędzi.

Ten mechanizm jest również przydatny w przypadku narzędzi wymagających dodatkowych danych wejściowych, których nie można dostarczyć przez usługę LLM, takich jak połączenia, wpisy tajne itp.

Zgodność: Używanie funkcji JądraFunction jako narzędzi platformy agentów

Jeśli masz istniejący kod jądra semantycznego z KernelFunction wystąpieniami (z monitów lub metod), możesz przekonwertować je na narzędzia platformy Agent Framework przy użyciu .as_agent_framework_tool metody .

Ważne

Ta funkcja wymaga semantic-kernel wersji 1.38 lub nowszej.

Używanie funkcji jądra z szablonu monitu

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)

Używanie polecenia KernelFunction z metody

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)

Używanie magazynu wektorów z create_search_function

Można również użyć integracji Semantic Kernel VectorStore z platformą Agent Framework. Metoda create_search_function z kolekcji magazynu wektorów zwraca element KernelFunction , który można przekonwertować na narzędzie Platformy agentów.

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)

Ten wzorzec współdziała z dowolnym łącznikiem Semantic Kernel VectorStore (Azure AI Search, Qdrant, Pinecone itp.), co umożliwia korzystanie z istniejącej infrastruktury wyszukiwania wektorów za pomocą agentów platformy Agent Framework.

Ta warstwa zgodności umożliwia stopniowe migrowanie kodu z semantycznego jądra do struktury agentów, ponowne używanie istniejących KernelFunction implementacji przy jednoczesnym wykorzystaniu uproszczonych wzorców tworzenia i wykonywania agenta programu Agent Framework.

6. Wywołanie agenta bez przesyłania strumieniowego

Kluczowe różnice można zobaczyć w nazwach metod z invoke do run, zwracanych typów (na przykład AgentRunResponse) i parametrów.

Jądro semantyczne

Wywołanie bez przesyłania strumieniowego używa wzorca iteratora asynchronicznego do zwracania wielu komunikatów agenta.

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

I była metoda wygody, aby uzyskać ostateczną odpowiedź:

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

Struktura agenta

Uruchomienie bez przesyłania strumieniowego zwraca pojedynczy element AgentRunResponse z odpowiedzią agenta, która może zawierać wiele komunikatów. Wynik tekstowy przebiegu jest dostępny w systemie response.text lub str(response). Wszystkie komunikaty utworzone w ramach odpowiedzi są zwracane na response.messages liście. Może to obejmować komunikaty wywołania narzędzi, wyniki funkcji, aktualizacje rozumowania i końcowe wyniki.

agent = ...

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

7. Wywołanie przesyłania strumieniowego agenta

Kluczowe różnice w nazwach metod od invoke do run_stream, zwracane typy (AgentRunResponseUpdate) i parametry.

Jądro semantyczne

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)

Struktura agenta

Podobny wzorzec interfejsu API przesyłania strumieniowego z kluczową różnicą, że zwraca AgentRunResponseUpdate obiekty, w tym więcej informacji związanych z agentem na aktualizację.

Zwracana jest cała zawartość utworzona przez dowolną usługę bazową agenta. Końcowy wynik agenta jest dostępny przez połączenie update wartości w jedną odpowiedź.

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)

Można to zrobić nawet bezpośrednio:

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. Konfiguracja opcji

Problem: Konfiguracja opcji złożonych w semantycznym jądrze

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)

Rozwiązanie: uproszczone opcje w strukturze agentów

Struktura agenta umożliwia przekazywanie wszystkich parametrów bezpośrednio do odpowiednich metod, dzięki czemu nie trzeba importować żadnych dodatkowych elementów ani tworzyć żadnych obiektów opcji, chyba że chcesz. Wewnętrznie używa ChatOptions obiektu i ChatClientsChatAgents, który można również utworzyć i przekazać, jeśli chcesz. Jest to również tworzone w elemecie ChatAgent , aby przechowywać opcje i można je zastąpić na wywołanie.

agent = ...

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

Uwaga / Notatka

Powyższe elementy są specyficzne dla elementu ChatAgent, ponieważ inni agenci mogą mieć różne opcje, wszystkie powinny akceptować messages jako parametr, ponieważ jest on zdefiniowany w elemecie AgentProtocol.

Dalsze kroki