Descripción de las funciones nativas
Las funciones nativas son funciones escritas en código nativo que pueden ser llamadas por el SDK del núcleo semántico en su aplicación. Son útiles para realizar tareas que los grandes modelos lingüísticos (LLM) no pueden hacer por sí solos. Puedes pensar en una función nativa como una aptitud que la aplicación puede realizar.
En módulos posteriores, aprenderá a usar el kernel semántico para invocar automáticamente las funciones nativas que cree y combinar la lógica con avisos al LLM. Combinar servicios de finalización de chat con aptitudes funcionales le permite crear un agente de inteligencia artificial que pueda realizar una amplia gama de tareas. Pero por ahora, vamos a centrarnos en el diseño de funciones nativas.
Las funciones nativas tienen un formato determinado y una estructura de archivos recomendada que usará el kernel. Las funciones nativas deben usar el KernelFunction
decorador en sus definiciones. También usan un Description
campo para parámetros. Por ejemplo:
[KernelFunction, Description("Convert an amount of currency to USD")]
public static string ConvertCurrency(
[Description("The currency")] string currency,
[Description("The amount")] double amount)
{
// Code to convert currency
}
Puede importar las funciones nativas en el kernel como complemento. Las clases que contienen funciones nativas deben colocarse en un directorio "Plugins". Las funciones relacionadas deben colocarse en el mismo archivo para mantener el código organizado. También puede usar subdirectorios en el directorio "Plugins" para organizar aún más el código.
Por ejemplo, supongamos que tiene una aplicación de lista de tareas pendientes. Un usuario quiere completar un elemento de su lista de tareas pendientes. El modelo de lenguaje amplio (LLM) no puede acceder directamente a la lista de tareas pendientes del usuario, pero puede escribir una función nativa para acceder a la lista y marcar un elemento como completo. Por ejemplo, el archivo de lista de tareas pendientes puede contener lo siguiente:
{
"todoList": [
{
"task": "Complete coding exercise",
"completed": false
},
{
"task": "Practice Mandarin",
"completed": false
},
{
"task": "Buy groceries",
"completed": false
}
]
}
Puede crear un archivo TodoListPlugin.cs
en el directorio 'Plugins' con algún código para marcar la tarea completada:
using System.ComponentModel;
using System.Text.Json;
using System.Text.Json.Nodes;
using Microsoft.SemanticKernel;
public class TodoListPlugin
{
[KernelFunction, Description("Mark a todo list item as complete")]
public static string CompleteTask([Description("The task to complete")] string task)
{
// Read the JSON file
string jsonFilePath = $"{Directory.GetCurrentDirectory()}/todo.txt";
string jsonContent = File.ReadAllText(jsonFilePath);
// Parse the JSON content
JsonNode todoData = JsonNode.Parse(jsonContent);
// Find the task and mark it as complete
JsonArray todoList = (JsonArray) todoData["todoList"];
foreach (JsonNode taskNode in todoList)
{
if (taskNode["task"].ToString() == task)
{
taskNode["completed"] = true;
break;
}
}
// Save the modified JSON back to the file
File.WriteAllText(jsonFilePath, JsonSerializer.Serialize(todoData));
return $"Task '{task}' marked as complete.";
}
}
Observe el decorador KernelFunction
en la función CompleteTask
. Este decorador indica al kernel que se puede acceder a esta función. El decorador Description
indica al kernel lo que hace la función. La función acepta task
como una cadena. Las variables de las funciones de kernel deben incluir una descripción que explique cuál es la variable. Esta función también devuelve una cadena que permite al usuario saber que la tarea se marcó como completada.
En el archivo Program.cs
, puede importar y llamar a esta función nativa de forma similar a cómo llamaría a uno de los complementos integrados. Por ejemplo:
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Plugins.Core;
var builder = Kernel.CreateBuilder();
builder.AddAzureOpenAIChatCompletion(
"your-deployment-name",
"your-endpoint",
"your-api-key",
"deployment-model");
var kernel = builder.Build();
kernel.ImportPluginFromType<TodoListPlugin>();
var result = await kernel.InvokeAsync<string>(
"TodoListPlugin",
"CompleteTask",
new() {{ "task", "Buy groceries" }}
);
Console.WriteLine(result);
En este ejemplo, kernel.InvokeAsync
se llama a con el nombre del complemento, el nombre de la función y los argumentos. El task
argumento se establece en "Comprar comestibles". La función marcará la tarea como completada en el archivo de lista de tareas pendientes y devolverá un mensaje al usuario.
Ahora el agente de inteligencia artificial puede ayudar al usuario a completar tareas en su lista de tareas pendientes. Opcionalmente, puede elegir indicar el tipo de valor devuelto de la función en la llamada InvokeAsync
. De lo contrario, se devuelve un objeto FunctionResult
.
En el ejercicio siguiente, practicará la creación de sus propios complementos con funciones nativas.