İşlev Çağırma Modları

Yapay zeka modeli işlevlerin listesini içeren bir istem aldığında, istemleri tamamlamak üzere çağrı için bunlardan birini veya daha fazlasını seçebilir. Model tarafından bir işlev seçildiğinde Anlam Çekirdeği tarafından çağrılması gerekir.

Anlam Çekirdeği'ndeki işlev çağırma alt sisteminin iki işlev çağırma modu vardır: otomatik ve el ile.

Çağırma moduna bağlı olarak, Anlam Çekirdeği uçtan uca işlev çağırması yapar veya çağırana işlev çağırma işlemi üzerinde denetim verir.

Otomatik İşlev Çağırma

Otomatik işlev çağırma, Anlam Çekirdeği işlev çağırma alt sisteminin varsayılan modudur. Yapay zeka modeli bir veya daha fazla işlev seçtiğinde Anlam Çekirdeği seçilen işlevleri otomatik olarak çağırır. Bu işlev çağrılarının sonuçları sohbet geçmişine eklenir ve sonraki isteklerde modele otomatik olarak gönderilir. Model daha sonra sohbet geçmişiyle ilgili nedenler oluşturur, gerekirse ek işlevler seçer veya son yanıtı oluşturur. Bu yaklaşım tamamen otomatiktir ve arayandan el ile müdahale gerektirmez.

Tip

Otomatik işlev çağırma, otomatik işlev seçimi davranışından farklıdır. İlki, işlevlerin Semantik Çekirdek tarafından otomatik olarak çağrılıp çağrılmadığını belirlerken, ikincisi ise işlevlerin yapay zeka modeli tarafından otomatik olarak seçilip seçilmeyeceğini belirler.

Bu örnek, Anlam Çekirdeği'nde otomatik işlev çağırmanın nasıl kullanılacağını gösterir. Yapay zeka modeli, istemi tamamlamak için hangi işlevlerin çağrıleceğine karar verir ve Semantik Çekirdek geri kalanını yapar ve bunları otomatik olarak çağırır.

using Microsoft.SemanticKernel;

IKernelBuilder builder = Kernel.CreateBuilder(); 
builder.AddOpenAIChatCompletion("<model-id>", "<api-key>");
builder.Plugins.AddFromType<WeatherForecastUtils>();
builder.Plugins.AddFromType<DateTimeUtils>(); 

Kernel kernel = builder.Build();

// By default, functions are set to be automatically invoked.  
// If you want to explicitly enable this behavior, you can do so with the following code:  
// PromptExecutionSettings settings = new() { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto(autoInvoke: true) };  
PromptExecutionSettings settings = new() { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() }; 

await kernel.InvokePromptAsync("Given the current time of day and weather, what is the likely color of the sky in Boston?", new(settings));
from semantic_kernel.connectors.ai.function_choice_behavior import FunctionChoiceBehavior
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion
from semantic_kernel.connectors.ai.prompt_execution_settings import PromptExecutionSettings
from semantic_kernel.functions.kernel_arguments import KernelArguments
from semantic_kernel.kernel import Kernel

kernel = Kernel()
kernel.add_service(OpenAIChatCompletion())

# Assuming that WeatherPlugin and DateTimePlugin are already implemented
kernel.add_plugin(WeatherPlugin(), "WeatherPlugin")
kernel.add_plugin(DateTimePlugin(), "DateTimePlugin")

query = "What is the weather in Seattle today?"
arguments = KernelArguments(
    settings=PromptExecutionSettings(
        # By default, functions are set to be automatically invoked.
        # If you want to explicitly enable this behavior, you can do so with the following code:
        # function_choice_behavior=FunctionChoiceBehavior.Auto(auto_invoke=True),
        function_choice_behavior=FunctionChoiceBehavior.Auto(),
    )
)

response = await kernel.invoke_prompt(query, arguments=arguments)

Tip

Java SDK'sına yakında daha fazla güncelleştirme eklenecek.

Bazı yapay zeka modelleri, modelin çağrı için birden çok işlev seçtiği paralel işlev çağrısını destekler. Bu, seçilen işlevleri çağırmanın uzun sürdüğü durumlarda yararlı olabilir. Örneğin yapay zeka, işlev başına gidiş dönüş yapmak yerine en son haberleri ve geçerli saati aynı anda almayı seçebilir.

Semantik Çekirdek bu işlevleri iki farklı yolla çağırabilir:

  • Sırayla: İşlevler ardışık olarak çağrılır. Bu varsayılan davranıştır.
  • Eşzamanlı olarak: İşlevler aynı anda çağrılır. Bu, aşağıdaki örnekte gösterildiği gibi, FunctionChoiceBehaviorOptions.AllowConcurrentInvocation özelliğini true olarak ayarlayarak etkinleştirilebilir.
using Microsoft.SemanticKernel;

IKernelBuilder builder = Kernel.CreateBuilder(); 
builder.AddOpenAIChatCompletion("<model-id>", "<api-key>");
builder.Plugins.AddFromType<NewsUtils>();
builder.Plugins.AddFromType<DateTimeUtils>(); 

Kernel kernel = builder.Build();

// Enable concurrent invocation of functions to get the latest news and the current time.
FunctionChoiceBehaviorOptions options = new() { AllowConcurrentInvocation = true };

PromptExecutionSettings settings = new() { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto(options: options) }; 

await kernel.InvokePromptAsync("Good morning! What is the current time and latest news headlines?", new(settings));

Bazen bir model çağrı için birden çok işlev seçebilir. Bu genellikle paralel işlev çağrısı olarak adlandırılır. Yapay zeka modeli tarafından birden çok işlev seçildiğinde Semantik Çekirdek bunları eşzamanlı olarak çağırır.

Tip

OpenAI veya Azure OpenAI bağlayıcısıyla, aşağıdakileri yaparak paralel işlev çağrısını devre dışı bırakabilirsiniz:

from semantic_kernel.connectors.ai.open_ai import OpenAIChatPromptExecutionSettings
from semantic_kernel.connectors.ai.function_choice_behavior import FunctionChoiceBehavior

settings = OpenAIChatPromptExecutionSettings(
    function_choice_behavior=FunctionChoiceBehavior.Auto(),
    parallel_tool_calls=False
)

El ile İşlev Çağırma

Çağıranın işlev çağırma işlemi üzerinde daha fazla denetim sahibi olmak istediği durumlarda, el ile işlev çağırma kullanılabilir.

El ile işlev çağırma etkinleştirildiğinde Anlam Çekirdeği, yapay zeka modeli tarafından seçilen işlevleri otomatik olarak çağırmaz. Bunun yerine, seçilen işlevlerin listesini çağırana döndürür. Bu liste, hangi işlevlerin çağrılabileceğine karar verebilir, bunları sırayla veya paralel olarak çağırabilir, özel durumları işleyebilir vb. İşlev çağırma sonuçlarının sohbet geçmişine eklenmesi ve modele geri döndürülmesi gerekir; bu da bunları gerekçelendirmeli ve ek işlevler seçmeye veya son bir yanıt oluşturmaya karar verecektir.

Aşağıdaki örnekte, el ile işlev çağırmanın nasıl kullanılacağı gösterilmektedir.

using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;

IKernelBuilder builder = Kernel.CreateBuilder(); 
builder.AddOpenAIChatCompletion("<model-id>", "<api-key>");
builder.Plugins.AddFromType<WeatherForecastUtils>();
builder.Plugins.AddFromType<DateTimeUtils>(); 

Kernel kernel = builder.Build();

IChatCompletionService chatCompletionService = kernel.GetRequiredService<IChatCompletionService>();

// Manual function invocation needs to be enabled explicitly by setting autoInvoke to false.
PromptExecutionSettings settings = new() { FunctionChoiceBehavior = Microsoft.SemanticKernel.FunctionChoiceBehavior.Auto(autoInvoke: false) };

ChatHistory chatHistory = [];
chatHistory.AddUserMessage("Given the current time of day and weather, what is the likely color of the sky in Boston?");

while (true)
{
    ChatMessageContent result = await chatCompletionService.GetChatMessageContentAsync(chatHistory, settings, kernel);

    // Check if the AI model has generated a response.
    if (result.Content is not null)
    {
        Console.Write(result.Content);
        // Sample output: "Considering the current weather conditions in Boston with a tornado watch in effect resulting in potential severe thunderstorms,
        // the sky color is likely unusual such as green, yellow, or dark gray. Please stay safe and follow instructions from local authorities."
        break;
    }

    // Adding AI model response containing chosen functions to chat history as it's required by the models to preserve the context.
    chatHistory.Add(result); 

    // Check if the AI model has chosen any function for invocation.
    IEnumerable<FunctionCallContent> functionCalls = FunctionCallContent.GetFunctionCalls(result);
    if (!functionCalls.Any())
    {
        break;
    }

    // Sequentially iterating over each chosen function, invoke it, and add the result to the chat history.
    foreach (FunctionCallContent functionCall in functionCalls)
    {
        try
        {
            // Invoking the function
            FunctionResultContent resultContent = await functionCall.InvokeAsync(kernel);

            // Adding the function result to the chat history
            chatHistory.Add(resultContent.ToChatMessage());
        }
        catch (Exception ex)
        {
            // Adding function exception to the chat history.
            chatHistory.Add(new FunctionResultContent(functionCall, ex).ToChatMessage());
            // or
            //chatHistory.Add(new FunctionResultContent(functionCall, "Error details that the AI model can reason about.").ToChatMessage());
        }
    }
}

Not

FunctionCallContent ve FunctionResultContent sınıfları sırasıyla yapay zeka modeli işlev çağrılarını ve Semantik Çekirdek işlevi çağırma sonuçlarını temsil etmek için kullanılır. Bunlar işlev kimliği, ad ve bağımsız değişkenler gibi seçilen işlevle ilgili bilgileri ve işlev çağrısı kimliği ve sonucu gibi işlev çağırma sonuçlarını içerir.

Aşağıdaki örnekte, akış sohbeti tamamlama API'siyle el ile işlev çağırmanın nasıl kullanılacağı gösterilmektedir. Akış içeriğinden işlev çağrıları oluşturmak için sınıfının kullanımına FunctionCallContentBuilder dikkat edin. API'nin akış yapısı nedeniyle işlev çağrıları da akışa eklenir. Bu, çağıranın çağırmadan önce akış içeriğinden işlev çağrılarını oluşturması gerektiği anlamına gelir.

using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;

IKernelBuilder builder = Kernel.CreateBuilder(); 
builder.AddOpenAIChatCompletion("<model-id>", "<api-key>");
builder.Plugins.AddFromType<WeatherForecastUtils>();
builder.Plugins.AddFromType<DateTimeUtils>(); 

Kernel kernel = builder.Build();

IChatCompletionService chatCompletionService = kernel.GetRequiredService<IChatCompletionService>();

// Manual function invocation needs to be enabled explicitly by setting autoInvoke to false.
PromptExecutionSettings settings = new() { FunctionChoiceBehavior = Microsoft.SemanticKernel.FunctionChoiceBehavior.Auto(autoInvoke: false) };

ChatHistory chatHistory = [];
chatHistory.AddUserMessage("Given the current time of day and weather, what is the likely color of the sky in Boston?");

while (true)
{
    AuthorRole? authorRole = null;
    FunctionCallContentBuilder fccBuilder = new ();

    // Start or continue streaming chat based on the chat history
    await foreach (StreamingChatMessageContent streamingContent in chatCompletionService.GetStreamingChatMessageContentsAsync(chatHistory, settings, kernel))
    {
        // Check if the AI model has generated a response.
        if (streamingContent.Content is not null)
        {
            Console.Write(streamingContent.Content);
            // Sample streamed output: "The color of the sky in Boston is likely to be gray due to the rainy weather."
        }
        authorRole ??= streamingContent.Role;

        // Collect function calls details from the streaming content
        fccBuilder.Append(streamingContent);
    }

    // Build the function calls from the streaming content and quit the chat loop if no function calls are found
    IReadOnlyList<FunctionCallContent> functionCalls = fccBuilder.Build();
    if (!functionCalls.Any())
    {
        break;
    }

    // Creating and adding chat message content to preserve the original function calls in the chat history.
    // The function calls are added to the chat message a few lines below.
    ChatMessageContent fcContent = new ChatMessageContent(role: authorRole ?? default, content: null);
    chatHistory.Add(fcContent);

    // Iterating over the requested function calls and invoking them.
    // The code can easily be modified to invoke functions concurrently if needed.
    foreach (FunctionCallContent functionCall in functionCalls)
    {
        // Adding the original function call to the chat message content
        fcContent.Items.Add(functionCall);

        // Invoking the function
        FunctionResultContent functionResult = await functionCall.InvokeAsync(kernel);

        // Adding the function result to the chat history
        chatHistory.Add(functionResult.ToChatMessage());
    }
}
from semantic_kernel.connectors.ai.function_choice_behavior import FunctionChoiceBehavior
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion
from semantic_kernel.connectors.ai.prompt_execution_settings import PromptExecutionSettings
from semantic_kernel.contents.chat_history import ChatHistory
from semantic_kernel.contents.function_call_content import FunctionCallContent
from semantic_kernel.contents.function_result_content import FunctionResultContent
from semantic_kernel.kernel import Kernel

kernel = Kernel()
chat_completion_service = OpenAIChatCompletion()

# Assuming that WeatherPlugin is already implemented
kernel.add_plugin(WeatherPlugin(), "WeatherPlugin")

settings = PromptExecutionSettings(
    function_choice_behavior=FunctionChoiceBehavior.Auto(auto_invoke=False),
)

chat_history = ChatHistory()
chat_history.add_user_message("What is the weather in Seattle on 10th of September 2024 at 11:29 AM?")

response = await chat_completion_service.get_chat_message_content(chat_history, settings, kernel=kernel)
function_call_content = response.items[0]
assert isinstance(function_call_content, FunctionCallContent)

# Need to add the response to the chat history to preserve the context
chat_history.add_message(response)

function = kernel.get_function(function_call_content.plugin_name, function_call_content.function_name)
function_result = await function(kernel, function_call_content.to_kernel_arguments())

function_result_content = FunctionResultContent.from_function_call_content_and_result(
    function_call_content, function_result
)

# Adding the function result to the chat history
chat_history.add_message(function_result_content.to_chat_message_content())

# Invoke the model again with the function result
response = await chat_completion_service.get_chat_message_content(chat_history, settings, kernel=kernel)
print(response)
# The weather in Seattle on September 10th, 2024, is expected to be [weather condition].

Not

FunctionCallContent ve FunctionResultContent sınıfları sırasıyla yapay zeka modeli işlev çağrılarını ve Semantik Çekirdek işlevi çağırma sonuçlarını temsil etmek için kullanılır. Bunlar işlev kimliği, ad ve bağımsız değişkenler gibi seçilen işlevle ilgili bilgileri ve işlev çağrısı kimliği ve sonucu gibi işlev çağırma sonuçlarını içerir.

Tip

Java SDK'sına yakında daha fazla güncelleştirme eklenecek.