Appeler un LLM depuis Delphi

Envoie un prompt depuis une application VCL, FMX ou console et récupère une réponse, d'un modèle hébergé comme OpenAI ou Anthropic Claude, ou d'un modèle qui tourne sur ta propre machine via Ollama. Cette page t'emmène d'une fiche vide à un appel qui fonctionne, puis aux trois sujets que tout projet rencontre ensuite : le streaming, l'appel d'outils et le choix entre un modèle hébergé et un modèle local.

OpenAI, Claude, Gemini, Grok, DeepSeek, Mistral, Ollama
Streaming via Server-Sent Events
De Delphi 7 à RAD Studio 13

Deux façons de faire l'appel

Il y a un composant de chat neutre vis-à-vis du fournisseur, et il y a un client REST dédié pour chaque fournisseur. Les deux sont livrés dans la même bibliothèque, tu peux donc commencer avec l'un et descendre vers l'autre sans changer de projet.

TsgcAIChat, une seule API pour tous les fournisseurs

Définis Provider, une clé API et un modèle, puis appelle Chat. Le composant construit le JSON du fournisseur, conserve l'historique de la conversation et renvoie le texte de l'assistant. Passer d'OpenAI à Claude, ou à un modèle Ollama local, tient en une seule affectation. Implémenté par TsgcAI_Chat dans l'unité sgcAI_Chat, et enregistré sur la palette sous le nom de TsgcAIChat.

Les clients REST par fournisseur

TsgcHTTP_API_OpenAI, TsgcHTTP_API_Anthropic et TsgcHTTP_API_Ollama exposent chaque API fournisseur en entier, y compris les parties qu'aucune couche neutre ne peut couvrir : entrée vision, entrée document, réflexion étendue, lots, fichiers, embeddings, génération d'images et transcription. Utilise-les quand tu as besoin d'un endpoint précis.

Édition et plateforme

Les clients IA et LLM sont une fonctionnalité Enterprise de sgcWebSockets, pas Standard et pas Professional, ou alors tu peux acheter le package sgcAI autonome.

La plateforme compte ici. Les trois clients REST compilent sur Windows, macOS, Linux, iOS et Android. TsgcAIChat non : il n'est compilé que pour Windows, donc sur un service Linux, une build macOS ou une cible mobile, tu appelles directement le client REST. Les exemples de cette page sont écrits pour que les deux voies fonctionnent.

Ton premier appel, en une dizaine de lignes

Dépose le composant, définis une clé et un modèle, envoie un prompt. Choisis l'onglet du fournisseur par lequel tu commences. Le dernier onglet ne demande aucune clé API, parce que le modèle tourne sur ta machine.

uChat.pas
uses
  Classes, SysUtils,
  // sgc
  sgcAI_Chat;

procedure TfrmMain.btnAskClick(Sender: TObject);
var
  oChat: TsgcAI_Chat;
begin
  oChat := TsgcAI_Chat.Create(nil);
  try
    oChat.Provider := aicpOpenAI;
    oChat.ChatOptions.ApiKey := GetApiKey;
    oChat.ChatOptions.Model := 'gpt-4o-mini';
    oChat.ChatOptions.MaxTokens := 1024;
    oChat.SystemMessage := 'You are a concise assistant inside a Delphi ERP.';

    memoAnswer.Lines.Text := oChat.Chat(memoPrompt.Lines.Text);
  finally
    oChat.Free;
  end;
end;

Changer de fournisseur tient en une ligne. Provider accepte aicpOpenAI, aicpAnthropic, aicpGemini, aicpDeepSeek, aicpOllama, aicpGrok et aicpMistral. Tout le reste de ton code reste en place.

Windows uniquement. TsgcAI_Chat et son composant de palette TsgcAIChat sont compilés pour Windows, Win32 et Win64. Sur macOS, Linux, iOS et Android, l'unité n'est pas compilée du tout, donc si ta cible est un service Linux ou une application mobile, utilise les clients REST des fournisseurs dans les trois autres onglets. Ceux-là n'ont aucune restriction de plateforme.

uOpenAI.pas
uses
  Classes, SysUtils,
  // sgc
  sgcHTTP_API_OpenAI;

var
  oOpenAI: TsgcHTTP_API_OpenAI;
begin
  oOpenAI := TsgcHTTP_API_OpenAI.Create(nil);
  try
    oOpenAI.OpenAIOptions.ApiKey := GetApiKey;

    // Shortcut: model plus one user message, raw JSON back
    memoAnswer.Lines.Text := oOpenAI._CreateChatCompletion(
      'gpt-4o', 'Say hello');
  finally
    oOpenAI.Free;
  end;
end;

Les méthodes préfixées d'un underscore sont des raccourcis chaîne qui renvoient le corps de réponse brut. Quand tu veux un objet déjà analysé, construis un TsgcOpenAIClass_Request_ChatCompletion et appelle CreateChatCompletion, montré plus bas sur cette page.

uClaude.pas
uses
  Classes, SysUtils,
  // sgc
  sgcHTTP_API_Anthropic;

var
  oAnthropic: TsgcHTTP_API_Anthropic;
begin
  oAnthropic := TsgcHTTP_API_Anthropic.Create(nil);
  try
    oAnthropic.AnthropicOptions.ApiKey := GetApiKey;
    oAnthropic.AnthropicOptions.AnthropicVersion := '2023-06-01';

    // Model, prompt, max tokens
    memoAnswer.Lines.Text := oAnthropic._CreateMessage(
      'claude-sonnet-4-20250514',
      'Summarise RFC 6455 in three bullet points.', 1024);
  finally
    oAnthropic.Free;
  end;
end;

Claude exige l'en-tête de version d'API, donc définis AnthropicVersion en plus de la clé. _CreateMessageWithSystem ajoute un prompt système, et _CountTokens chiffre le coût d'un prompt avant que tu ne l'envoies.

uOllama.pas
uses
  Classes, SysUtils,
  // sgc
  sgcHTTP_API_Ollama;

var
  oOllama: TsgcHTTP_API_Ollama;
begin
  oOllama := TsgcHTTP_API_Ollama.Create(nil);
  try
    // Local server, no API key required
    oOllama.OllamaOptions.Host := 'http://localhost:11434';

    // Which models are pulled on this machine?
    memoModels.Lines.Text := oOllama._GetTags;

    memoAnswer.Lines.Text := oOllama._CreateMessage(
      'llama3', 'Summarise this invoice in one line.');
  finally
    oOllama.Free;
  end;
end;

Host vaut par défaut http://localhost:11434, donc sur une installation par défaut tu peux le laisser tel quel. _PullModel télécharge un modèle, _GetTags liste ce qui est déjà sur le disque et _ShowModel lit ses détails.

Afficher la réponse au fur et à mesure

Un appel en une seule fois bloque jusqu'à ce que le modèle ait fini, ce qui, sur une réponse longue, donne l'impression que tout est planté. Le streaming livre la réponse par fragments, donc le texte apparaît dans ton memo pendant que le modèle réfléchit encore. C'est le point sur lequel la plupart des gens bloquent, voici donc ses deux niveaux.

Avec TsgcAIChat, les deltas déjà décodés

Appelle ChatStream au lieu de Chat et gère OnChatStream. Le composant demande au fournisseur une réponse en streaming, analyse chaque Server-Sent Event et te transmet aChunk, qui contient le nouveau texte et rien d'autre. Tu l'ajoutes, et c'est toute l'implémentation.

Chaque fournisseur diffuse une forme de JSON différente. OpenAI, DeepSeek, Ollama, Grok et Mistral mettent le texte dans choices[0].delta.content, Claude dans delta.text, Gemini plus profond encore dans candidates. TsgcAIChat sait déjà laquelle s'applique au fournisseur que tu as choisi, donc ton handler ne voit jamais de JSON.

Mets Cancel à True dans le handler pour arrêter une réponse qui s'emballe. La requête est abandonnée à ce moment-là, et aucun autre fragment n'arrive. Quand le flux se termine, le texte assemblé est ajouté à l'historique et renvoyé par ChatStream, et OnChatMessage se déclenche une fois avec la réponse complète.

uChatStream.pas
procedure TfrmMain.btnStreamClick(Sender: TObject);
begin
  FChat.Provider := aicpAnthropic;
  FChat.ChatOptions.ApiKey := GetApiKey;
  FChat.ChatOptions.Model := 'claude-sonnet-4-20250514';
  FChat.OnChatStream := OnChatStream;
  FChat.OnChatError := OnChatError;

  memoAnswer.Lines.Clear;
  FChat.ChatStream(memoPrompt.Lines.Text);
end;

procedure TfrmMain.OnChatStream(Sender: TObject;
  const aChunk: string; var Cancel: Boolean);
begin
  memoAnswer.Text := memoAnswer.Text + aChunk;
  Cancel := FUserPressedStop;
end;

procedure TfrmMain.OnChatError(Sender: TObject;
  const aError: string);
begin
  memoAnswer.Lines.Add('ERROR: ' + aError);
end;

Avec un client fournisseur, les événements bruts

Les clients REST font aussi du streaming. Affecte OnHTTPAPISSE et appelle le raccourci de streaming : _CreateMessageStream sur Claude et sur Ollama, et sur OpenAI un TsgcOpenAIClass_Request_ChatCompletion avec Stream mis à True. L'événement te donne aEvent, le nom du Server-Sent Event, et aData, la charge utile de cet événement, exactement telle que le fournisseur l'a envoyée.

À ce niveau, tu analyses le JSON toi-même, et c'est bien l'intérêt : tu vois les deltas d'appels d'outils, les raisons d'arrêt, les enregistrements d'usage et tout ce que le fournisseur met sur le fil. Les lectures réseau partielles sont déjà réassemblées pour toi, donc un événement coupé sur deux lectures TCP arrive quand même entier, et le JSON délimité par retours à la ligne d'Ollama est livré par le même événement.

Les terminateurs diffèrent selon le fournisseur. OpenAI clôt avec le littéral [DONE], Claude avec un événement nommé message_stop. Gère les deux si ton code vise les deux.

uRawStream.pas
procedure TfrmMain.FormCreate(Sender: TObject);
begin
  FAnthropic := TsgcHTTP_API_Anthropic.Create(nil);
  FAnthropic.AnthropicOptions.ApiKey := GetApiKey;
  FAnthropic.AnthropicOptions.AnthropicVersion := '2023-06-01';
  FAnthropic.OnHTTPAPISSE := HandleSSE;
  FAnthropic.OnHTTPAPIException := HandleException;
end;

procedure TfrmMain.btnStreamClick(Sender: TObject);
begin
  memoRaw.Lines.Clear;
  FAnthropic._CreateMessageStream(
    'claude-sonnet-4-20250514',
    'Write a haiku about Object Pascal.', 1024);
end;

procedure TfrmMain.HandleSSE(Sender: TObject;
  const aEvent, aData: string; var Cancel: Boolean);
begin
  if (aEvent = 'message_stop') or (aData = '[DONE]') then
    Exit;
  memoRaw.Lines.Add(aEvent + ': ' + aData);
end;

procedure TfrmMain.HandleException(Sender: TObject;
  E: Exception);
begin
  memoRaw.Lines.Add('ERROR: ' + E.Message);
end;

Les threads. Chat et ChatStream sont synchrones, donc les appeler directement depuis un clic de bouton fige la fiche pendant toute la durée de la requête. Sur Delphi 2010 et supérieur, ChatAsync exécute l'appel sur un thread de travail et renvoie un IsgcFuture<string>. Enchaîne ThenProc pour le résultat et OnError pour les échecs, et appelle Cancel pour abandonner une requête en cours. Le callback ThenProc est distribué sur le thread principal, donc tu peux y toucher l'UI directement.

Laisse le modèle appeler ton code Pascal

L'appel d'outils, aussi appelé function calling, est la façon dont un modèle demande à ton application de chercher une information ou d'effectuer une action. Tu décris la fonction avec un JSON Schema, le modèle répond avec les arguments qu'il veut, tu exécutes le code Pascal et tu renvoies le résultat. C'est le mécanisme derrière tout assistant utile à l'intérieur d'une application métier.

Claude, avec des objets outils typés

Construis un TsgcAnthropicClass_Request_Messages, attache une ou plusieurs entrées TsgcAnthropicClass_Request_Tool et appelle CreateMessage. Chaque outil porte un Name, une Description et un InputSchema, qui est le JSON Schema de ses arguments.

La réponse est un TsgcAnthropicClass_Response_Messages dont le Content est un tableau de blocs. Un bloc dont le ContentType vaut 'tool_use' porte le nom de l'outil dans Name, les arguments dans Input et un Id. Exécute ta fonction, puis envoie un message de suivi contenant un TsgcAnthropicClass_Request_Content_Block avec ContentType mis à 'tool_result', le même ToolUseId et ta réponse dans Content. Définis IsError quand l'appel a échoué, pour que le modèle puisse se rattraper au lieu de deviner.

Attention à la propriété des objets : la requête Anthropic ne possède pas les messages et les outils que tu attaches, donc libère-les toi-même, comme dans l'exemple.

uToolUse.pas
var
  oRequest: TsgcAnthropicClass_Request_Messages;
  oMessage: TsgcAnthropicClass_Request_Message;
  oTool: TsgcAnthropicClass_Request_Tool;
  oMessages: TsgcAnthropicArray_Request_Messages;
  oTools: TsgcAnthropicArray_Request_Tools;
  oResponse: TsgcAnthropicClass_Response_Messages;
  i: Integer;
begin
  oRequest := TsgcAnthropicClass_Request_Messages.Create;
  try
    oRequest.Model := 'claude-sonnet-4-20250514';
    oRequest.MaxTokens := 4096;

    oMessage := TsgcAnthropicClass_Request_Message.Create;
    oMessage.Role := 'user';
    oMessage.Content := 'What is the stock of SKU 8841?';
    SetLength(oMessages, 1);
    oMessages[0] := oMessage;
    oRequest.Messages := oMessages;

    oTool := TsgcAnthropicClass_Request_Tool.Create;
    oTool.Name := 'get_stock';
    oTool.Description := 'Read the on-hand stock for a SKU';
    oTool.InputSchema :=
      '{"type":"object","properties":{"sku":{"type":"string",' +
      '"description":"The product code"}},"required":["sku"]}';
    SetLength(oTools, 1);
    oTools[0] := oTool;
    oRequest.Tools := oTools;

    oResponse := FAnthropic.CreateMessage(oRequest);
    try
      for i := 0 to Length(oResponse.Content) - 1 do
        if oResponse.Content[i].ContentType = 'tool_use' then
          // .Name is the tool, .Input the JSON arguments,
          // .Id the value to echo back as ToolUseId
          RunTool(oResponse.Content[i].Name,
            oResponse.Content[i].Input, oResponse.Content[i].Id)
        else if oResponse.Content[i].ContentType = 'text' then
          memoAnswer.Lines.Add(oResponse.Content[i].Text);
    finally
      oResponse.Free;
    end;
  finally
    sgcFree(oMessage);
    sgcFree(oTool);
    sgcFree(oRequest);
  end;
end;

OpenAI, avec une requête typée

Même idée, forme différente. Remplis un TsgcOpenAIClass_Request_ChatCompletion, affecte le tableau Messages, mets tes définitions d'outils dans Tools sous forme de tableau JSON et, si tu veux, oriente le modèle avec ToolChoice. ParallelToolCalls contrôle si le modèle peut demander plusieurs outils à la fois, et ResponseFormat force la réponse en JSON quand tu as besoin de l'analyser.

CreateChatCompletion renvoie un TsgcOpenAIClass_Response_ChatCompletiondéjà analysé. Lis la réponse dans Choices[0]._Message.Content, les appels demandés dans Choices[0]._Message.ToolCalls, la raison pour laquelle le modèle s'est arrêté dans Choices[0].FinishReason, et ce que cela a coûté dans Usage.PromptTokens, Usage.CompletionTokens et Usage.TotalTokens. Contrairement à la requête Anthropic, celle-ci possède les objets message que tu attaches et les libère avec elle.

Les anciennes propriétés Functions et FunctionCall sont toujours là pour le code écrit contre la forme d'origine du function calling d'OpenAI.

uTypedRequest.pas
var
  oRequest: TsgcOpenAIClass_Request_ChatCompletion;
  oResponse: TsgcOpenAIClass_Response_ChatCompletion;
  oSystem, oUser: TsgcOpenAIClass_Request_Completion_Message;
  oMessages: TsgcOpenAIArray_Request_Completion_Messages;
begin
  oRequest := TsgcOpenAIClass_Request_ChatCompletion.Create;
  try
    oRequest.Model := 'gpt-4o';
    oRequest.MaxTokens := 1024;
    oRequest.Temperature := 0.2;

    oSystem := TsgcOpenAIClass_Request_Completion_Message.Create;
    oSystem.Role := 'system';
    oSystem.Content := 'You are a warehouse assistant.';

    oUser := TsgcOpenAIClass_Request_Completion_Message.Create;
    oUser.Role := 'user';
    oUser.Content := 'What is the stock of SKU 8841?';

    SetLength(oMessages, 2);
    oMessages[0] := oSystem;
    oMessages[1] := oUser;
    oRequest.Messages := oMessages;

    // Tool definitions as a JSON array
    oRequest.Tools :=
      '[{"type":"function","function":{"name":"get_stock",' +
      '"description":"Read the on-hand stock for a SKU",' +
      '"parameters":{"type":"object","properties":' +
      '{"sku":{"type":"string"}},"required":["sku"]}}}]';
    oRequest.ToolChoice := 'auto';

    oResponse := FOpenAI.CreateChatCompletion(oRequest);
    try
      if Length(oResponse.Choices) > 0 then
      begin
        memoAnswer.Lines.Text := oResponse.Choices[0]._Message.Content;
        memoTools.Lines.Text := oResponse.Choices[0]._Message.ToolCalls;
        lblStop.Caption := oResponse.Choices[0].FinishReason;
      end;
      lblTokens.Caption := IntToStr(oResponse.Usage.TotalTokens);
    finally
      oResponse.Free;
    end;
  finally
    // frees the attached Messages too
    oRequest.Free;
  end;
end;

Modèle hébergé ou modèle local

Si tes prompts contiennent des fiches clients, des données médicales, des contrats ou quoi que ce soit couvert par un accord de traitement des données, ce n'est pas une question de performance, c'est une question de conformité. Voici la comparaison.

Hébergé, OpenAI ou Claude En local, Ollama
Où va le prompt Chez le fournisseur, en HTTPS, sous ses conditions Nulle part. La requête va vers http://localhost:11434
Identifiants Une clé API que tu dois garder hors du contrôle de version et hors du binaire Aucun par défaut. OllamaOptions.ApiKey existe pour une instance distante ou derrière un proxy
Qualité des réponses Les modèles les plus puissants disponibles aujourd'hui Bonne et en progrès, nettement derrière la frontière sur le raisonnement difficile
Coût Au token, pour toujours. Surveille Usage.TotalTokens Ton matériel, une seule fois. Un modèle utile réclame beaucoup de RAM ou un GPU
Latence Un aller-retour réseau, plus la mise en file d'attente du fournisseur aux heures chargées Pas de réseau. La vitesse est celle de ta machine
Hors ligne et réseau isolé Non Oui
Limites de débit et pannes Côté fournisseur. Utilise RetryOptions et respecte Retry-After Seulement ta propre capacité
Composant TsgcHTTP_API_OpenAI, TsgcHTTP_API_Anthropic TsgcHTTP_API_Ollama

Une réponse courante, c'est les deux. Comme TsgcAIChat place tous les fournisseurs derrière une seule API, tu peux router selon la classification des données à l'exécution : en local pour tout ce qui touche une fiche client, hébergé pour le reste. Le commutateur, c'est Provider, auquel s'ajoute ChatOptions.BaseUrl quand le fournisseur est Ollama.

if aContainsPersonalData then
begin
  FChat.Provider := aicpOllama;
  FChat.ChatOptions.BaseUrl := 'http://localhost:11434';
  FChat.ChatOptions.Model := 'llama3';
end
else
begin
  FChat.Provider := aicpOpenAI;
  FChat.ChatOptions.ApiKey := GetApiKey;
  FChat.ChatOptions.Model := 'gpt-4o-mini';
end;

memoAnswer.Lines.Text := FChat.Chat(memoPrompt.Lines.Text);

Les réglages qui comptent en production

Une démo qui marche sur ton bureau, ce n'est pas la même chose qu'un client qui survit à une limite de débit, à un modèle lent et à un ticket de support qui dit « ça s'est arrêté tout seul ».

Nouvelles tentatives et backoff

Chaque client porte un bloc RetryOptions avec : Enabled, Retries, Wait, Multiplier, MaxInterval, Jitter et HonorRetryAfter. Active-le et un échec transitoire est réessayé avec un backoff exponentiel au lieu de remonter en exception. HonorRetryAfter fait obéir le client à l'en-tête Retry-After du fournisseur plutôt que de deviner.

Délais d'attente

HttpOptions.ReadTimeout est celui qu'il faut augmenter. Une génération longue, surtout sur un modèle local, peut dépasser un délai de lecture HTTP par défaut et échouer au milieu d'une réponse qui se passait bien.

Journalisation

LogOptions.Enabled combiné à LogOptions.FileName écrit le trafic dans un fichier. Quand un prompt se comporte différemment en production, c'est le moyen le plus rapide de voir le JSON que ton code a réellement envoyé.

Historique de conversation

TsgcAIChat conserve l'échange et le rejoue à l'appel suivant, ce qui fait fonctionner une question de suivi. Plafonne-le avec MaxHistoryMessages pour qu'une longue session ne fasse pas grossir le prompt, et donc la facture, sans limite. ClearHistory repart de zéro, et GetHistory expose Count et les messages individuels.

Azure OpenAI

Définis OpenAIOptions.Provider à oapvAzure et renseigne AzureOptions.ResourceName, AzureOptions.DeploymentId et AzureOptions.APIVersion. Le reste de ton code ne change pas, ce qui compte quand les achats exigent que le trafic reste à l'intérieur de ton tenant Azure.

Erreurs et coupe-circuit

OnHTTPAPIException remonte les échecs des clients REST, et OnChatError fait de même pour TsgcAIChat. Une erreur HTTP arrive sous la forme d'une EsgcHTTPAPIProtocolException, qui descend toujours de EIdHTTPProtocolException et porte en plus les en-têtes de la réponse. CircuitBreaker et RateLimit sont disponibles sur le client pour les appels que tu fais toi-même.

Ce que l'on construit après le premier appel

Une zone de chat, c'est le début. Voici les quatre directions que ce travail prend habituellement, et chacune est déjà dans la bibliothèque.

Répondre à partir de tes propres données

Transforme tes documents en vecteurs avec TsgcAIOpenAIEmbeddings, stocke-les dans TsgcAIDatabaseVectorFile ou TsgcAIDatabaseVectorPinecone, et récupère les passages les plus proches pour les mettre dans le prompt. C'est la génération augmentée par récupération, et c'est comme cela que tu empêches le modèle d'inventer des réponses sur ton activité.

Embeddings et bases de données vectorielles

Lui parler, et le laisser répondre à voix haute

TsgcAIOpenAIChatBot relie un enregistreur, la transcription, l'appel de chat et la synthèse vocale dans un seul composant, pour qu'un utilisateur puisse tenir une conversation parlée avec ton application. TsgcAIOpenAITranslator fait la même chose pour la traduction en direct.

ChatBot IA et Traducteur IA

Exposer ton application à un agent IA

Le Model Context Protocol est la façon dont les assistants découvrent et appellent des outils. TsgcWSServer_API_MCP transforme ton application Delphi en serveur MCP que Claude et d'autres clients peuvent piloter, et TsgcWSAPI_Client_MCP consomme d'autres serveurs depuis ton code. Sur la palette, ils apparaissent sous les noms TsgcWSAPIServer_MCP et TsgcWSAPIClient_MCP.

Bon à savoir : contrairement au composant de chat, les unités MCP ne sont pas limitées à Windows, donc un serveur MCP écrit en Delphi peut tourner sur Linux.

Aperçu de MCP, serveur MCP et client MCP

Utiliser le reste de chaque API fournisseur

Génération d'images, transcription, modération, lots et fine tuning sur OpenAI. Vision, documents, réflexion étendue, recherche web et comptage de tokens sur Claude. Embeddings et gestion des modèles sur Ollama. Chaque page fournisseur liste ce que son client expose.

OpenAI, Claude et Ollama

Référence, démos et tutoriels

La référence des composants documente chaque propriété et chaque événement. Des projets de démonstration prêts à lancer sont livrés dans la bibliothèque, sous Demos\AI.

Référence, client OpenAI Chaque méthode, option et événement de TsgcHTTP_API_OpenAI.
Référence, client Anthropic Messages, outils, vision, lots et comptage de tokens sur TsgcHTTP_API_Anthropic.
Tutoriel, Claude depuis Delphi La visite guidée détaillée du client Anthropic, de bout en bout.
Tutoriel, modèles locaux avec Ollama Récupère un modèle, pointe le client sur localhost et exécute-le hors ligne.
Tutoriel, function calling Relier un modèle à tes propres fonctions Pascal, étape par étape.
Manuel utilisateur (PDF) Manuel complet couvrant chaque composant de la bibliothèque.

À lire aussi : le client OpenAI depuis Delphi, construire un chatbot IA, construire un agent IA et le client MCP. Les pages de présentation des composants sont Client OpenAI Delphi et API Anthropic.

Cette page fait partie des cas d'usage Delphi, qui prennent chacun une seule tâche de bout en bout. Les autres, pour l'instant, sont authentifier un utilisateur avec OAuth2 et PKCE et connecter deux applications en pair à pair avec WebRTC.

Foire aux questions

Crée un TsgcAI_Chat à partir de l'unité sgcAI_Chat, mets Provider sur le fournisseur que tu veux, définis ChatOptions.ApiKey et ChatOptions.Model, puis appelle Chat('your prompt'), qui renvoie la réponse sous forme de chaîne. Si tu préfères parler directement à l'API d'un seul fournisseur, utilise TsgcHTTP_API_OpenAI, TsgcHTTP_API_Anthropic ou TsgcHTTP_API_Ollama et appelle _CreateChatCompletion ou _CreateMessage. Les deux approches sont livrées dans sgcWebSockets et dans le package autonome sgcAI, et elles fonctionnent de Delphi 7 à RAD Studio 13.
Appelle ChatStream plutôt que Chat, et gère OnChatStream, qui se déclenche avec aChunk, le texte décodé de chaque delta, et un indicateur Cancel que tu peux positionner pour arrêter plus tôt. Au niveau du client REST, affecte OnHTTPAPISSE et appelle _CreateMessageStream sur les clients Claude et Ollama, ou mets Stream à True sur un TsgcOpenAIClass_Request_ChatCompletion. Cet événement te donne le nom et les données brutes du Server-Sent Event, avec les lectures réseau partielles déjà réassemblées.
Oui. Installe Ollama, récupère un modèle, puis pointe TsgcHTTP_API_Ollama dessus. OllamaOptions.Host vaut déjà par défaut http://localhost:11434, donc sur une installation par défaut tu n'as qu'à choisir un modèle et appeler _CreateMessage. Rien ne quitte la machine, aucune clé API n'est nécessaire et l'application fonctionne hors ligne. Via TsgcAIChat on atteint le même serveur en mettant Provider à aicpOllama et, quand le serveur n'est pas sur localhost, ChatOptions.BaseUrl.
Décris la fonction avec un JSON Schema et attache-la à la requête. Sur Claude, ajoute un TsgcAnthropicClass_Request_Tool avec Name, Description et InputSchema au tableau Tools d'un TsgcAnthropicClass_Request_Messages. La réponse contient alors un bloc de contenu dont le ContentType vaut tool_use, qui porte Name, Input et Id, et tu réponds avec un bloc tool_result qui cite le même ToolUseId. Sur OpenAI, mets les définitions dans la propriété Tools d'un TsgcOpenAIClass_Request_ChatCompletion et lis les appels demandés dans Choices[0]._Message.ToolCalls.
Les clients IA et LLM sont une fonctionnalité Enterprise de sgcWebSockets. Ils ne sont pas inclus dans les éditions Standard ni Professional. Si tu n'as pas besoin du reste de sgcWebSockets, le package autonome sgcAI contient les mêmes composants ainsi que le runtime dont ils ont besoin. La bibliothèque prend en charge Delphi 7 jusqu'à RAD Studio 13 et les versions correspondantes de C++ Builder. Côté plateformes, les clients REST TsgcHTTP_API_OpenAI, TsgcHTTP_API_Anthropic et TsgcHTTP_API_Ollama compilent pour Windows, macOS, Linux, iOS et Android, tandis que TsgcAIChat n'est compilé que pour Windows, Win32 et Win64. Le client et le serveur MCP ne sont pas non plus limités à Windows.
Pour les fournisseurs hébergés, oui. Les composants sont des clients REST, donc tu apportes une clé de ton propre compte OpenAI, Anthropic, Google, xAI, DeepSeek ou Mistral et tu l'affectes à ChatOptions.ApiKey, ou aux options du fournisseur comme OpenAIOptions.ApiKey. L'usage est facturé par ce fournisseur sur ta clé, et tu peux le suivre réponse par réponse via Usage.PromptTokens, Usage.CompletionTokens et Usage.TotalTokens. Ollama n'a besoin d'aucune clé, parce que le modèle tourne en local.
Chat et ChatStream sont synchrones. Sur Delphi 2010 et supérieur, appelle ChatAsync à la place : il exécute la requête sur un thread de travail et renvoie un IsgcFuture de string, donc tu enchaînes ThenProc pour recevoir la réponse, OnError pour recevoir une exception et Cancel pour abandonner une requête en cours. Le callback ThenProc est distribué sur le thread principal, donc il est sûr de mettre à jour l'UI depuis celui-ci. Augmente aussi HttpOptions.ReadTimeout, parce qu'une génération longue peut dépasser un délai de lecture par défaut.
Oui. Définis OpenAIOptions.Provider à oapvAzure et renseigne AzureOptions.ResourceName, AzureOptions.DeploymentId et AzureOptions.APIVersion. Le client vise alors ton déploiement Azure, et les appels que tu as déjà écrits restent exactement les mêmes.

Prêt à appeler un LLM depuis ton application Delphi ?

Télécharge l'essai gratuit et fais ton premier appel dès aujourd'hui.