Costruire un agente AI in Delphi: function calling e uso degli strumenti MCP

· Componenti

Risposta rapida: un agente AI è semplicemente un modello linguistico che può chiamare il tuo codice. Descrivi un insieme di strumenti, il modello decide quando invocarne uno, la tua applicazione lo esegue e restituisce il risultato, e il modello prosegue da lì — in un loop finché il compito non è completato. sgcWebSockets ti offre due modi per costruirlo in Delphi o C++ Builder: il function calling del provider (il modello chiede di chiamare una delle tue funzioni tramite il componente OpenAI, Anthropic o Gemini) e MCP (l'aperto Model Context Protocol, in cui il tuo server espone strumenti che qualunque client o agente compatibile con MCP può scoprire e chiamare). Entrambi usano la stessa idea; scegli quello che si adatta a dove vive l'agente.

A volte si immagina un "agente" come un modello speciale. Non lo è. È un comune modello di chat più un piccolo loop di controllo nel tuo codice che gli permette di andare oltre la conversazione. Una volta che il modello può chiamare una funzione che interroga un database, legge un file o raggiunge un'API interna, smette di essere un chatbot e inizia a poter agire. I due percorsi seguenti differiscono solo per chi ospita gli strumenti.

Il loop dell'agente

Ogni agente, indipendentemente dal provider, segue lo stesso ciclo:

  1. Invia il messaggio dell'utente insieme a un elenco di definizioni di strumenti (nome, descrizione, parametri).
  2. Il modello o risponde in testo semplice, o replica "chiama lo strumento X con questi argomenti".
  3. Se chiede uno strumento, il tuo codice esegue il lavoro reale e restituisce il risultato.
  4. Il modello legge il risultato e o chiama un altro strumento o produce la risposta finale.
  5. Ripeti finché il modello non smette di chiedere strumenti.

Il modello non esegue mai nulla di per sé. Propone soltanto chiamate; il tuo codice Delphi resta in controllo di ciò che viene effettivamente eseguito, ed è questo che rende lo schema sicuro da mettere davanti a sistemi reali.

Percorso 1: function calling del provider

Il modo più diretto per dare a un singolo modello accesso al tuo codice è l'API di function calling propria del provider. Dichiari le funzioni disponibili, il modello ne sceglie una quando ne ha bisogno, e un evento viene generato nel tuo componente affinché tu possa fornire il risultato. Con il componente OpenAI definisci gli strumenti una volta sull'assistant, poi gestisci la chiamata:

Assistant := TsgcAIOpenAIAssistant.Create(nil);
Assistant.OpenAIOptions.ApiKey := 'sk-...';
Assistant.AssistantOptions.Name := 'Delphi Weather Bot';
Assistant.AssistantOptions.Instructions.Text :=
  'You are a weather bot. Use the provided functions to answer questions.';
Assistant.AssistantOptions.Model := 'gpt-4o';

// Describe the callable functions as JSON tool definitions
Assistant.AssistantOptions.Tools.Functions.Functions.Text :=
  '[{"type":"function","function":{"name":"get_current_temperature",' +
  '"description":"Get the current temperature for a specific location",' +
  '"parameters":{"type":"object","properties":{"location":{"type":"string"}},' +
  '"required":["location"]}}}]';

Quando il modello decide che gli serve un valore, il componente solleva OnFunctionCall. Ispezioni aRequest._Function._Name per sapere quale strumento è stato richiesto e scrivi la risposta in aResponse.Output — quel risultato viene rimandato direttamente al modello affinché possa completare la sua risposta:

procedure TForm1.AssistantFunctionCall(Sender: TObject;
  const aRequest: TsgcOpenAIClass_ToolCall;
  const aResponse: TsgcHTTPOpenAI_ToolCall_Response);
begin
  if aRequest._Function._Name = 'get_current_temperature' then
    aResponse.Output := 30
  else if aRequest._Function._Name = 'get_rain_probability' then
    aResponse.Output := 10;
end;

Quel gestore di evento è il loop dell'agente. Ogni volta che il modello chiede uno strumento, lo esegui e restituisci; il componente mantiene attiva la conversazione finché il modello non ha tutto ciò che gli serve. Questo percorso è ideale quando l'agente vive all'interno della tua applicazione e parla con un solo provider. La stessa forma è disponibile sui componenti Anthropic e Gemini, quindi non sei vincolato. Consulta la guida al function calling di OpenAI per l'esempio completo.

Percorso 2: strumenti MCP

Il function calling lega i tuoi strumenti a un modello in un'app. Il Model Context Protocol trasforma la stessa idea in un servizio riutilizzabile: la tua applicazione espone un insieme di strumenti su un endpoint JSON-RPC standard, e qualunque client o agente compatibile con MCP — un assistente IDE, un'app AI desktop o il tuo loop di agente — può connettersi, scoprire quegli strumenti e chiamarli. Scrivi lo strumento una volta; ogni host MCP può usarlo.

In sgcWebSockets il lato server è TsgcWSAPIServer_MCP. Lo colleghi a un server HTTP sgcWebSockets, registri gli strumenti con Tools.AddTool e gestisci la chiamata in arrivo in OnMCPRequestTool:

uses
  sgcWebSocket_Server, sgcAI, sgcAI_MCP_Classes, sgcAI_MCP_Server;

procedure TForm1.SetupMCPServer;
begin
  MCPServer.Server := Server;
  MCPServer.EndpointOptions.Endpoint := '/mcp';
  MCPServer.MCPOptions.ServerInfo.Name    := 'sgc-mcp-server';
  MCPServer.MCPOptions.ServerInfo.Version := '1.0.0';

  // Register a callable tool with a typed argument
  with MCPServer.Tools.AddTool('GetTemperature',
    'Get the actual temperature in a city.') do
    InputSchema.Properties.AddProperty('city', True);

  MCPServer.OnMCPRequestTool := MCPRequestTool;
  Server.Port   := 8080;
  Server.Active := True;
end;

Quando un client connesso chiama lo strumento, l'evento viene generato con oggetti di richiesta e risposta fortemente tipizzati. Leggi il nome dello strumento da aRequest.Params.Name e i suoi argomenti da aRequest.Params.Arguments, poi scrivi la risposta con aResponse.Result.Content.AddText:

procedure TForm1.MCPRequestTool(Sender: TObject;
  const aSession: TsgcAI_MCP_Session;
  const aRequest: TsgcAI_MCP_Request_ToolsCall;
  const aResponse: TsgcAI_MCP_Response_ToolsCall);
begin
  if aRequest.Params.Name = 'GetTemperature' then
    aResponse.Result.Content.AddText('The current temperature in ' +
      aRequest.Params.Arguments.Item[0].Value + ' is 22 Celsius');
end;

Il gestore svolge lo stesso lavoro dell'evento di function calling, ma ora lo strumento è raggiungibile da qualunque host MCP attraverso la rete. Poiché MCP è uno standard pubblicato, l'agente che guida la conversazione non deve essere stato scritto affatto da te. Approfondisci nella panoramica MCP e nella pagina del componente MCP Server.

Quale percorso usare?

Se vuoi…UsaComponente
Un agente che vive all'interno della tua app e parla con un solo providerFunction calling del providerTsgcAIOpenAIAssistant
Strumenti che qualunque client o agente compatibile con MCP può scoprire e chiamareServer MCPTsgcWSAPIServer_MCP
Chiamare strumenti ospitati dal server MCP di qualcun altroClient MCPTsgcWSAPIClient_MCP

I due non si escludono a vicenda. Un design comune è un agente in-app che usa il function calling del provider per i propri strumenti privati, connettendosi al contempo come client MCP a server di strumenti condivisi altrove nella tua organizzazione. Qualunque tu scelga, il loop che scrivi appare quasi identico, quindi passare dall'uno all'altro in seguito costa poco.

Come iniziare

Entrambi i percorsi sono inclusi in sgcWebSockets (il server e il client MCP sono componenti Enterprise). Scarica la prova gratuita, inserisci TsgcAIOpenAIAssistant per il function calling o TsgcWSAPIServer_MCP per un servizio MCP, collega l'evento dello strumento e avrai un agente in grado di agire sul tuo codice in poche righe. Esplora ogni blocco costitutivo per l'AI nell'hub dei componenti AI & LLM.

Domande o vuoi aiuto a progettare il tuo agente? Contattaci — riceverai una risposta dalle persone che hanno scritto il codice.

Correlati