Bagikan melalui


Menjelajahi Kernel Semantik ChatCompletionAgent

Petunjuk / Saran

Dokumentasi API terperinci yang terkait dengan diskusi ini tersedia di:

Petunjuk / Saran

Dokumentasi API terperinci yang terkait dengan diskusi ini tersedia di:

Petunjuk / Saran

Dokumentasi API terperinci yang terkait dengan diskusi ini tersedia di:

Penyelesaian Percakapan pada Kernel Semantik

Penyelesaian Obrolan pada dasarnya adalah protokol untuk interaksi berbasis obrolan dengan model AI tempat riwayat obrolan dipertahankan dan disajikan ke model dengan setiap permintaan. Layanan Semantic Kernel AI menawarkan kerangka kerja terpadu untuk mengintegrasikan kemampuan penyelesaian obrolan dari berbagai model AI.

Sebuah ChatCompletionAgent dapat memanfaatkan salah satu dari layanan AI ini untuk menghasilkan respons, baik yang diarahkan ke pengguna atau agen lain.

Menyiapkan lingkungan pengembangan Anda

Untuk melanjutkan pengembangan ChatCompletionAgent, konfigurasikan lingkungan pengembangan Anda dengan paket yang sesuai.

Tambahkan paket Microsoft.SemanticKernel.Agents.Core ke proyek Anda:

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

Instal paket semantic-kernel:

pip install semantic-kernel

Penting

Tergantung pada Layanan AI mana yang Anda gunakan sebagai bagian dari ChatCompletionAgent, Anda mungkin perlu menginstal paket tambahan. Silakan periksa tambahan yang diperlukan di halaman berikut

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

Membuat ChatCompletionAgent

ChatCompletionAgent pada dasarnya didasarkan pada layanan kecerdasan buatan . Dengan demikian, membuat ChatCompletionAgent dimulai dengan membuat instans Kernel yang berisi satu atau beberapa layanan penyelesaian obrolan lalu membuat instans agen dengan referensi ke instans Kernel tersebut.

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

Ada dua cara untuk membuat ChatCompletionAgent:

1. Dengan menyediakan layanan penyelesaian obrolan secara langsung

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. Dengan membuat Kernel terlebih dahulu, menambahkan layanan ke dalamnya, lalu menyediakan kernel

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

Metode pertama berguna ketika Anda sudah menyiapkan layanan penyelesaian obrolan. Metode kedua bermanfaat ketika Anda memerlukan kernel yang mengelola beberapa layanan atau fungsionalitas tambahan.

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

Pilihan Layanan AI

Tidak berbeda dengan menggunakan layanan Semantic Kernel AI secara langsung, ChatCompletionAgent mendukung spesifikasi pemilih layanan. Pemilih layanan mengidentifikasi layanan AI mana yang akan ditargetkan saat Kernel berisi lebih dari satu.

Nota

Jika beberapa layanan AI ada dan tidak ada pemilih layanan yang disediakan, logika default yang sama diterapkan untuk agen yang akan Anda temukan saat menggunakan layanan AI di luar 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)
)

Fitur saat ini tidak tersedia di Java.

Berbicara dengan ChatCompletionAgent

Berkonversasi dengan ChatCompletionAgent Anda berdasarkan instance ChatHistory, tidak berbeda dengan berinteraksi dengan layanan AI Penyelesaian Obrolan .

Anda cukup memanggil agen dengan pesan pengguna Anda.

// 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)...
}

Anda juga dapat menggunakan AgentThread untuk melakukan percakapan dengan agen Anda. Di sini kita menggunakan ChatHistoryAgentThread.

ChatHistoryAgentThread juga dapat menerima objek opsional ChatHistory sebagai input melalui konstruktornya, jika melanjutkan percakapan sebelumnya. (tidak ditampilkan)

// 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)...
}

Ada beberapa cara untuk berkomunikasi dengan ChatCompletionAgent.

Yang paling mudah adalah memanggil dan menunggu get_response:

# Define agent
agent = ChatCompletionAgent(...)

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

Jika Anda ingin agen mempertahankan riwayat percakapan antar pemanggilan, Anda bisa meneruskannya ChatHistoryAgentThread sebagai berikut:


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

Memanggil metode invoke mengembalikan AsyncIterable dari 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 juga mendukung streaming, di mana metode invoke_stream akan mengembalikan AsyncIterable dari StreamingChatMessageContent:

# 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();

Anda juga dapat menggunakan AgentThread untuk melakukan percakapan dengan agen Anda. Di sini kita menggunakan ChatHistoryAgentThread.

ChatHistoryAgentThread juga dapat mengambil objek ChatHistory sebagai input, melalui konstruktornya, jika melanjutkan percakapan sebelumnya. (tidak ditampilkan)

// Define agent
ChatCompletionAgent agent = ...;

AgentThread thread = new ChatHistoryAgentThread();

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

Menangani Pesan Perantara dengan ChatCompletionAgent

Semantic Kernel ChatCompletionAgent dirancang untuk memanggil sebuah agen yang memenuhi kueri atau pertanyaan pengguna. Selama pemanggilan, agen dapat menjalankan alat untuk mendapatkan jawaban akhir. Untuk mengakses pesan perantara yang dihasilkan selama proses ini, penelepon dapat menyediakan fungsi panggilan balik yang menangani instans FunctionCallContent atau FunctionResultContent.

Dokumentasi callback untuk ChatCompletionAgent akan segera tersedia.

Mengonfigurasi on_intermediate_message panggilan balik dalam agent.invoke(...) atau agent.invoke_stream(...) memungkinkan pemanggil untuk menerima pesan perantara yang dihasilkan selama proses merumuskan respons akhir agen.

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

Berikut ini menunjukkan sampel output dari proses pemanggilan agen:

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!

Fitur saat ini tidak tersedia di Java.

Spesifikasi Deklaratif

Dokumentasi tentang menggunakan spesifikasi deklaratif akan segera hadir.

Penting

Fitur ini dalam tahap eksperimental. Fitur pada tahap ini sedang dalam pengembangan dan dapat berubah sebelum maju ke tahap pratinjau atau kandidat rilis.

ChatCompletionAgent dapat dibuat langsung dari spesifikasi deklaratif YAML. Pendekatan ini memungkinkan Anda untuk menentukan properti inti agen, instruksi, dan fungsi (plugin) yang tersedia dengan cara terstruktur dan portabel. Dengan menggunakan YAML, Anda dapat menjelaskan nama, deskripsi, perintah instruksi, set alat, dan parameter model agen dalam satu dokumen, membuat konfigurasi agen mudah diaudit dan direproduksi.

Nota

Alat atau fungsi apa pun yang ditentukan dalam YAML deklaratif harus sudah ada di instans Kernel pada saat agen dibuat. Agen pemuat tidak membuat fungsi baru dari spesifikasinya; sebaliknya, ia mencari plugin dan fungsi yang direferensikan oleh pengidentifikasinya di kernel. Jika plugin atau fungsi yang diperlukan tidak ada di kernel, akan terjadi kesalahan pada saat konstruksi agen.

Contoh: Membuat ChatCompletionAgent dari spesifikasi 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())

Fitur ini tidak tersedia.

Panduan Praktis

Untuk contoh lengkap untuk ChatCompletionAgent, lihat:

Langkah Selanjutnya