Risposta rapida: un chatbot è un completamento di chat più memoria. sgcWebSockets include un componente dedicato TsgcAIChat che conserva al posto tuo l'intera cronologia dei messaggi, così ogni turno viene inviato con la conversazione fino a quel momento e il modello può rispondere nel contesto. Trascina il componente, imposta la chiave API e il modello, poi chiama Chat per una risposta o ChatStream per un effetto di digitazione dal vivo, token per token. Cancellare la conversazione è una sola chiamata a ClearHistory.
Se hai già chiamato un LLM da Delphi, avrai probabilmente notato qualcosa di frustrante: poni una domanda di follow-up e il modello si comporta come se non ti avesse mai parlato prima. Non è un bug, è il modo in cui funziona un completamento one-shot. Trasformare tutto questo in un vero assistente conversazionale è la differenza tra un giocattolo e un chatbot, e si riduce a un'unica idea: la memoria.
Completamento one-shot vs un chatbot
Un'API LLM è stateless. Ogni richiesta è indipendente, quindi il modello conosce solo ciò che metti in quella richiesta. Una chiamata one-shot invia un singolo prompt:
// User: "What is the capital of France?" -> "Paris."
// User: "And its population?" -> "Population of what?"
La seconda domanda fallisce perché il server non ha conservato nulla della prima. Un chatbot risolve questo reinviando l'intero scambio ogni volta: il messaggio di sistema, ogni turno dell'utente e ogni risposta dell'assistant, in ordine. Il modello legge la cronologia, vede che "its" si riferisce a Parigi e risponde correttamente. Non ti serve un database o un server di sessione per questo, basta un elenco di messaggi che cresce con la conversazione. L'unico vero lavoro è costruire e mantenere quell'elenco, ed è esattamente ciò che il componente chatbot fa al posto tuo.
Il componente TsgcAIChat: memoria gestita per te
Anziché collegare a mano un array di messaggi, trascina un TsgcAIChat sulla tua form. Possiede internamente la cronologia della conversazione, aggiunge automaticamente ogni messaggio dell'utente e ogni risposta dell'assistant, e invia il contesto accumulato a ogni chiamata. Imposti il provider, la chiave API e un modello, poi basta chiamare Chat.
uses
sgcAI, sgcAI_Chat;
var
Bot: TsgcAIChat;
begin
Bot := TsgcAIChat.Create(nil);
Bot.Provider := aicpOpenAI;
Bot.ChatOptions.ApiKey := 'sk-...';
Bot.ChatOptions.Model := 'gpt-4o-mini';
Bot.SystemMessage := 'You are a concise assistant for Delphi developers.';
// Each call adds to the same conversation:
ShowMessage(Bot.Chat('What is the capital of France?')); // "Paris."
ShowMessage(Bot.Chat('And its population?')); // answers about Paris
end;
Poiché il componente ricorda il primo turno, il follow-up funziona e basta. Il SystemMessage imposta la persona dell'assistant ed è incluso in ogni richiesta. Quando vuoi una conversazione nuova, chiama Bot.ClearHistory; per ispezionare o persistere ciò che è stato detto, Bot.GetHistory restituisce l'elenco dei messaggi. Puoi anche limitare la memoria con MaxHistoryMessages in modo che una chat lunga non cresca illimitatamente (i turni più vecchi vengono potati automaticamente).
Lo stesso componente parla con ogni provider supportato da sgcWebSockets. Cambia Provider in aicpAnthropic, aicpGemini, aicpDeepSeek, aicpOllama, aicpGrok o aicpMistral, cambia il nome del modello, e il resto del codice del tuo chatbot resta identico. Consulta la pagina del componente ChatBot e l'hub dei componenti AI & LLM.
Trasmettere in streaming una risposta dal vivo
Aspettare diversi secondi che compaia una risposta completa dà una sensazione di lentezza. I chatbot reali trasmettono in streaming la risposta così le parole appaiono man mano che vengono generate, il familiare effetto di digitazione. TsgcAIChat espone questo tramite ChatStream più l'evento OnChatStream, che viene generato per ogni chunk di testo man mano che arriva.
Bot.OnChatStream := BotChatStream;
Bot.ChatStream('Explain WebSockets in two sentences.');
procedure TForm1.BotChatStream(Sender: TObject; const aChunk: string;
var Cancel: Boolean);
begin
Memo1.Text := Memo1.Text + aChunk; // append each token as it arrives
// set Cancel := True to stop the response early
end;
I chunk vengono consegnati in modo incrementale tramite i Server-Sent Events sotto il cofano, ma non tocchi mai l'impianto SSE. Quando lo stream termina, la risposta completa dell'assistant viene aggiunta alla cronologia proprio come in una chiamata non in streaming, così il turno successivo ha ancora il contesto completo. Il parametro Cancel ti permette di implementare un pulsante "interrompi la generazione". C'è anche OnChatMessage per il messaggio finale assemblato e OnChatError per far emergere eventuali errori dell'API.
Un chatbot vocale, dall'inizio alla fine
Se vuoi che l'assistant ascolti e parli, il componente TsgcAIOpenAIChatBot incapsula l'intero loop: cattura l'audio del microfono, lo trascrive con Whisper, invia il testo a Chat Completions e pronuncia la risposta tramite un provider di sintesi vocale. Collega un registratore audio e un motore di sintesi vocale, imposta la chiave e chiama Start.
uses
sgcAI, sgcAI_OpenAI_Audio_ChatBot,
sgcAI_AudioRecorder_MCI, sgcAI_TextToSpeech_System;
var
ChatBot: TsgcAIOpenAIChatBot;
begin
ChatBot := TsgcAIOpenAIChatBot.Create(nil);
ChatBot.OpenAIOptions.ApiKey := 'sk-...';
ChatBot.AudioRecorder := TsgcAudioRecorderMCI.Create(nil);
ChatBot.TextToSpeech := TsgcTextToSpeechSystem.Create(nil);
ChatBot.OnChatCompletion := ChatBotChatCompletion;
ChatBot.Start; // begin listening; Stop ends it
ChatBot.ChatAsUser('Tell me a joke'); // or push a turn programmatically
end;
L'evento OnChatCompletion ti fornisce il ruolo e il contenuto di ogni risposta, e OnTranscription ti permette di ispezionare o modificare ciò che è stato ascoltato prima che venga inviato. È la stessa idea conversazionale di TsgcAIChat, solo con l'audio a entrambe le estremità.
Preferisci gestire tu stesso l'elenco?
Non sei obbligato a usare il componente chatbot. Se vuoi il controllo completo, mantieni il tuo elenco di messaggi { role, content } e invialo a ogni chiamata con TsgcHTTP_API_OpenAI._CreateChatCompletion. Aggiungi il messaggio dell'utente, invia l'array, poi aggiungi nuovamente la risposta dell'assistant nello stesso elenco prima del turno successivo. È esattamente la contabilità che TsgcAIChat svolge internamente, quindi la maggior parte delle persone lascia che sia il componente a gestirla. L'API di livello inferiore è trattata nel tutorial API OpenAI in Delphi e nella pagina del componente OpenAI.
Come iniziare
Tutto ciò che trovi qui è incluso in sgcWebSockets. Scarica la prova gratuita, trascina un TsgcAIChat su una form, imposta la chiave API e il modello, e avrai un chatbot consapevole del contesto che risponde alle domande di follow-up in poche righe. Aggiungi ChatStream per l'effetto di digitazione dal vivo quando sei pronto.
Domande, feedback o aiuto per integrarlo nella tua app? Contattaci — riceverai una risposta dalle persone che hanno scritto il codice.
