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.
Una vez que tenga varios complementos, necesita una manera de que el agente de IA los use juntos para resolver la necesidad de un usuario. Aquí es donde entra en acción la planificación.
Al principio, el Kernel Semántico introdujo el concepto de planificadores que usaban indicaciones para solicitar a la inteligencia artificial que eligiera las funciones que se van a invocar. Sin embargo, como se introdujo el kernel semántico, OpenAI introdujo una manera nativa para que el modelo invoque o "llame" a una función: llamada a función. Otros modelos de inteligencia artificial como Gemini, Claude y Mistral han adoptado la llamada a funciones como una funcionalidad básica, lo que lo convierte en una característica admitida entre modelos.
Debido a estos avances, el kernel semántico ha evolucionado para usar la llamada a funciones como la forma principal de planear y ejecutar tareas.
Importante
La llamada a funciones solo está disponible en los modelos OpenAI que son 0613 o versiones posteriores. Si usa un modelo anterior (por ejemplo, 0314), esta funcionalidad devolverá un error. Se recomienda usar los modelos openAI más recientes para aprovechar esta característica.
¿Cómo la llamada a una función crea un "plan"?
En su forma más sencilla, la llamada a funciones es simplemente una manera de que una inteligencia artificial invoque una función con los parámetros correctos. Por ejemplo, un usuario quiere activar una bombilla. Suponiendo que la inteligencia artificial tiene el complemento adecuado, puede llamar a la función para encender la luz.
| Rol | Mensaje |
|---|---|
| 🔵 usuario | Active la luz n.º 1. |
| 🔴 Assistant (llamada de función) | Lights.change_state(1, { "isOn": true }) |
| 🟢 Herramienta | { "id": 1, "name": "Table Lamp", "isOn": true, "brightness": 100, "hex": "FF0000" } |
| 🔴 asistente | La lámpara está ahora activada |
Pero, ¿qué ocurre si el usuario no conoce el identificador de la luz? ¿O qué ocurre si el usuario quiere encender todas las luces? Aquí es donde entra en acción la planificación. Los modelos LLM actuales tienen la capacidad de llamar funciones de manera iterativa para satisfacer las necesidades de un usuario. Esto se logra mediante la creación de un bucle de comentarios en el que la inteligencia artificial puede llamar a una función, comprobar el resultado y, a continuación, decidir qué hacer a continuación.
Por ejemplo, un usuario puede pedir a la IA que "encienda/apague" una bombilla. La inteligencia artificial primero tendría que comprobar el estado de la bombilla antes de decidir si se activará o desactivará.
| Rol | Mensaje |
|---|---|
| 🔵 usuario | Por favor, enciende o apaga todas las luces |
| 🔴 Assistant (llamada de función) | Lights.get_lights() |
| 🟢 Herramienta | { "lights": [ { "id": 1, "name": "Table Lamp", "isOn": true, "brightness": 100, "hex": "FF0000" }, { "id": 2, "name": "Ceiling Light", "isOn": false, "brightness": 0, "hex": "FFFFFF" } ] } |
| 🔴 Assistant (llamada de función) |
Lights.change_state(1, { "isOn": false })
Lights.change_state(2, { "isOn": true })
|
| 🟢 Herramienta | { "id": 1, "name": "Table Lamp", "isOn": false, "brightness": 0, "hex": "FFFFFF" } |
| 🟢 Herramienta | { "id": 2, "name": "Ceiling Light", "isOn": true, "brightness": 100, "hex": "FF0000" } |
| 🔴 asistente | Las luces se han activado |
Nota:
En este ejemplo, también ha visto llamadas paralelas de funciones. Aquí es donde la inteligencia artificial puede llamar a varias funciones al mismo tiempo. Se trata de una característica eficaz que puede ayudar a la inteligencia artificial a resolver tareas complejas con mayor rapidez. Se agregó a los modelos openAI en 1106.
Bucle de planeación automática
Admitir llamadas a funciones sin kernel semántico es relativamente compleja. Tendría que escribir un bucle que lograra lo siguiente:
- Creación de esquemas JSON para cada una de las funciones
- Proporcionar al LLM el historial de chat anterior y los esquemas de función
- Analizar la respuesta de LLM para determinar si quiere responder con un mensaje o llamar a una función
- Si el LLM quiere llamar a una función, debería analizar el nombre de la función y los parámetros de la respuesta del LLM.
- Invocación de la función con los parámetros correctos
- Devuelve los resultados de la función para que LLM pueda determinar lo que debe hacer a continuación.
- Repita los pasos del 2 al 6 hasta que LLM decida que ha completado la tarea o necesita ayuda del usuario.
En Semantic Kernel, facilitamos el uso de llamadas a funciones mediante la automatización de este bucle. Esto le permite centrarse en la creación de los complementos necesarios para resolver las necesidades del usuario.
Nota:
Comprender cómo funciona el bucle de llamada de funciones es esencial para crear agentes de inteligencia artificial confiables y eficaces. Para obtener información detallada sobre cómo funciona el bucle, consulte el artículo sobre llamadas a funciones.
Utilización de la llamada automática de funciones
Para usar llamadas automáticas a funciones en kernel semántico, debe hacer lo siguiente:
- Registro del complemento con el kernel
- Creación de un objeto de configuración de ejecución que indica a la inteligencia artificial que llame automáticamente a funciones
- Invoca el servicio de finalización de chat con el historial de chat y el kernel
Sugerencia
En el ejemplo de código siguiente se usa el LightsPlugin elemento definido aquí.
using System.ComponentModel;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;
// 1. Create the kernel with the Lights plugin
var builder = Kernel.CreateBuilder().AddAzureOpenAIChatCompletion(modelId, endpoint, apiKey);
builder.Plugins.AddFromType<LightsPlugin>("Lights");
Kernel kernel = builder.Build();
var chatCompletionService = kernel.GetRequiredService<IChatCompletionService>();
// 2. Enable automatic function calling
OpenAIPromptExecutionSettings openAIPromptExecutionSettings = new()
{
FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
};
var history = new ChatHistory();
string? userInput;
do {
// Collect user input
Console.Write("User > ");
userInput = Console.ReadLine();
// Add user input
history.AddUserMessage(userInput);
// 3. Get the response from the AI with automatic function calling
var result = await chatCompletionService.GetChatMessageContentAsync(
history,
executionSettings: openAIPromptExecutionSettings,
kernel: kernel);
// Print the results
Console.WriteLine("Assistant > " + result);
// Add the message from the agent to the chat history
history.AddMessage(result.Role, result.Content ?? string.Empty);
} while (userInput is not null)
import asyncio
from semantic_kernel import Kernel
from semantic_kernel.connectors.ai import FunctionChoiceBehavior
from semantic_kernel.connectors.ai.chat_completion_client_base import ChatCompletionClientBase
from semantic_kernel.connectors.ai.open_ai import (
AzureChatCompletion,
AzureChatPromptExecutionSettings,
)
from semantic_kernel.contents import ChatHistory
from semantic_kernel.functions import kernel_function
async def main():
# 1. Create the kernel with the Lights plugin
kernel = Kernel()
kernel.add_service(AzureChatCompletion())
kernel.add_plugin(
LightsPlugin(),
plugin_name="Lights",
)
chat_completion: AzureChatCompletion = kernel.get_service(type=ChatCompletionClientBase)
# 2. Enable automatic function calling
execution_settings = AzureChatPromptExecutionSettings()
execution_settings.function_choice_behavior = FunctionChoiceBehavior.Auto()
# Create a history of the conversation
history = ChatHistory()
userInput = None
while True:
# Collect user input
userInput = input("User > ")
# Terminate the loop if the user says "exit"
if userInput == "exit":
break
# Add user input to the history
history.add_user_message(userInput)
# 3. Get the response from the AI with automatic function calling
result = await chat_completion.get_chat_message_content(
chat_history=history,
settings=execution_settings,
kernel=kernel,
)
# Print the results
print("Assistant > " + str(result))
# Add the message from the agent to the chat history
history.add_message(result)
# Run the main function
if __name__ == "__main__":
asyncio.run(main())
OpenAIAsyncClient client = new OpenAIClientBuilder()
.credential(new AzureKeyCredential(AZURE_CLIENT_KEY))
.endpoint(CLIENT_ENDPOINT)
.buildAsyncClient();
// Import the LightsPlugin
KernelPlugin lightPlugin = KernelPluginFactory.createFromObject(new LightsPlugin(),
"LightsPlugin");
// Create your AI service client
ChatCompletionService chatCompletionService = OpenAIChatCompletion.builder()
.withModelId(MODEL_ID)
.withOpenAIAsyncClient(client)
.build();
// Create a kernel with Azure OpenAI chat completion and plugin
Kernel kernel = Kernel.builder()
.withAIService(ChatCompletionService.class, chatCompletionService)
.withPlugin(lightPlugin)
.build();
// Add a converter to the kernel to show it how to serialise LightModel objects into a prompt
ContextVariableTypes
.addGlobalConverter(
ContextVariableTypeConverter.builder(LightModel.class)
.toPromptString(new Gson()::toJson)
.build());
// Enable planning
InvocationContext invocationContext = new InvocationContext.Builder()
.withReturnMode(InvocationReturnMode.LAST_MESSAGE_ONLY)
.withToolCallBehavior(ToolCallBehavior.allowAllKernelFunctions(true))
.build();
// Create a history to store the conversation
ChatHistory history = new ChatHistory();
// Initiate a back-and-forth chat
Scanner scanner = new Scanner(System.in);
String userInput;
do {
// Collect user input
System.out.print("User > ");
userInput = scanner.nextLine();
// Add user input
history.addUserMessage(userInput);
// Prompt AI for response to users input
List<ChatMessageContent<?>> results = chatCompletionService
.getChatMessageContentsAsync(history, kernel, invocationContext)
.block();
for (ChatMessageContent<?> result : results) {
// Print the results
if (result.getAuthorRole() == AuthorRole.ASSISTANT && result.getContent() != null) {
System.out.println("Assistant > " + result);
}
// Add the message from the agent to the chat history
history.addMessage(result);
}
} while (userInput != null && !userInput.isEmpty());
Cuando se usa la llamada automática a funciones, todos los pasos del bucle de planeación automática se controlan automáticamente y se agregan al ChatHistory objeto . Una vez completado el bucle de llamadas a funciones, puede inspeccionar el objeto ChatHistory para ver todas las llamadas a función que se han realizado y los resultados proporcionados por el Kernel Semántico.
¿Qué ha ocurrido con los planificadores Stepwise y Handlebars?
Los planificadores Stepwise y Handlebars han quedado en desuso y se han quitado del paquete de kernel semántico. Estos planificadores ya no se admiten en Python, .NET o Java.
Se recomienda usar la llamada a funciones, que es más eficaz y fácil de usar para la mayoría de los escenarios.
Para actualizar las soluciones existentes, siga nuestra Guía de migración de Stepwise Planner.
Sugerencia
Para los nuevos agentes de inteligencia artificial, utilice la función de llamadas en lugar de los planificadores obsoletos. Ofrece una mejor flexibilidad, compatibilidad con herramientas integradas y una experiencia de desarrollo más sencilla.
Pasos siguientes
Ahora que comprende cómo funcionan los planificadores en Semantic Kernel, puede obtener más información sobre cómo influir en su agente de IA para que planee y ejecute las tareas en nombre de los usuarios.