Informazioni sulle funzioni native
Le funzioni native sono funzioni scritte in codice nativo che possono essere chiamate dall'SDK Kernel semantico in un'applicazione. Sono utili per eseguire attività che i modelli linguistici di grandi dimensioni (LLM) non possono eseguire autonomamente. È possibile pensare a una funzione nativa come a una competenza che l'applicazione può eseguire.
Nei moduli successivi si apprenderà come usare il kernel semantico per richiamare automaticamente le funzioni native create e combinare la logica con le richieste al modello linguistico di grandi dimensioni. La combinazione di servizi di completamento chat con competenze funzionali consente di creare un agente di intelligenza artificiale in grado di eseguire un'ampia gamma di attività. Ma per il momento viene illustrata la progettazione delle funzioni native.
Le funzioni native hanno un formato specifico e una struttura di file consigliata per l'uso da parte del kernel. Le funzioni native devono usare l'elemento Decorator KernelFunction
nelle relative definizioni. Usano anche un campo Description
per i parametri. Ad esempio:
[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
}
È possibile importare le funzioni native nel kernel come plug-in. Le classi contenenti funzioni native devono essere inserite in una directory "Plugins". Le funzioni correlate devono essere inserite nello stesso file per mantenere il codice organizzato. È anche possibile utilizzare sottodirectory all'interno della directory "Plugins" per organizzare ulteriormente il codice.
Si supponga, ad esempio, di avere un'applicazione di elenco attività. Un utente vuole completare un elemento del proprio elenco attività. Il modello linguistico di grandi dimensioni (LLM) non può accedere direttamente all'elenco attività dell'utente, ma è possibile scrivere una funzione nativa per accedere all'elenco e contrassegnare un elemento come completo. Ad esempio, il file di elenco attività potrebbe contenere quanto segue:
{
"todoList": [
{
"task": "Complete coding exercise",
"completed": false
},
{
"task": "Practice Mandarin",
"completed": false
},
{
"task": "Buy groceries",
"completed": false
}
]
}
È possibile creare un file TodoListPlugin.cs
nella directory 'Plugins' con del codice per contrassegnare l'attività come completata:
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.";
}
}
Si noti l'elemento Decorator KernelFunction
nella funzione CompleteTask
. Questo elemento Decorator indica al kernel che è possibile accedere alla funzione. L'elemento Decorator Description
comunica al kernel cosa fa la funzione. La funzione accetta task
come stringa. Le variabili delle funzioni del kernel devono includere una descrizione che indichi una spiegazione della variabile. La funzione restituisce anche una stringa che informa l'utente che l'attività è stata contrassegnata come completata.
Nel file Program.cs
è possibile importare e chiamare questa funzione nativa esattamente come quando si usano i plug-in predefiniti. Ad esempio:
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);
In questo esempio, kernel.InvokeAsync
viene chiamato con il nome del plug-in, il nome della funzione e gli argomenti. L'argomento task
è impostato su "Buy groceries". La funzione contrassegnerà l'attività come completata nel file di elenco attività e restituirà un messaggio all'utente.
A questo punto, l'agente di intelligenza artificiale può aiutare l'utente a completare le attività nell'elenco attività. Facoltativamente, è possibile scegliere di indicare il tipo restituito della funzione nella chiamata InvokeAsync
. In caso contrario, viene restituito un oggetto FunctionResult
.
Nell'esercizio successivo si proverà a creare plug-in personalizzati con funzioni native.