Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Cuando el modelo de IA recibe un mensaje que contiene una lista de funciones, puede elegir uno o varios de ellos para que la invocación complete el mensaje. Cuando el modelo elige una función, esta debe ser invocada por Kernel semántico.
El subsistema de llamada de función en kernel semántico tiene dos modos de invocación de función: automático y manual.
En función del modo de invocación, el kernel semántico realiza la invocación de funciones de un extremo a otro o proporciona al autor de la llamada el control sobre el proceso de invocación de función.
Invocación automática de funciones
La invocación de función automática es el modo predeterminado del subsistema de llamada a funciones semánticas del kernel. Cuando el modelo de IA elige una o varias funciones, el kernel semántico invoca automáticamente las funciones elegidas. Los resultados de estas invocaciones de función se agregan al historial de chat y se envían al modelo automáticamente en las solicitudes posteriores. A continuación, el modelo tiene motivos sobre el historial de chat, elige funciones adicionales si es necesario o genera la respuesta final. Este enfoque está totalmente automatizado y no requiere ninguna intervención manual del autor de la llamada.
Tip
La invocación de función automática es diferente del comportamiento de elección de función automática. El primero determina si las funciones deben invocarse automáticamente mediante Kernel semántico, mientras que esta última determina si el modelo de IA debe elegir automáticamente las funciones.
En este ejemplo se muestra cómo usar la invocación de función automática en kernel semántico. El modelo de IA decide a qué funciones llamar para completar el prompt, y Kernel semántico se encarga del resto y las invoca automáticamente.
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
Próximamente se agregarán más actualizaciones al SDK de Java.
Algunos modelos de IA admiten llamadas a funciones paralelas, donde el modelo elige varias funciones para la invocación. Esto puede ser útil en los casos en los que la invocación de funciones elegidas tarda mucho tiempo. Por ejemplo, la inteligencia artificial puede optar por recuperar las noticias más recientes y la hora actual simultáneamente, en lugar de realizar un recorrido de ida y vuelta por función.
El kernel semántico puede invocar estas funciones de dos maneras diferentes:
- Secuencialmente: las funciones se invocan una después de otra. Este es el comportamiento predeterminado.
-
Simultáneamente: las funciones se invocan al mismo tiempo. Esto se puede habilitar estableciendo la propiedad
FunctionChoiceBehaviorOptions.AllowConcurrentInvocationentrue, como se muestra en el ejemplo siguiente.
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));
A veces, un modelo puede elegir varias funciones para la invocación. Esto se conoce a menudo como llamada a funciones paralelas . Cuando el modelo de IA elige varias funciones, Kernel semántico las invocará simultáneamente.
Tip
Con el conector de OpenAI o Azure OpenAI, puede deshabilitar las llamadas paralelas a funciones haciendo lo siguiente:
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
)
Invocación manual de funciones
En los casos en los que el autor de la llamada quiere tener más control sobre el proceso de invocación de función, se puede usar la invocación de función manual.
Cuando se habilita la invocación de función manual, el kernel semántico no invoca automáticamente las funciones elegidas por el modelo de IA. En su lugar, devuelve una lista de funciones elegidas al autor de la llamada, que luego puede decidir qué funciones invocar, invocarlas secuencialmente o en paralelo, controlar excepciones, etc. Los resultados de la invocación de función deben agregarse al historial de chat y devolverse al modelo, lo que razonará sobre ellos y decidir si elegir funciones adicionales o generar una respuesta final.
En el ejemplo siguiente se muestra cómo usar la invocación manual de funciones.
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());
}
}
}
Nota:
Las clases FunctionCallContent y FunctionResultContent se usan para representar llamadas de función del modelo de IA y resultados de invocación de función de kernel semántica, respectivamente. Contienen información sobre la función elegida, como el identificador de función, el nombre y los argumentos, y los resultados de la invocación de función, como el identificador de llamada de función y el resultado.
En el ejemplo siguiente se muestra cómo usar la invocación manual de funciones con la API de finalización del chat de streaming. Tenga en cuenta el uso de la FunctionCallContentBuilder clase para compilar llamadas de función desde el contenido de streaming.
Debido al carácter de transmisión en flujo de la API, las llamadas a funciones también se envían en flujo. Esto significa que quien realiza la llamada debe construir las llamadas a funciones a partir del contenido en streaming antes de invocarlas.
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].
Nota:
Las clases FunctionCallContent y FunctionResultContent se usan para representar llamadas de función del modelo de IA y resultados de invocación de función de kernel semántica, respectivamente. Contienen información sobre la función elegida, como el identificador de función, el nombre y los argumentos, y los resultados de la invocación de función, como el identificador de llamada de función y el resultado.
Tip
Próximamente se agregarán más actualizaciones al SDK de Java.