Chamar um LLM a partir do Delphi

Envie um prompt a partir de uma aplicação VCL, FMX ou console e receba uma resposta, de um modelo hospedado como OpenAI ou Anthropic Claude, ou de um modelo rodando na sua própria máquina através do Ollama. Esta página leva você de um formulário vazio até uma chamada que funciona, e depois às três coisas que todo projeto encontra em seguida: streaming, tool calling e a decisão entre um modelo hospedado e um local.

OpenAI, Claude, Gemini, Grok, DeepSeek, Mistral, Ollama
Streaming sobre Server-Sent Events
Do Delphi 7 ao RAD Studio 13

Duas maneiras de fazer a chamada

Existe um componente de chat neutro em relação ao provedor e existe um cliente REST dedicado para cada fornecedor. Os dois vêm na mesma biblioteca, então você pode começar por um e descer para o outro sem trocar de projeto.

TsgcAIChat, uma API para todos os provedores

Defina Provider, uma chave de API e um modelo, depois chame Chat. O componente monta o JSON do fornecedor, guarda o histórico da conversa e devolve o texto do assistente. Trocar da OpenAI para o Claude, ou para um modelo Ollama local, é uma única atribuição. É implementado por TsgcAI_Chat na unit sgcAI_Chat e registrado na paleta como TsgcAIChat.

Os clientes REST por fornecedor

TsgcHTTP_API_OpenAI, TsgcHTTP_API_Anthropic e TsgcHTTP_API_Ollama expõem a API de cada fornecedor por inteiro, inclusive as partes que nenhuma camada neutra consegue cobrir: entrada de imagens, entrada de documentos, extended thinking, batches, arquivos, embeddings, geração de imagens e transcrição. Use estes quando você precisar de um endpoint específico.

Edição e plataforma

Os clientes de IA e LLM são um recurso Enterprise do sgcWebSockets, não do Standard e não do Professional, ou você pode comprar o pacote independente sgcAI.

A plataforma importa aqui. Os três clientes REST compilam em Windows, macOS, Linux, iOS e Android. O TsgcAIChat não: ele é compilado somente para Windows, então em um serviço Linux, em uma build macOS ou em um alvo mobile você chama o cliente REST diretamente. Os exemplos desta página estão escritos de modo que os dois caminhos funcionem.

Sua primeira chamada, em cerca de dez linhas

Solte o componente, defina uma chave e um modelo, envie um prompt. Escolha a aba do provedor pelo qual você está começando. A última aba não precisa de chave de API nenhuma, porque o modelo roda na sua máquina.

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;

Trocar de fornecedor é uma única linha. Provider aceita aicpOpenAI, aicpAnthropic, aicpGemini, aicpDeepSeek, aicpOllama, aicpGrok e aicpMistral. Todo o resto do seu código fica onde está.

Somente Windows. O TsgcAI_Chat e seu componente de paleta TsgcAIChat são compilados para Windows, Win32 e Win64. Em macOS, Linux, iOS e Android a unit não é compilada, então, se o seu alvo é um serviço Linux ou um aplicativo mobile, use os clientes REST dos fornecedores nas outras três abas. Eles não têm restrição de plataforma.

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;

Os métodos com sublinhado são atalhos de string que devolvem o corpo bruto da resposta. Quando você quiser um objeto já interpretado, monte um TsgcOpenAIClass_Request_ChatCompletion e chame CreateChatCompletion, mostrado mais abaixo nesta página.

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;

O Claude exige o cabeçalho de versão da API, então defina AnthropicVersion junto com a chave. _CreateMessageWithSystem acrescenta um system prompt, e _CountTokens calcula o custo de um prompt antes de você enviá-lo.

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;

O Host tem como padrão http://localhost:11434, então em uma instalação padrão você pode deixá-lo como está. _PullModel baixa um modelo, _GetTags lista o que já está em disco e _ShowModel lê os detalhes dele.

Mostre a resposta enquanto ela é escrita

Uma chamada de uma tacada só bloqueia até o modelo terminar, o que em uma resposta longa parece defeito. O streaming entrega a resposta em fragmentos, então o texto aparece no seu memo enquanto o modelo ainda está pensando. É nesta parte que a maioria das pessoas trava, por isso aqui estão os dois níveis dela.

Com o TsgcAIChat, deltas já decodificados

Chame ChatStream em vez de Chat e trate OnChatStream. O componente pede ao provedor uma resposta em streaming, interpreta cada Server-Sent Event e entrega a você aChunk, que é o texto novo e nada mais. Você concatena, e essa é a implementação inteira.

Cada provedor faz streaming com um formato de JSON diferente. OpenAI, DeepSeek, Ollama, Grok e Mistral colocam o texto em choices[0].delta.content, o Claude em delta.text, o Gemini ainda mais fundo dentro de candidates. O TsgcAIChat já sabe qual deles vale para o provedor que você selecionou, então o seu manipulador nunca vê JSON.

Defina Cancel como True dentro do manipulador para interromper uma resposta descontrolada. A requisição é abandonada nesse ponto e nenhum outro chunk chega. Quando o stream termina, o texto montado é adicionado ao histórico e devolvido por ChatStream, e OnChatMessage dispara uma vez com a resposta completa.

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;

Com um cliente de fornecedor, eventos brutos

Os clientes REST também fazem streaming. Atribua OnHTTPAPISSE e chame o atalho de streaming: _CreateMessageStream no Claude e no Ollama, e na OpenAI um TsgcOpenAIClass_Request_ChatCompletion com Stream em True. O evento entrega aEvent, o nome do Server-Sent Event, e aData, a carga daquele evento, exatamente como o fornecedor enviou.

Nesse nível você interpreta o JSON por conta própria, e é justamente esse o objetivo: você vê os deltas de tool call, os motivos de parada, os registros de uso e qualquer outra coisa que o fornecedor coloque na rede. As leituras parciais de rede já são remontadas para você, então um evento dividido entre duas leituras TCP ainda chega inteiro, e o JSON delimitado por quebra de linha do Ollama é entregue pelo mesmo evento.

Os terminadores variam conforme o fornecedor. A OpenAI encerra com o literal [DONE], o Claude com um evento chamado message_stop. Trate os dois se o seu código atende aos dois.

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;

Threads. Chat e ChatStream são síncronos, então chamá-los direto do clique de um botão congela o formulário durante toda a requisição. No Delphi 2010 e posteriores, ChatAsync executa a chamada em uma thread de trabalho e devolve um IsgcFuture<string>. Encadeie ThenProc para o resultado e OnError para as falhas, e chame Cancel para abandonar uma requisição em andamento. O callback de ThenProc é despachado na thread principal, então você pode mexer na interface diretamente a partir dele.

Deixe o modelo chamar o seu código Pascal

Tool calling, também chamado de function calling, é como um modelo pede à sua aplicação para consultar algo ou executar uma ação. Você descreve a função com um JSON Schema, o modelo responde com os argumentos que quer, você executa o código Pascal e devolve o resultado. Esse é o mecanismo por trás de todo assistente útil dentro de uma aplicação corporativa.

Claude, com objetos de tool tipados

Monte um TsgcAnthropicClass_Request_Messages, anexe uma ou mais entradas TsgcAnthropicClass_Request_Tool e chame CreateMessage. Cada tool carrega um Name, uma Description e um InputSchema, que é o JSON Schema dos seus argumentos.

A resposta é um TsgcAnthropicClass_Response_Messages cujo Content é um array de blocos. Um bloco com ContentType igual a 'tool_use' carrega o Name da tool, os argumentos em Input e um Id. Execute a sua função e depois envie uma mensagem de continuação contendo um TsgcAnthropicClass_Request_Content_Block com ContentType definido como 'tool_result', o mesmo ToolUseId e a sua resposta em Content. Defina IsError quando a chamada falhar, para que o modelo consiga se recuperar em vez de adivinhar.

Repare na propriedade dos objetos: a requisição da Anthropic não é dona das mensagens e das tools que você anexa, então libere-as você mesmo, como no exemplo.

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, com uma requisição tipada

A mesma ideia, com outro formato. Preencha um TsgcOpenAIClass_Request_ChatCompletion, atribua o array Messages, coloque as definições das suas tools em Tools como um array JSON e, se quiser, direcione o modelo com ToolChoice. ParallelToolCalls controla se o modelo pode pedir várias tools de uma vez, e ResponseFormat fixa a resposta em JSON quando você precisa interpretá-la.

CreateChatCompletion devolve um TsgcOpenAIClass_Response_ChatCompletion já interpretado. Leia a resposta em Choices[0]._Message.Content, as chamadas solicitadas em Choices[0]._Message.ToolCalls, o motivo de o modelo ter parado em Choices[0].FinishReason e o custo em Usage.PromptTokens, Usage.CompletionTokens e Usage.TotalTokens. Ao contrário da requisição da Anthropic, esta é dona dos objetos de mensagem que você anexa e os libera junto com ela.

As propriedades mais antigas Functions e FunctionCall continuam disponíveis para código escrito no formato original de function calling da 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;

Modelo hospedado ou modelo local

Se os seus prompts contêm cadastros de clientes, dados médicos, contratos ou qualquer coisa coberta por um contrato de tratamento de dados, isto não é uma questão de desempenho, é uma questão de conformidade. Aqui está a comparação.

Hospedado, OpenAI ou Claude Local, Ollama
Para onde vai o prompt Para o fornecedor, sobre HTTPS, sob os termos dele Para lugar nenhum. A requisição vai para http://localhost:11434
Credenciais Uma chave de API que você precisa manter fora do controle de versão e fora do binário Nenhuma por padrão. OllamaOptions.ApiKey existe para uma instância remota ou atrás de proxy
Qualidade da resposta Os modelos mais fortes disponíveis hoje Boa e melhorando, claramente atrás da fronteira em raciocínio difícil
Custo Por token, para sempre. Acompanhe Usage.TotalTokens Seu hardware, uma vez só. Um modelo útil pede bastante RAM ou uma GPU
Latência Uma ida e volta pela rede, mais a fila do fornecedor nos horários movimentados Sem rede. A velocidade é a que a sua máquina entrega
Offline e em rede isolada Não Sim
Limites de taxa e indisponibilidades Do lado do fornecedor. Use RetryOptions e respeite Retry-After Apenas a sua própria capacidade
Componente TsgcHTTP_API_OpenAI, TsgcHTTP_API_Anthropic TsgcHTTP_API_Ollama

Uma resposta comum é usar os dois. Como o TsgcAIChat coloca todos os provedores atrás de uma única API, você pode rotear por classificação de dados em tempo de execução: local para tudo que toca um cadastro de cliente, hospedado para o resto. A chave é Provider, mais ChatOptions.BaseUrl quando o provedor é o 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);

As configurações que importam em produção

Uma demonstração que funciona na sua mesa não é a mesma coisa que um cliente que sobrevive a um limite de taxa, a um modelo lento e a um chamado de suporte dizendo "simplesmente parou".

Novas tentativas e backoff

Cada cliente traz um bloco RetryOptions: Enabled, Retries, Wait, Multiplier, MaxInterval, Jitter e HonorRetryAfter. Ative-o e uma falha transitória é repetida com backoff exponencial em vez de aparecer como exceção. HonorRetryAfter faz o cliente obedecer ao cabeçalho Retry-After do fornecedor em vez de chutar.

Tempos limite

HttpOptions.ReadTimeout é o valor a aumentar. Uma geração longa, principalmente em um modelo local, pode ultrapassar o tempo limite de leitura HTTP padrão e falhar no meio de uma resposta que ia bem.

Registro de log

LogOptions.Enabled mais LogOptions.FileName grava o tráfego em um arquivo. Quando um prompt se comporta de forma diferente em produção, esse é o jeito mais rápido de ver o JSON que o seu código realmente enviou.

Histórico da conversa

O TsgcAIChat guarda a troca de mensagens e a reenvia na chamada seguinte, que é o que faz uma pergunta de continuação funcionar. Limite isso com MaxHistoryMessages para que uma sessão longa não faça o prompt, e portanto a conta, crescer sem limite. ClearHistory recomeça do zero, e GetHistory expõe Count e as mensagens individuais.

Azure OpenAI

Defina OpenAIOptions.Provider como oapvAzure e preencha AzureOptions.ResourceName, AzureOptions.DeploymentId e AzureOptions.APIVersion. O resto do seu código continua igual, o que importa quando o setor de compras exige que o tráfego fique dentro do seu tenant Azure.

Erros e circuit breaking

OnHTTPAPIException expõe as falhas dos clientes REST, e OnChatError faz o mesmo para o TsgcAIChat. Um erro HTTP chega como um EsgcHTTPAPIProtocolException, que continua descendendo de EIdHTTPProtocolException e ainda carrega os cabeçalhos da resposta. CircuitBreaker e RateLimit estão disponíveis no cliente para as chamadas que você mesmo faz.

O que as pessoas constroem depois da primeira chamada

Uma caixa de chat é só o começo. Estas são as quatro direções que esse trabalho costuma tomar, e todas elas já estão na biblioteca.

Responder a partir dos seus próprios dados

Transforme seus documentos em vetores com TsgcAIOpenAIEmbeddings, guarde-os em TsgcAIDatabaseVectorFile ou TsgcAIDatabaseVectorPinecone e recupere as passagens mais próximas para colocar no prompt. Isso é retrieval augmented generation, e é assim que você impede o modelo de inventar respostas sobre o seu negócio.

Embeddings e bancos de dados vetoriais

Fale com ele, e deixe que ele responda falando

O TsgcAIOpenAIChatBot junta gravador, transcrição, a chamada de chat e a conversão de texto em fala em um só componente, para que um usuário possa manter uma conversa falada com a sua aplicação. O TsgcAIOpenAITranslator faz o mesmo para tradução ao vivo.

AI ChatBot e AI Translator

Expor a sua aplicação a um agente de IA

O Model Context Protocol é como os assistentes descobrem e chamam tools. O TsgcWSServer_API_MCP transforma a sua aplicação Delphi em um servidor MCP que o Claude e outros clientes conseguem conduzir, e o TsgcWSAPI_Client_MCP consome outros servidores a partir do seu código. Na paleta eles aparecem como TsgcWSAPIServer_MCP e TsgcWSAPIClient_MCP.

Vale saber: ao contrário do componente de chat, as units de MCP não estão restritas ao Windows, então um servidor MCP escrito em Delphi pode rodar em Linux.

Visão geral do MCP, servidor MCP e cliente MCP

Usar o resto da API de cada fornecedor

Geração de imagens, transcrição, moderação, batches e fine tuning na OpenAI. Visão, documentos, extended thinking, busca na web e contagem de tokens no Claude. Embeddings e gerenciamento de modelos no Ollama. A página de cada fornecedor lista o que o cliente dele expõe.

OpenAI, Claude e Ollama

Referência, demonstrações e tutoriais

A referência dos componentes documenta cada propriedade e cada evento. Projetos de demonstração prontos para rodar vêm dentro da biblioteca, em Demos\AI.

Referência, cliente OpenAI Todos os métodos, opções e eventos do TsgcHTTP_API_OpenAI.
Referência, cliente Anthropic Mensagens, tools, visão, batches e contagem de tokens no TsgcHTTP_API_Anthropic.
Tutorial, Claude a partir do Delphi O passo a passo longo do cliente Anthropic, do início ao fim.
Tutorial, modelos locais com Ollama Baixe um modelo, aponte o cliente para o localhost e rode offline.
Tutorial, function calling Ligando um modelo às suas próprias funções Pascal, passo a passo.
Manual do usuário (PDF) Manual completo cobrindo todos os componentes da biblioteca.

Mais leituras: o cliente OpenAI a partir do Delphi, construir um chatbot de IA, construir um agente de IA e o cliente MCP. As páginas dos componentes são cliente OpenAI para Delphi e API Anthropic.

Esta página faz parte dos casos de uso Delphi, cada um deles levando um único trabalho do início ao fim. Os outros até agora são autenticar um usuário com OAuth2 e PKCE e conectar duas aplicações peer to peer com WebRTC.

Perguntas frequentes

Crie um TsgcAI_Chat a partir da unit sgcAI_Chat, defina Provider com o fornecedor que você quer, defina ChatOptions.ApiKey e ChatOptions.Model e depois chame Chat('your prompt'), que devolve a resposta como string. Se você preferir falar diretamente com a API de um fornecedor, use TsgcHTTP_API_OpenAI, TsgcHTTP_API_Anthropic ou TsgcHTTP_API_Ollama e chame _CreateChatCompletion ou _CreateMessage. As duas abordagens vêm no sgcWebSockets e no pacote independente sgcAI, e funcionam do Delphi 7 ao RAD Studio 13.
Chame ChatStream em vez de Chat e trate OnChatStream, que dispara com aChunk, o texto decodificado de cada delta, e uma flag Cancel que você pode definir para parar antes. No nível do cliente REST, atribua OnHTTPAPISSE e chame _CreateMessageStream nos clientes Claude e Ollama, ou defina Stream como True em um TsgcOpenAIClass_Request_ChatCompletion. Esse evento entrega o nome e os dados brutos do Server-Sent Event, com as leituras parciais de rede já remontadas.
Sim. Instale o Ollama, baixe um modelo e aponte o TsgcHTTP_API_Ollama para ele. OllamaOptions.Host já vem com o padrão http://localhost:11434, então em uma instalação padrão você só escolhe um modelo e chama _CreateMessage. Nada sai da máquina, nenhuma chave de API é necessária e a aplicação funciona offline. Pelo TsgcAIChat, o mesmo servidor é alcançado definindo Provider como aicpOllama e, quando o servidor não está no localhost, ChatOptions.BaseUrl.
Descreva a função com um JSON Schema e anexe-a à requisição. No Claude, adicione um TsgcAnthropicClass_Request_Tool com Name, Description e InputSchema ao array Tools de um TsgcAnthropicClass_Request_Messages. A resposta então contém um bloco de conteúdo cujo ContentType é tool_use, carregando Name, Input e Id, e você responde com um bloco tool_result citando o mesmo ToolUseId. Na OpenAI, coloque as definições na propriedade Tools de um TsgcOpenAIClass_Request_ChatCompletion e leia as chamadas solicitadas em Choices[0]._Message.ToolCalls.
Os clientes de IA e LLM são um recurso Enterprise do sgcWebSockets. Eles não estão incluídos nas edições Standard ou Professional. Se você não precisa do resto do sgcWebSockets, o pacote independente sgcAI contém os mesmos componentes junto com o runtime de que eles precisam. A biblioteca é compatível do Delphi 7 ao RAD Studio 13 e com as versões correspondentes do C++ Builder. Quanto às plataformas, os clientes REST TsgcHTTP_API_OpenAI, TsgcHTTP_API_Anthropic e TsgcHTTP_API_Ollama compilam para Windows, macOS, Linux, iOS e Android, enquanto o TsgcAIChat é compilado somente para Windows, Win32 e Win64. O cliente e o servidor MCP também não estão restritos ao Windows.
Para provedores hospedados, sim. Os componentes são clientes REST, então você traz uma chave da sua própria conta OpenAI, Anthropic, Google, xAI, DeepSeek ou Mistral e a atribui a ChatOptions.ApiKey, ou às opções do fornecedor, como OpenAIOptions.ApiKey. O uso é cobrado por esse fornecedor na sua chave, e você pode acompanhá-lo por resposta através de Usage.PromptTokens, Usage.CompletionTokens e Usage.TotalTokens. O Ollama não precisa de chave, porque o modelo roda localmente.
Chat e ChatStream são síncronos. No Delphi 2010 e posteriores, chame ChatAsync: ele executa a requisição em uma thread de trabalho e devolve um IsgcFuture de string, então você encadeia ThenProc para receber a resposta, OnError para receber uma exceção e Cancel para abandonar uma requisição em andamento. O callback de ThenProc é despachado na thread principal, então é seguro atualizar a interface a partir dele. Aumente também HttpOptions.ReadTimeout, porque uma geração longa pode ultrapassar um tempo limite de leitura padrão.
Sim. Defina OpenAIOptions.Provider como oapvAzure e preencha AzureOptions.ResourceName, AzureOptions.DeploymentId e AzureOptions.APIVersion. O cliente passa a apontar para a sua implantação no Azure, e as chamadas que você já escreveu continuam exatamente as mesmas.

Pronto para chamar um LLM do seu aplicativo Delphi?

Baixe a versão de avaliação gratuita e faça a sua primeira chamada hoje.