Sdílet prostřednictvím


Zkoumání sémantického jádra ChatCompletionAgent

Návod

Podrobná dokumentace k rozhraní API související s touto diskuzí je k dispozici na adrese:

Návod

Podrobná dokumentace k rozhraní API související s touto diskuzí je k dispozici na adrese:

Návod

Podrobná dokumentace k rozhraní API související s touto diskuzí je k dispozici na adrese:

Dokončení chatu v sémantickém jádru

Dokončování chatu je v podstatě protokolem pro chatovou interakci s modelem AI, kde se udržuje historie chatu a prezentuje modelu s každou žádostí. Sémantické služby AI jádra nabízejí jednotnou architekturu pro integraci možností dokončování chatu různých modelů AI.

A ChatCompletionAgent může využít některou z těchto služeb AI k vygenerování odpovědí, ať už směrovaných na uživatele nebo jiného agenta.

Příprava vývojového prostředí

Pokud chcete pokračovat v vývoji ChatCompletionAgent, nakonfigurujte vývojové prostředí s příslušnými balíčky.

Přidejte do projektu balíček Microsoft.SemanticKernel.Agents.Core:

dotnet add package Microsoft.SemanticKernel.Agents.Core --prerelease

Nainstalujte balíček semantic-kernel:

pip install semantic-kernel

Důležité

V závislosti na tom, kterou službu AI používáte jako součást ChatCompletionAgentslužby , možná budete muset nainstalovat další balíčky. Na následující stránce zkontrolujte, jestli potřebujete další informace.

<dependency>
    <groupId>com.microsoft.semantic-kernel</groupId>
    <artifactId>semantickernel-agents-core</artifactId>
    <version>[LATEST]</version>
</dependency>

Vytvoření ChatCompletionAgent

ChatCompletionAgent je v podstatě založené na službách umělé inteligence . Vytvoření ChatCompletionAgent začíná vytvořením instance Kernel, která obsahuje jednu nebo více služeb pro dokončování chatu, a následným vytvořením instance agenta s odkazem na tuto instanci Kernel.

// Initialize a Kernel with a chat-completion service
IKernelBuilder builder = Kernel.CreateBuilder();

builder.AddAzureOpenAIChatCompletion(/*<...configuration parameters>*/);

Kernel kernel = builder.Build();

// Create the agent
ChatCompletionAgent agent =
    new()
    {
        Name = "SummarizationAgent",
        Instructions = "Summarize user input",
        Kernel = kernel
    };

Existují dva způsoby, jak vytvořit ChatCompletionAgent:

1. Poskytnutím služby pro dokončování chatu přímo

from semantic_kernel.agents import ChatCompletionAgent

# Create the agent by directly providing the chat completion service
agent = ChatCompletionAgent(
    service=AzureChatCompletion(),  # your chat completion service instance
    name="<agent name>",
    instructions="<agent instructions>",
)

2. Nejprve vytvořením jádra přidáte službu do ní a pak poskytnete jádro.

# Define the kernel
kernel = Kernel()

# Add the chat completion service to the kernel
kernel.add_service(AzureChatCompletion())

# Create the agent using the kernel
agent = ChatCompletionAgent(
  kernel=kernel, 
  name="<agent name>", 
  instructions="<agent instructions>",
)

První metoda je užitečná, když už máte připravenou službu dokončení chatu. Druhá metoda je užitečná, když potřebujete jádro, které spravuje více služeb nebo další funkce.

// Initialize a Kernel with a chat-completion service
var chatCompletion = OpenAIChatCompletion.builder()
        .withOpenAIAsyncClient(client) // OpenAIAsyncClient with configuration parameters
        .withModelId(MODEL_ID)
        .build();

var kernel = Kernel.builder()
        .withAIService(ChatCompletionService.class, chatCompletion)
        .build();

// Create the agent
var agent = ChatCompletionAgent.builder()
        .withKernel(kernel)
        .build();

Výběr služby AI

Stejně jako při přímém použití Semantic Kernel AI služeb, ChatCompletionAgent podporuje specifikaci selektoru služby. Selektor služby identifikuje, na kterou AI službu cílit, pokud Kernel obsahuje více než jednu službu.

Poznámka:

Pokud existuje více služeb AI a není k dispozici žádný selektor služeb, použije se stejná výchozí logika pro agenta, kterou byste našli při použití služeb AI mimo Agent Framework

IKernelBuilder builder = Kernel.CreateBuilder();

// Initialize multiple chat-completion services.
builder.AddAzureOpenAIChatCompletion(/*<...service configuration>*/, serviceId: "service-1");
builder.AddAzureOpenAIChatCompletion(/*<...service configuration>*/, serviceId: "service-2");

Kernel kernel = builder.Build();

ChatCompletionAgent agent =
    new()
    {
        Name = "<agent name>",
        Instructions = "<agent instructions>",
        Kernel = kernel,
        Arguments = // Specify the service-identifier via the KernelArguments
          new KernelArguments(
            new OpenAIPromptExecutionSettings() 
            { 
              ServiceId = "service-2" // The target service-identifier.
            })
    };
from semantic_kernel.connectors.ai.open_ai import (
    AzureChatCompletion,
    AzureChatPromptExecutionSettings,
)

# Define the Kernel
kernel = Kernel()

# Add the AzureChatCompletion AI Service to the Kernel
kernel.add_service(AzureChatCompletion(service_id="service1"))
kernel.add_service(AzureChatCompletion(service_id="service2"))

settings = AzureChatPromptExecutionSettings(service_id="service2")

# Create the agent
agent = ChatCompletionAgent(
  kernel=kernel, 
  name="<agent name>", 
  instructions="<agent instructions>",
  arguments=KernelArguments(settings=settings)
)

Funkce aktuálně není dostupná v Javě.

Hovory s ChatCompletionAgent

Konverzace s vaším ChatCompletionAgent je založena na instanci ChatHistory, která se nijak neliší od interakce s dokončením chatu služby AI.

Agenta můžete jednoduše vyvolat pomocí zprávy uživatele.

// Define agent
ChatCompletionAgent agent = ...;

// Generate the agent response(s)
await foreach (ChatMessageContent response in agent.InvokeAsync(new ChatMessageContent(AuthorRole.User, "<user input>")))
{
  // Process agent response(s)...
}

Ke konverzaci s agentem můžete použít také AgentThread. Zde používáme ChatHistoryAgentThread.

ChatHistoryAgentThread také může jako vstup použít volitelný objekt ChatHistory, a to prostřednictvím jeho konstruktoru, pokud obnoví předchozí konverzaci. (není zobrazeno)

// Define agent
ChatCompletionAgent agent = ...;

AgentThread thread = new ChatHistoryAgentThread();

// Generate the agent response(s)
await foreach (ChatMessageContent response in agent.InvokeAsync(new ChatMessageContent(AuthorRole.User, "<user input>"), thread))
{
  // Process agent response(s)...
}

Existuje několik způsobů, jak komunikovat s ChatCompletionAgent.

Nejjednodušší je volat a očekávat get_response:

# Define agent
agent = ChatCompletionAgent(...)

# Generate the agent response
response = await agent.get_response(messages="user input")
# response is an `AgentResponseItem[ChatMessageContent]` object

Pokud chcete, aby agent zachoval historii konverzací mezi vyvoláními, můžete mu ChatHistoryAgentThread předat následujícím způsobem:


# Define agent
agent = ChatCompletionAgent(...)

# Generate the agent response(s)
response = await agent.get_response(messages="user input")

# Generate another response, continuing the conversation thread from the first response.
response2 = await agent.get_response(messages="user input", thread=response.thread)
# process agent response(s)

Volání metody invoke vrátí hodnotu AsyncIterable typu AgentResponseItem[ChatMessageContent].

# Define agent
agent = ChatCompletionAgent(...)

# Define the thread
thread = ChatHistoryAgentThread()

# Generate the agent response(s)
async for response in agent.invoke(messages="user input", thread=thread):
  # process agent response(s)

ChatCompletionAgent také podporuje streamování, přičemž metoda invoke_stream vrací AsyncIterableStreamingChatMessageContent:

# Define agent
agent = ChatCompletionAgent(...)

# Define the thread
thread = ChatHistoryAgentThread()

# Generate the agent response(s)
async for response in agent.invoke_stream(messages="user input", thread=thread):
  # process agent response(s)
ChatCompletionAgent agent = ...;

// Generate the agent response(s)
agent.invokeAsync(new ChatMessageContent<>(AuthorRole.USER, "<user input>")).block();

Ke konverzaci s agentem můžete použít také AgentThread. Zde používáme ChatHistoryAgentThread.

Objekt ChatHistoryAgentThread může také převzít ChatHistory jako vstup prostřednictvím jeho konstruktoru, pokud obnoví předchozí konverzaci. (není zobrazeno)

// Define agent
ChatCompletionAgent agent = ...;

AgentThread thread = new ChatHistoryAgentThread();

// Generate the agent response(s)
agent.invokeAsync(new ChatMessageContent<>(AuthorRole.USER, "<user input>"), thread).block();

Zpracování přechodných zpráv pomocí ChatCompletionAgent

Sémantické jádro ChatCompletionAgent je navrženo tak, aby použilo agenta, který zodpovídá dotazy nebo otázky uživatelů. Během vyvolání může agent spouštět nástroje, které odvozují konečnou odpověď. Pro přístup k přechodným zprávám vytvořeným během tohoto procesu mohou volající poskytnout funkci zpětného volání, která zpracovává instance FunctionCallContent nebo FunctionResultContent.

Dokumentace ke zpětnému volání pro tuto ChatCompletionAgent bude dostupná brzy.

Konfigurace zpětného on_intermediate_message volání uvnitř agent.invoke(...) nebo agent.invoke_stream(...) umožňuje volajícímu přijímat přechodné zprávy generované během procesu formulace konečné odpovědi agenta.

import asyncio
from typing import Annotated

from semantic_kernel.agents.chat_completion.chat_completion_agent import ChatCompletionAgent, ChatHistoryAgentThread
from semantic_kernel.connectors.ai.open_ai.services.azure_chat_completion import AzureChatCompletion
from semantic_kernel.contents import FunctionCallContent, FunctionResultContent
from semantic_kernel.contents.chat_message_content import ChatMessageContent
from semantic_kernel.functions import kernel_function


# Define a sample plugin for the sample
class MenuPlugin:
    """A sample Menu Plugin used for the concept sample."""

    @kernel_function(description="Provides a list of specials from the menu.")
    def get_specials(self) -> Annotated[str, "Returns the specials from the menu."]:
        return """
        Special Soup: Clam Chowder
        Special Salad: Cobb Salad
        Special Drink: Chai Tea
        """

    @kernel_function(description="Provides the price of the requested menu item.")
    def get_item_price(
        self, menu_item: Annotated[str, "The name of the menu item."]
    ) -> Annotated[str, "Returns the price of the menu item."]:
        return "$9.99"


# This callback function will be called for each intermediate message
# Which will allow one to handle FunctionCallContent and FunctionResultContent
# If the callback is not provided, the agent will return the final response
# with no intermediate tool call steps.
async def handle_intermediate_steps(message: ChatMessageContent) -> None:
    for item in message.items or []:
        if isinstance(item, FunctionCallContent):
            print(f"Function Call:> {item.name} with arguments: {item.arguments}")
        elif isinstance(item, FunctionResultContent):
            print(f"Function Result:> {item.result} for function: {item.name}")
        else:
            print(f"{message.role}: {message.content}")


async def main() -> None:
    agent = ChatCompletionAgent(
        service=AzureChatCompletion(),
        name="Assistant",
        instructions="Answer questions about the menu.",
        plugins=[MenuPlugin()],
    )

    # Create a thread for the agent
    # If no thread is provided, a new thread will be
    # created and returned with the initial response
    thread: ChatHistoryAgentThread = None

    user_inputs = [
        "Hello",
        "What is the special soup?",
        "How much does that cost?",
        "Thank you",
    ]

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


if __name__ == "__main__":
    asyncio.run(main())

Následující příklad ukazuje ukázkový výstup z procesu vyvolání agenta:

User: 'Hello'
AuthorRole.ASSISTANT: Hi there! How can I assist you today?
User: 'What is the special soup?'
Function Call:> MenuPlugin-get_specials with arguments: {}
Function Result:> 
        Special Soup: Clam Chowder
        Special Salad: Cobb Salad
        Special Drink: Chai Tea
        for function: MenuPlugin-get_specials
AuthorRole.ASSISTANT: The special soup today is Clam Chowder. Would you like to know anything else from the menu?
User: 'How much does that cost?'
Function Call:> MenuPlugin-get_item_price with arguments: {"menu_item":"Clam Chowder"}
Function Result:> $9.99 for function: MenuPlugin-get_item_price
AuthorRole.ASSISTANT: The Clam Chowder costs $9.99. Would you like to know more about the menu or anything else?
User: 'Thank you'
AuthorRole.ASSISTANT: You're welcome! If you have any more questions, feel free to ask. Enjoy your day!

Funkce aktuálně není dostupná v Javě.

Deklarativní specifikace

Dokumentace k používání deklarativních specifikací bude brzy k dispozici.

Důležité

Tato funkce je v experimentální fázi. Funkce v této fázi jsou ve vývoji a před přechodem na fázi Preview nebo release candidate se můžou změnit.

ChatCompletionAgent lze instancovat přímo z YAML deklarativní specifikace. Tento přístup umožňuje definovat základní vlastnosti, pokyny a dostupné funkce agenta (pluginy) strukturovaným a přenosným způsobem. Pomocí YAML můžete popsat název, popis agenta, příkazový řádek, sadu nástrojů a parametry modelu v jednom dokumentu, aby bylo možné snadno auditovat a reprodukovat konfiguraci agenta.

Poznámka:

Všechny nástroje nebo funkce zadané v deklarativním jazyce YAML už musí existovat v instanci jádra v okamžiku vytvoření agenta. Zavaděč agenta nevytváří nové funkce na základě specifikace; místo toho vyhledává referencované pluginy a funkce podle jejich identifikátorů v jádru. Pokud v jádru není přítomen požadovaný modul plug-in nebo funkce, dojde během sestavování agentů k chybě.

Příklad: Vytvoření ChatCompletionAgent ze specifikace YAML

import asyncio
from typing import Annotated

from semantic_kernel import Kernel
from semantic_kernel.agents import AgentRegistry, ChatHistoryAgentThread
from semantic_kernel.agents.chat_completion.chat_completion_agent import ChatCompletionAgent
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion
from semantic_kernel.functions import kernel_function

# Define a plugin with kernel functions
class MenuPlugin:
    @kernel_function(description="Provides a list of specials from the menu.")
    def get_specials(self) -> Annotated[str, "Returns the specials from the menu."]:
        return """
        Special Soup: Clam Chowder
        Special Salad: Cobb Salad
        Special Drink: Chai Tea
        """

    @kernel_function(description="Provides the price of the requested menu item.")
    def get_item_price(
        self, menu_item: Annotated[str, "The name of the menu item."]
    ) -> Annotated[str, "Returns the price of the menu item."]:
        return "$9.99"

# YAML spec for the agent
AGENT_YAML = """
type: chat_completion_agent
name: Assistant
description: A helpful assistant.
instructions: Answer the user's questions using the menu functions.
tools:
  - id: MenuPlugin.get_specials
    type: function
  - id: MenuPlugin.get_item_price
    type: function
model:
  options:
    temperature: 0.7
"""

USER_INPUTS = [
    "Hello",
    "What is the special soup?",
    "What does that cost?",
    "Thank you",
]

async def main():
    kernel = Kernel()
    kernel.add_plugin(MenuPlugin(), plugin_name="MenuPlugin")

    agent: ChatCompletionAgent = await AgentRegistry.create_from_yaml(
        AGENT_YAML, kernel=kernel, service=OpenAIChatCompletion()
    )

    thread: ChatHistoryAgentThread | None = None

    for user_input in USER_INPUTS:
        print(f"# User: {user_input}")
        response = await agent.get_response(user_input, thread=thread)
        print(f"# {response.name}: {response}")
        thread = response.thread

    await thread.delete() if thread else None

if __name__ == "__main__":
    asyncio.run(main())

Tato funkce není k dispozici.

Návod

Kompletní příklad od začátku do konce pro ChatCompletionAgent najdete zde:

Další kroky