CSharp AI Esempi semplici
From Aino Wiki
Contents
Introduzione
ATTENZIONE, il seguente esempio funziona solo se l'applicazione Console ha accesso ad Internet altrimenti si otterrà l'errore:
No such host is known. (api.openai.com:443)
Queasto a prescindere dal fatto che il modello dell'AI sia o meno rafforzato dall'History cioè da un minimo di conoscenza fornita localmente... l'AI non riesce a "ragionare".
Esempi
La premessa è che ci si sia registrati su OpenAI, e si aggiunga la libreria OpenAI.
La registrazione produrrà una "API Key" da utilizzare negli esempi seguenti o per le proprie applicazioni. A scopo di test si userà la versione free.
Esempio chat
Da video da Microsoft vs Youtube Stephen Toub, segue una applicazione console che interagisce come in una chat.
Step 1
In questa versione si fa una semplice domanda cablata bel codice e mostra la risposta da ChatGPT.
Usare la API key di OpenAI ottenuta dopo la registrazione utente.
Precondizione è l'installazione, attraverso NuGet manager, della libreria OpenAI:
Questo codice funziona sia con le librerie .Net Framework 4.* e sia con .Net 8 (il codice originale della Demo è in .Net 8).
using OpenAI; //By OpenAIOfficial, attualmente alla versione 2.1.0 using OpenAI.Chat; using System; using System.ClientModel; using System.Threading.Tasks; namespace CA_AI_Test_01 { internal class Program { static async Task Main(string[] args) { //Per usufruire del servizio OpenAI è necessario registrarsi e generare una chiave API OpenAIClient client = new OpenAIClient(new ApiKeyCredential("sk-proj-************************************************************************************************************************************************************")); //La chiave API può essere letta da un file di configurazione o da una variabile d'ambiente come nel seguente istruzione commentata //OpenAIClient client = new OpenAIClient(new ApiKeyCredential(Environment.GetEnvironmentVariable("AI:OpenAPI:ApiKey"))); ChatClient chatClient = client.GetChatClient("gpt-4o-mini"); //La domanda è fatta in italiano che produrrà risposta in italiano ClientResult<ChatCompletion> result = await chatClient.CompleteChatAsync("Di che colore è il cielo?"); if (result != null && result.Value.Content.Count > 0) { Console.WriteLine(result.Value.Content[0].Text); // <-- Risposta accessibile così } Console.ReadLine(); //Attesa della pressione di un tasto } } }
Prestare attenzione alla natura dell'oggetto "response" così strutturato:
Step 2
Chat interattiva di domanda digitata dall'utente e risposta specifica dall'AI.
In questa versione occorre installare il package NuGet Microsoft.SemanticKernel (es. ver. 1.48.0).
Semantic Kernel (SK) è un SDK leggero che consente l'integrazione di modelli linguistici di grandi dimensioni (LLM) per l'AI con linguaggi di programmazione convenzionali.
NOTE
- Purtroppo il seguente codice funziona solo con .Net 8 in quanto per la versione .Net Framework 4.* c'è un baco di incompatibilità tra librerie (L'errore strano e fuorviante è: "Unable to find a version of 'Azure.AI.OpenAI' that is compatible with 'Microsoft.SemanticKernel.Connectors.AzureOpenAI 1.48.0 constraint: Azure.AI.OpenAI (= 2.2.0-beta.4)'.").
- L'installazione di Microsoft.SemanticKernel comporta automaticamente l'installazione di: Azure.AI.OpenAI, Azure.Core.
using System.Configuration; // Per ottenere "AI_OpenAPI_ApiKey" dal file di configurazione App.config using Microsoft.SemanticKernel.ChatCompletion; // Per utilizzare il sistema di Chat domanda risposta verso una AI using Microsoft.SemanticKernel.Connectors.OpenAI; // Per interrogare il modello dell'AI OpenAI namespace CA_AI_Test02 { public class Program { private static string AI_OpenAPI_ApiKey { get { string strTmp = string.Empty; if (ConfigurationManager.AppSettings["AI_OpenAPI_ApiKey"] != null) { strTmp = ConfigurationManager.AppSettings["AI_OpenAPI_ApiKey"]!; // Use null-forgiving operator to suppress CS8602 } return strTmp; } } static async Task Main(string[] args) { IChatCompletionService chatService = new OpenAIChatCompletionService("gpt-4o-mini", AI_OpenAPI_ApiKey); while (true) { Console.Write("Q: "); string? userMessage = Console.ReadLine(); if (string.IsNullOrEmpty(userMessage)) { break; } Console.WriteLine(await chatService.GetChatMessageContentAsync(userMessage)); } } } }
Step 3
Versione della chat con conservazione dello stato. In questo caso se si inseriscono delle informazioni queste non si perdono ma costituiranno un contesto presente sinché la applicazione console funziona.
using System.Configuration; // Per ottenere "AI_OpenAPI_ApiKey" dal file di configurazione App.config using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.ChatCompletion; // Per utilizzare il sistema di Chat domanda risposta verso una AI using Microsoft.SemanticKernel.Connectors.OpenAI; // Per interrogare il modello dell'AI OpenAI namespace CA_AI_Test02 { public class Program { private static string AI_OpenAPI_ApiKey { get { string strTmp = string.Empty; if (ConfigurationManager.AppSettings["AI_OpenAPI_ApiKey"] != null) { strTmp = ConfigurationManager.AppSettings["AI_OpenAPI_ApiKey"]!; // Use null-forgiving operator to suppress CS8602 } return strTmp; } } static async Task Main(string[] args) { IChatCompletionService chatService = new OpenAIChatCompletionService("gpt-4o-mini", AI_OpenAPI_ApiKey); ChatHistory chatHistory = new ChatHistory(); // Conserverà lo stato della conversazione while (true) { Console.Write("Q: "); string? userMessage = Console.ReadLine(); if (string.IsNullOrEmpty(userMessage)) { break; } chatHistory.AddUserMessage(userMessage); // Aggiunge il messaggio dell'utente alla cronologia ChatMessageContent messageContent = await chatService.GetChatMessageContentAsync(chatHistory); chatHistory.Add(messageContent); // Aggiungi la risposta dell'AI alla cronologia Console.WriteLine(messageContent); } } } }
Versione con conservazione dello stato ma anche integrazione di informazioni esterne mediante funzioni, questa caratteristica grazie all'uso del "kernel" ed il comportamento adattativo usando le funzioni.
Ad es. si può chiedere: "Che differenza di età c'è tra Luigi e Mario"?
using System.Configuration; // Per ottenere "AI_OpenAPI_ApiKey" dal file di configurazione App.config using Microsoft.Extensions.DependencyInjection; using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.ChatCompletion; // Per utilizzare il sistema di Chat domanda risposta verso una AI using Microsoft.SemanticKernel.Connectors.OpenAI; // Per interrogare il modello dell'AI OpenAI namespace CA_AI_Test02 { public class Program { private static string AI_OpenAPI_ApiKey { get { string strTmp = string.Empty; if (ConfigurationManager.AppSettings["AI_OpenAPI_ApiKey"] != null) { strTmp = ConfigurationManager.AppSettings["AI_OpenAPI_ApiKey"]!; // Use null-forgiving operator to suppress CS8602 } return strTmp; } } static async Task Main(string[] args) { ServiceCollection c = new(); c.AddOpenAIChatCompletion("gpt-4o-mini", AI_OpenAPI_ApiKey); c.AddKernel(); // Aggiunge abilità di eseguire funzioni estensive ad es per acquisire conoscenza integrativa IServiceProvider services = c.BuildServiceProvider(); Kernel kernel = services.GetRequiredService<Kernel>(); // Kernel è il cuore del sistema di AI kernel.ImportPluginFromType<Demographics>(); // Importa le funzioni del plugin Demographics PromptExecutionSettings settings = new OpenAIPromptExecutionSettings() { ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions, }; IChatCompletionService chatService = services.GetRequiredService<IChatCompletionService>(); ChatHistory chatHistory = new(); // Conserverà lo stato della conversazione while (true) { Console.Write("Q: "); string? userMessage = Console.ReadLine(); if (string.IsNullOrEmpty(userMessage)) { break; } chatHistory.AddUserMessage(userMessage); // Aggiunge il messaggio dell'utente alla cronologia //Si collega al modello usando la history, i settings (con riferimento al comportamento automatico nel //richiamo delle funzioni) e il kernel (per richiamare le funzioni definite nel plugin Demographics) ChatMessageContent messageContent = await chatService.GetChatMessageContentAsync(chatHistory, settings, kernel); chatHistory.Add(messageContent); // Aggiungi la risposta dell'AI alla cronologia Console.WriteLine(messageContent); } } } class Demographics { [KernelFunction] public int GetPersonAge(string name) { return name switch { "Mario" => 35, "Luigi" => 40, "Peach" => 30, _ => 0 }; } } }
Logging
E' possibile moitorare le operazioni compiute dall'AI nel processo di risposta. Dopo aver aggiunto il riferimento al Kernel dell'AI alla collezione di servizi utilizzabili aggiungiamo la visualizzazione sulla console degli eventi salienti dell'elaborazione. ATTENZIONE, in particolare si evidenzieranno il token utilizzati in elaborazione così da fare i conti sulla spesa di utilizzo della AI.
PURTROPPO L'istruzione, metodo .AddLogging(), da aggiungere non funziona !!!
ServiceCollection c = new(); c.AddOpenAIChatCompletion("gpt-4o-mini", AI_OpenAPI_ApiKey); c.AddKernel(); //------------------- c.AddLogging(b => b.AddConsole().SetMinimumLevel(LogLevel.Trace)); //NON FUNZIONA rispetto l'esempio di codice //------------------- IServiceProvider services = c.BuildServiceProvider();
Step 4
E' possibile integrare la conoscenza dell'AI aprendo ai motori di ricerca sul WEB. Purtroppo riporto il codice dal tutorial come aggiungere questo riferimento ma NON FUNZIONA in quanto manca qualcosa e non so cosa....
Kernel kernel = services.GetRequiredService<Kernel>(); // Kernel è il cuore del sistema di AI kernel.ImportPluginFromType<Demographics>(); // Importa le funzioni del plugin Demographics kernel.ImportPluginFromObject(new WebSearchEnginePlugin("WebSearchEnginePlugin")); // Importa il plugin WebSearchEnginePlugin MA NON FUNZIONA
Da Microsoft [1] ma non funziona per il Semantic Model 1.48.0
using Microsoft.SemanticKernel.Data; using Microsoft.SemanticKernel.Plugins.Web.Bing; // Create a kernel with OpenAI chat completion IKernelBuilder kernelBuilder = Kernel.CreateBuilder(); kernelBuilder.AddOpenAIChatCompletion( modelId: "gpt-4o", apiKey: "<Your OpenAI API Key>"); Kernel kernel = kernelBuilder.Build(); // Create a text search using Bing search var textSearch = new BingTextSearch(apiKey: "<Your Bing API Key>"); // Build a text search plugin with Bing search and add to the kernel var searchPlugin = textSearch.CreateWithSearch("SearchPlugin"); kernel.Plugins.Add(searchPlugin); // Invoke prompt and use text search plugin to provide grounding information var query = "What is the Semantic Kernel?"; var prompt = "{{SearchPlugin.Search $query}}. {{$query}}"; KernelArguments arguments = new() { { "query", query } }; Console.WriteLine(await kernel.InvokePromptAsync(prompt, arguments));
Materiale
Mappa e Link
Visual Studio | MS SQL | Dizionario
Parole chiave: