Implementare agenti di intelligenza artificiale con GitHub Copilot SDK
Questa unità illustra i modelli di implementazione principali per la creazione di un agente di intelligenza artificiale usando GitHub Copilot SDK. Questi modelli si applicano a qualsiasi scenario dell'agente. Gli esempi di codice usano C# e .NET, ovvero la piattaforma usata nell'esercizio del modulo.
Configurare il client GitHub Copilot SDK
Il primo passaggio consiste nel creare un'istanza CopilotClient che gestisce la connessione al server dell'interfaccia della riga di comando di Copilot. In genere, il client viene registrato come servizio singleton nell'applicazione.
Installare i pacchetti necessari
Aggiungere GitHub Copilot SDK e il pacchetto Microsoft.Extensions.AI (usato per le definizioni degli strumenti) al progetto:
dotnet add package GitHub.Copilot.SDK
dotnet add package Microsoft.Extensions.AI
Configurare il client
Creare un CopilotClient con CopilotClientOptions che controlla il comportamento di avvio e il log:
var client = new CopilotClient(new CopilotClientOptions
{
AutoStart = true,
LogLevel = "info"
});
L'opzione AutoStart indica all'SDK di avviare automaticamente il processo del server dell'interfaccia della riga di comando di Copilot al momento della creazione della prima sessione. L'opzione LogLevel controlla il livello di dettaglio dell'output di diagnostica dell'SDK.
Dopo aver creato il client, avviarlo:
await client.StartAsync();
Questo codice stabilisce la connessione al server dell'interfaccia della riga di comando e prepara il client per la creazione della sessione.
Definire gli strumenti dell'agente
Gli strumenti offrono all'agente la possibilità di interagire con i servizi back-end dell'applicazione. In GitHub Copilot SDK per .NET è possibile definire gli strumenti usando AIFunctionFactory.Create dal pacchetto Microsoft.Extensions.AI.
Creare un servizio di strumenti
Un modello comune consiste nel creare una classe di servizio dedicata che contiene tutti i metodi degli strumenti che l'agente può chiamare. Ogni metodo rappresenta un'azione che l'agente può eseguire:
public class SupportAgentTools
{
public async Task<string> GetOrderDetailsAsync(int orderId)
{
// Query the database for order information
var order = await _dbContext.Orders.FindAsync(orderId);
return order != null
? $"Order {orderId}: {order.ProductName}, Status: {order.Status}"
: "Order not found.";
}
public async Task<string> ProcessReturnAsync(int orderId, string reason)
{
// Business logic to process the return
var order = await _dbContext.Orders.FindAsync(orderId);
order.Status = "Return Initiated";
await _dbContext.SaveChangesAsync();
return $"Return initiated for order {orderId}.";
}
}
Registrare gli strumenti con l'SDK
Convertire i metodi del servizio in definizioni di strumenti che l'SDK può usare. Ogni strumento richiede un nome, una descrizione e le descrizioni dei parametri in modo che il modello di intelligenza artificiale comprenda quando e come usarlo:
var toolService = new SupportAgentTools(dbContext);
var tools = new List<AIFunction>
{
AIFunctionFactory.Create(
async ([Description("The order ID number")] int orderId) =>
await toolService.GetOrderDetailsAsync(orderId),
"get_order_details",
"Look up the status and details of a specific order."),
AIFunctionFactory.Create(
async ([Description("The order ID")] int orderId,
[Description("The reason for the return")] string reason) =>
await toolService.ProcessReturnAsync(orderId, reason),
"process_return",
"Process a return request for an order.")
};
Ogni AIFunctionFactory.Create chiamata accetta tre argomenti:
- Funzione lambda che avvolge il metodo del servizio, con attributi su ogni parametro.
- Nome dello strumento usato dal modello di intelligenza artificiale per fare riferimento allo strumento.
- Descrizione che consente al modello di comprendere quando chiamare lo strumento.
Gli [Description] attributi sui parametri sono importanti: indicano al modello di intelligenza artificiale cosa rappresenta ogni parametro, che consente al modello di fornire valori accurati quando si chiama lo strumento.
Creare e configurare una sessione
Le sessioni rappresentano singole conversazioni o contesti di attività. Si configura una sessione con il modello, il prompt di sistema, gli strumenti e altre impostazioni.
Configurare la sessione
Usare SessionConfig per specificare il comportamento della sessione:
var config = new SessionConfig
{
Model = "gpt-4.1",
SystemMessage = new SystemMessageConfig
{
Mode = SystemMessageMode.Replace,
Content = @"You are a customer support agent for an e-commerce company.
CAPABILITIES:
- Look up order details
- Process returns
RULES:
- Only assist with order-related inquiries
- Always verify order details before taking action
- Be polite and professional"
},
Tools = tools,
InfiniteSessions = new InfiniteSessionConfig
{
Enabled = false
}
};
Opzioni di configurazione chiave:
- Modello: specifica il modello di intelligenza artificiale da usare per questa sessione.
-
SystemMessage: definisce il ruolo e il comportamento dell'agente. Determina
Modese il prompt sostituisce il messaggio di sistema predefinito (Replace) o lo aggiunge (Append). - Strumenti: elenco di definizioni degli strumenti che l'agente può usare.
-
InfiniteSessions: controlla la compattazione automatica del contesto per conversazioni lunghe. Quando abilitata, è possibile regolare
BackgroundCompactionThresholdeBufferExhaustionThresholdper controllare quando si verifica la compattazione.
Creare la sessione
Crea una sessione dal client usando la tua configurazione.
var session = await client.CreateSessionAsync(config);
Gestione delle risposte con eventi
GitHub Copilot SDK usa un modello basato su eventi per la comunicazione. Dopo l'invio di un messaggio, si sottoscrive gli eventi per ricevere risposte e rilevare quando l'elaborazione è stata completata.
Iscriversi agli eventi di sessione
Usare il metodo session.On con criteri di ricerca per gestire tipi di evento diversi:
var responseBuilder = new StringBuilder();
var tcs = new TaskCompletionSource<string>();
session.On(evt =>
{
switch (evt)
{
case AssistantMessageEvent msg:
responseBuilder.Append(msg.Data.Content);
break;
case SessionIdleEvent:
tcs.SetResult(responseBuilder.ToString());
break;
case SessionErrorEvent err:
tcs.SetException(
new Exception($"Agent error: {err.Data.Message}"));
break;
}
});
Ogni tipo di evento ha uno scopo specifico:
- AssistantMessageEvent: contiene una parte del testo della risposta dell'agente. Questi messaggi vengono accumulati per compilare la risposta completa.
- SessionIdleEvent: segnala che l'agente ha terminato l'elaborazione, incluse tutte le chiamate agli strumenti. Questo evento indica che la risposta è stata completata.
-
SessionErrorEvent: indica che si è verificato un errore durante l'elaborazione. La
Data.Messageproprietà contiene la descrizione dell'errore.
Inviare un messaggio e attendere la risposta
Usare SendAsync con un MessageOptions oggetto per inviare la richiesta dell'utente all'agente:
await session.SendAsync(new MessageOptions
{
Prompt = "What is the status of order 12345?"
});
// Wait for the response with a timeout
var response = await tcs.Task.WaitAsync(TimeSpan.FromSeconds(30));
Il TaskCompletionSource modello illustrato qui consente di collegare il modello SDK basato su eventi con codice asincrono/await. Quando SessionIdleEvent viene attivato, completa l'attività con il testo di risposta accumulato.
Procedure consigliate per la gestione degli errori
La gestione degli errori affidabile è fondamentale per gli agenti di produzione.
Errori del gestore degli strumenti
Eseguire il wrapping dei gestori di strumenti in blocchi try-catch e restituire messaggi significativi anziché generare eccezioni. Quando uno strumento restituisce un messaggio di errore, il modello di intelligenza artificiale può interpretarlo e fornire una risposta utile all'utente:
AIFunctionFactory.Create(
async ([Description("The order ID")] int orderId) =>
{
try
{
return await toolService.GetOrderDetailsAsync(orderId);
}
catch (Exception ex)
{
return $"Error retrieving order: {ex.Message}";
}
},
"get_order_details",
"Look up the status and details of a specific order.")
Gestione degli errori a livello di sessione
Utilizzare SessionErrorEvent per intercettare gli errori durante l'elaborazione dell'agente. È anche possibile configurare l'hook della sessione OnErrorOccurred, che restituisce un valore ErrorHandling per controllare la risposta dell'agente agli errori.
- Riprova: tentare di nuovo l'operazione non riuscita.
- Ignora: Continuare l'elaborazione senza il risultato fallito.
- Interruzione: arrestare l'elaborazione e visualizzare l'errore.
Timeout
Impostare sempre un timeout quando si attendono le risposte. Nell'esempio precedente viene WaitAsync(TimeSpan.FromSeconds(30)) usato per evitare l'attesa illimitata se l'agente rileva un problema imprevisto.
Progettazione dei prompt di sistema
Il prompt di sistema è una delle decisioni di configurazione più importanti. Definisce chi è l'agente, cosa può fare e come deve comportarsi. Una richiesta di sistema ben strutturata include in genere:
- Definizione del ruolo: che cosa rappresenta l'agente, ad esempio "Si è un agente di supporto clienti per ContosoShop".
- Funzionalità: quali strumenti sono disponibili e cosa fanno.
- Indicazioni sul flusso di lavoro: come l'agente deve affrontare le attività (ad esempio, "Verificare sempre i dettagli dell'ordine prima di elaborare un ritorno").
- Regole e vincoli: i limiti che l'agente deve seguire (ad esempio, "Discutere solo gli argomenti correlati all'ordine" o "Inoltrare le richieste di rimborso oltre $100").
Mantenere mirato e specifico il prompt di sistema. Le istruzioni vaghe portano a comportamenti imprevedibili, mentre le regole eccessivamente restrittive possono rendere l'agente inutile.
Trasmettere risposte con eventi delta
Per applicazioni interattive come le interfacce utente della chat, è possibile trasmettere in streaming il token di risposta dell'agente in base al token anziché attendere il messaggio completo. Usare AssistantMessageDeltaEvent per acquisire ogni token parziale man mano che arriva:
session.On(evt =>
{
switch (evt)
{
case AssistantMessageDeltaEvent delta:
// Render each token as it arrives
Console.Write(delta.Data.DeltaContent);
break;
case SessionIdleEvent:
Console.WriteLine();
tcs.SetResult("Done");
break;
case SessionErrorEvent err:
tcs.SetException(
new Exception($"Agent error: {err.Data.Message}"));
break;
}
});
La DeltaContent proprietà contiene il frammento di testo incrementale. Lo streaming offre un'esperienza più reattiva perché gli utenti vedono la risposta man mano che si forma, anziché attendere che il modello generi l'intero messaggio.
Riassunto
GitHub Copilot SDK offre un framework potente per l'implementazione di agenti di intelligenza artificiale che possono ragionare, usare strumenti e gestire il contesto. Definendo le funzionalità dell'agente tramite strumenti, configurando sessioni con richieste di sistema chiare e gestendo risposte con eventi, è possibile creare agenti sofisticati che offrono valore aziendale reale. La gestione degli errori affidabile e la progettazione di richieste ponderate sono fondamentali per garantire che l'agente funzioni in modo affidabile ed efficace negli scenari di produzione. Nell'unità successiva si vedrà come applicare questi modelli di implementazione per creare un agente di supporto clienti di esempio usando GitHub Copilot SDK.