Llamar a un LLM desde Delphi

Envía un prompt desde una aplicación VCL, FMX o de consola y recibe una respuesta, de un modelo alojado como OpenAI o Anthropic Claude, o de un modelo que se ejecuta en tu propia máquina a través de Ollama. Esta página te lleva de un formulario vacío a una llamada que funciona, y después a las tres cosas con las que se topa todo proyecto: streaming, llamada a herramientas y la decisión entre un modelo alojado y uno local.

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

Dos formas de hacer la llamada

Hay un componente de chat neutral respecto al proveedor, y hay un cliente REST específico para cada fabricante. Los dos vienen en la misma biblioteca, así que puedes empezar con uno y bajar al otro sin cambiar de proyecto.

TsgcAIChat, una API para todos los proveedores

Asigna Provider, una clave de API y un modelo, y luego llama a Chat. El componente construye el JSON del fabricante, guarda el historial de la conversación y devuelve el texto del asistente. Pasar de OpenAI a Claude, o a un modelo local de Ollama, es una sola asignación. Lo implementa TsgcAI_Chat en la unidad sgcAI_Chat, y se registra en la paleta como TsgcAIChat.

Los clientes REST por fabricante

TsgcHTTP_API_OpenAI, TsgcHTTP_API_Anthropic y TsgcHTTP_API_Ollama exponen la API de cada fabricante al completo, incluidas las partes que ninguna capa neutral puede cubrir: entrada de visión, entrada de documentos, razonamiento extendido, lotes, archivos, embeddings, generación de imágenes y transcripción. Usa estos cuando necesites un endpoint concreto.

Edición y plataforma

Los clientes de IA y LLM son una característica Enterprise de sgcWebSockets, no de Standard ni de Professional, o puedes comprar el paquete independiente sgcAI.

La plataforma importa aquí. Los tres clientes REST compilan en Windows, macOS, Linux, iOS y Android. TsgcAIChat no: está compilado solo para Windows, así que en un servicio Linux, una build de macOS o un objetivo móvil llamas directamente al cliente REST. Los ejemplos de esta página están escritos para que las dos vías funcionen.

Tu primera llamada, en unas diez líneas

Suelta el componente, pon una clave y un modelo, envía un prompt. Elige la pestaña del proveedor con el que vayas a empezar. La última pestaña no necesita ninguna clave de API, porque el modelo se ejecuta en tu 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;

Cambiar de fabricante es una sola línea. Provider acepta aicpOpenAI, aicpAnthropic, aicpGemini, aicpDeepSeek, aicpOllama, aicpGrok y aicpMistral. Todo lo demás en tu código se queda donde está.

Solo Windows. TsgcAI_Chat y su componente de paleta TsgcAIChat están compilados para Windows, Win32 y Win64. En macOS, Linux, iOS y Android la unidad no se compila en absoluto, así que si tu objetivo es un servicio Linux o una app móvil, usa los clientes REST de fabricante de las otras tres pestañas. Esos no tienen restricción 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;

Los métodos con guion bajo son atajos de cadena que devuelven el cuerpo de la respuesta en crudo. Cuando quieras un objeto ya parseado, construye un TsgcOpenAIClass_Request_ChatCompletion y llama a CreateChatCompletion, como se muestra más abajo en esta 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;

Claude requiere la cabecera de versión de API, así que asigna AnthropicVersion junto con la clave. _CreateMessageWithSystem añade un prompt de sistema, y _CountTokens calcula el precio de un prompt antes de que lo envíes.

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 vale por defecto http://localhost:11434, así que en una instalación por defecto puedes dejarlo tal cual. _PullModel descarga un modelo, _GetTags lista lo que ya está en disco y _ShowModel lee sus detalles.

Muestra la respuesta mientras se escribe

Una llamada de una sola pasada bloquea hasta que el modelo ha terminado, lo que en una respuesta larga parece que está roto. El streaming entrega la respuesta en fragmentos, así que el texto aparece en tu memo mientras el modelo todavía está pensando. Esta es la parte en la que más gente se atasca, así que aquí están los dos niveles.

Con TsgcAIChat, deltas ya decodificados

Llama a ChatStream en lugar de a Chat y maneja OnChatStream. El componente pide al proveedor una respuesta en streaming, parsea cada Server-Sent Event y te entrega aChunk, que es el texto nuevo y nada más. Lo añades, y esa es toda la implementación.

Cada proveedor envía en streaming una forma de JSON distinta. OpenAI, DeepSeek, Ollama, Grok y Mistral ponen el texto en choices[0].delta.content, Claude en delta.text, Gemini aún más adentro, dentro de candidates. TsgcAIChat ya sabe cuál se aplica al proveedor que has elegido, así que tu manejador nunca ve JSON.

Asigna Cancel a True dentro del manejador para detener una respuesta desbocada. La petición se abandona en ese punto, y no llegan más fragmentos. Cuando el stream termina, el texto ensamblado se añade al historial y lo devuelve ChatStream, y OnChatMessage se dispara una vez con la respuesta 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;

Con un cliente de fabricante, eventos en crudo

Los clientes REST también hacen streaming. Asigna OnHTTPAPISSE y llama al atajo de streaming: _CreateMessageStream en Claude y en Ollama, y en OpenAI un TsgcOpenAIClass_Request_ChatCompletion con Stream puesto a True. El evento te da aEvent, el nombre del Server-Sent Event, y aData, la carga útil de ese evento, exactamente como la envió el fabricante.

A este nivel parseas el JSON tú mismo, que es justo el objetivo: ves los deltas de llamadas a herramientas, los motivos de parada, los registros de uso y cualquier otra cosa que el fabricante ponga en el cable. Las lecturas de red parciales ya vienen reensambladas, así que un evento partido entre dos lecturas TCP llega igualmente entero, y el JSON delimitado por saltos de línea de Ollama se entrega a través del mismo evento.

Los terminadores varían según el fabricante. OpenAI cierra con el literal [DONE], Claude con un evento llamado message_stop. Maneja los dos si tu código apunta a los dos.

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;

Hilos. Chat y ChatStream son síncronos, así que llamarlos directamente desde un clic de botón congela el formulario mientras dura la petición. En Delphi 2010 y posteriores, ChatAsync ejecuta la llamada en un hilo de trabajo y devuelve un IsgcFuture<string>. Encadena ThenProc para el resultado y OnError para los fallos, y llama a Cancel para abandonar una petición en curso. El callback ThenProc se despacha en el hilo principal, así que puedes tocar la interfaz desde él directamente.

Deja que el modelo llame a tu código Pascal

La llamada a herramientas, también llamada function calling, es la forma en que un modelo pide a tu aplicación que busque algo o realice una acción. Describes la función con un JSON Schema, el modelo responde con los argumentos que quiere, tú ejecutas el código Pascal y devuelves el resultado. Este es el mecanismo que hay detrás de todo asistente útil dentro de una aplicación de gestión.

Claude, con objetos de herramienta tipados

Construye un TsgcAnthropicClass_Request_Messages, adjunta una o varias entradas TsgcAnthropicClass_Request_Tool y llama a CreateMessage. Cada herramienta lleva un Name, una Description y un InputSchema, que es el JSON Schema de sus argumentos.

La respuesta es un TsgcAnthropicClass_Response_Messages cuyo Content es un array de bloques. Un bloque con ContentType igual a 'tool_use' lleva el Namede la herramienta, los argumentos en Input y un Id. Ejecuta tu función y luego envía un mensaje de seguimiento que contenga un TsgcAnthropicClass_Request_Content_Block con ContentType puesto a 'tool_result', el mismo ToolUseId y tu respuesta en Content. Asigna IsError cuando la llamada haya fallado, para que el modelo pueda recuperarse en lugar de adivinar.

Fíjate en quién es dueño de qué: la petición de Anthropic no es dueña de los mensajes ni de las herramientas que le adjuntas, así que libéralos tú, como en el ejemplo.

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, con una petición tipada

La misma idea, con otra forma. Rellena un TsgcOpenAIClass_Request_ChatCompletion, asigna el array Messages, pon tus definiciones de herramienta en Tools como array JSON y, si quieres, guía al modelo con ToolChoice. ParallelToolCalls controla si el modelo puede pedir varias herramientas a la vez, y ResponseFormat fija la respuesta a JSON cuando necesitas parsearla.

CreateChatCompletion devuelve un TsgcOpenAIClass_Response_ChatCompletionya parseado. Lee la respuesta de Choices[0]._Message.Content, las llamadas solicitadas de Choices[0]._Message.ToolCalls, por qué paró el modelo de Choices[0].FinishReason, y lo que costó de Usage.PromptTokens, Usage.CompletionTokens y Usage.TotalTokens. A diferencia de la petición de Anthropic, esta sí es dueña de los objetos de mensaje que le adjuntas y los libera consigo misma.

Las propiedades antiguas Functions y FunctionCall siguen ahí para el código escrito contra la forma original de function calling de 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 alojado o modelo local

Si tus prompts contienen fichas de clientes, datos médicos, contratos o cualquier cosa cubierta por un acuerdo de tratamiento de datos, esta no es una cuestión de rendimiento, es una cuestión de cumplimiento. Aquí está la comparación.

Alojado, OpenAI o Claude Local, Ollama
Adónde va el prompt Al fabricante, sobre HTTPS, bajo sus condiciones A ningún sitio. La petición va a http://localhost:11434
Credenciales Una clave de API que tienes que mantener fuera del control de versiones y fuera del binario Ninguna por defecto. OllamaOptions.ApiKey existe para una instancia con proxy o remota
Calidad de la respuesta Los modelos más potentes disponibles hoy Buena y mejorando, claramente por detrás de la frontera en razonamiento difícil
Coste Por token, para siempre. Vigila Usage.TotalTokens Tu hardware, una vez. Un modelo útil quiere mucha RAM o una GPU
Latencia Un viaje de ida y vuelta por la red, más las colas del fabricante en horas punta Sin red. La velocidad es la que dé tu máquina
Sin conexión y en entornos aislados No
Límites de tasa y caídas Del lado del fabricante. Usa RetryOptions y respeta Retry-After Solo tu propia capacidad
Componente TsgcHTTP_API_OpenAI, TsgcHTTP_API_Anthropic TsgcHTTP_API_Ollama

Una respuesta habitual es los dos. Como TsgcAIChat pone a todos los proveedores detrás de una sola API, puedes enrutar por clasificación de datos en tiempo de ejecución: local para todo lo que toque una ficha de cliente, alojado para el resto. El interruptor es Provider, más ChatOptions.BaseUrl cuando el proveedor es 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);

Los ajustes que importan en producción

Una demo que funciona en tu escritorio no es lo mismo que un cliente que sobrevive a un límite de tasa, a un modelo lento y a un ticket de soporte que dice "simplemente dejó de funcionar".

Reintentos y backoff

Cada cliente lleva un bloque RetryOptions: Enabled, Retries, Wait, Multiplier, MaxInterval, Jitter y HonorRetryAfter. Actívalo y un fallo transitorio se reintenta con backoff exponencial en lugar de aparecer como una excepción. HonorRetryAfter hace que el cliente obedezca la cabecera Retry-After del fabricante en lugar de adivinar.

Tiempos de espera

HttpOptions.ReadTimeout es el que hay que subir. Una generación larga, sobre todo en un modelo local, puede durar más que un tiempo de espera de lectura HTTP por defecto y fallar a mitad de una respuesta que iba bien.

Registro

LogOptions.Enabled más LogOptions.FileName escribe el tráfico en un archivo. Cuando un prompt se comporta distinto en producción, esta es la forma más rápida de ver el JSON que tu código envió de verdad.

Historial de conversación

TsgcAIChat guarda el intercambio y lo reproduce en la siguiente llamada, que es lo que hace que funcione una pregunta de seguimiento. Limítalo con MaxHistoryMessages para que una sesión larga no haga crecer el prompt, y por tanto la factura, sin límite. ClearHistory empieza de cero, y GetHistory expone Count y los mensajes individuales.

Azure OpenAI

Asigna OpenAIOptions.Provider a oapvAzure y rellena AzureOptions.ResourceName, AzureOptions.DeploymentId y AzureOptions.APIVersion. El resto de tu código no cambia, lo que importa cuando compras insiste en que el tráfico se quede dentro de tu tenant de Azure.

Errores y circuit breaking

OnHTTPAPIException expone los fallos de los clientes REST, y OnChatError hace lo mismo para TsgcAIChat. Un error HTTP llega como EsgcHTTPAPIProtocolException, que sigue descendiendo de EIdHTTPProtocolException y además lleva las cabeceras de la respuesta. CircuitBreaker y RateLimit están disponibles en el cliente para las llamadas que hagas tú.

Qué construye la gente después de la primera llamada

Una caja de chat es el principio. Estas son las cuatro direcciones que suele tomar este trabajo, y todas ellas ya están en la biblioteca.

Responder desde tus propios datos

Convierte tus documentos en vectores con TsgcAIOpenAIEmbeddings, guárdalos en TsgcAIDatabaseVectorFile o TsgcAIDatabaseVectorPinecone, y recupera los pasajes más cercanos para ponerlos en el prompt. Esto es la generación aumentada por recuperación, y es la forma de evitar que el modelo se invente respuestas sobre tu negocio.

Embeddings y bases de datos vectoriales

Háblale, y deja que te conteste

TsgcAIOpenAIChatBot conecta un grabador, la transcripción, la llamada de chat y el texto a voz en un solo componente, para que una persona pueda mantener una conversación hablada con tu aplicación. TsgcAIOpenAITranslator hace lo mismo para la traducción en vivo.

ChatBot con IA y Traductor con IA

Expón tu app a un agente de IA

El Model Context Protocol es la forma en que los asistentes descubren y llaman a herramientas. TsgcWSServer_API_MCP convierte tu aplicación Delphi en un servidor MCP que Claude y otros clientes pueden manejar, y TsgcWSAPI_Client_MCP consume otros servidores desde tu código. En la paleta aparecen como TsgcWSAPIServer_MCP y TsgcWSAPIClient_MCP.

Conviene saberlo: a diferencia del componente de chat, las unidades de MCP no están restringidas a Windows, así que un servidor MCP escrito en Delphi puede ejecutarse en Linux.

Visión general de MCP, Servidor MCP y Cliente MCP

Usar el resto de la API de cada fabricante

Generación de imágenes, transcripción, moderación, lotes y ajuste fino en OpenAI. Visión, documentos, razonamiento extendido, búsqueda web y conteo de tokens en Claude. Embeddings y gestión de modelos en Ollama. La página de cada fabricante lista lo que expone su cliente.

OpenAI, Claude y Ollama

Referencia, demos y tutoriales

La referencia de componentes documenta todas las propiedades y todos los eventos. Los proyectos de demo listos para ejecutar vienen dentro de la biblioteca, en Demos\AI.

Referencia, cliente de OpenAI Todos los métodos, opciones y eventos de TsgcHTTP_API_OpenAI.
Referencia, cliente de Anthropic Mensajes, herramientas, visión, lotes y conteo de tokens en TsgcHTTP_API_Anthropic.
Tutorial, Claude desde Delphi El recorrido largo por el cliente de Anthropic, de principio a fin.
Tutorial, modelos locales con Ollama Descarga un modelo, apunta el cliente a localhost y ejecútalo sin conexión.
Tutorial, function calling Conectar un modelo con tus propias funciones Pascal, paso a paso.
Manual de usuario (PDF) Manual completo que cubre todos los componentes de la biblioteca.

Más lectura: el cliente de OpenAI desde Delphi, construir un chatbot de IA, construir un agente de IA y el cliente MCP. Las páginas de producto de los componentes son Cliente OpenAI para Delphi y API de Anthropic.

Esta página es uno de los casos de uso de Delphi, cada uno de los cuales lleva un único trabajo de principio a fin. Los otros que hay hasta ahora son iniciar la sesión de una persona con OAuth2 y PKCE y conectar dos aplicaciones entre pares con WebRTC.

Preguntas frecuentes

Crea un TsgcAI_Chat de la unidad sgcAI_Chat, asigna Provider al fabricante que quieras, asigna ChatOptions.ApiKey y ChatOptions.Model, y luego llama a Chat('your prompt'), que devuelve la respuesta como cadena. Si prefieres hablar directamente con la API de un fabricante, usa TsgcHTTP_API_OpenAI, TsgcHTTP_API_Anthropic o TsgcHTTP_API_Ollama y llama a _CreateChatCompletion o _CreateMessage. Los dos enfoques vienen en sgcWebSockets y en el paquete independiente sgcAI, y funcionan desde Delphi 7 hasta RAD Studio 13.
Llama a ChatStream en lugar de a Chat, y maneja OnChatStream, que se dispara con aChunk, el texto decodificado de cada delta, y un flag Cancel que puedes activar para parar antes. A nivel de cliente REST, asigna OnHTTPAPISSE y llama a _CreateMessageStream en los clientes de Claude y Ollama, o pon Stream a True en un TsgcOpenAIClass_Request_ChatCompletion. Ese evento te da el nombre y los datos del Server-Sent Event en crudo, con las lecturas de red parciales ya reensambladas.
Sí. Instala Ollama, descarga un modelo y luego apunta TsgcHTTP_API_Ollama hacia él. OllamaOptions.Host ya vale por defecto http://localhost:11434, así que en una instalación por defecto solo eliges un modelo y llamas a _CreateMessage. Nada sale de la máquina, no hace falta ninguna clave de API y la aplicación funciona sin conexión. A través de TsgcAIChat se llega al mismo servidor asignando Provider a aicpOllama y, cuando el servidor no está en localhost, ChatOptions.BaseUrl.
Describe la función con un JSON Schema y adjúntala a la petición. En Claude, añade un TsgcAnthropicClass_Request_Tool con Name, Description y InputSchema al array Tools de un TsgcAnthropicClass_Request_Messages. La respuesta contiene entonces un bloque de contenido cuyo ContentType es tool_use, que lleva Name, Input y Id, y respondes con un bloque tool_result que cita el mismo ToolUseId. En OpenAI, pon las definiciones en la propiedad Tools de un TsgcOpenAIClass_Request_ChatCompletion y lee las llamadas solicitadas de Choices[0]._Message.ToolCalls.
Los clientes de IA y LLM son una característica Enterprise de sgcWebSockets. No están incluidos en las ediciones Standard ni Professional. Si no necesitas el resto de sgcWebSockets, el paquete independiente sgcAI contiene los mismos componentes junto con el runtime que necesitan. La biblioteca soporta desde Delphi 7 hasta RAD Studio 13 y las versiones de C++ Builder correspondientes. En cuanto a plataformas, los clientes REST TsgcHTTP_API_OpenAI, TsgcHTTP_API_Anthropic y TsgcHTTP_API_Ollama compilan para Windows, macOS, Linux, iOS y Android, mientras que TsgcAIChat está compilado solo para Windows, Win32 y Win64. El cliente y el servidor MCP tampoco están restringidos a Windows.
Para los proveedores alojados, sí. Los componentes son clientes REST, así que traes una clave de tu propia cuenta de OpenAI, Anthropic, Google, xAI, DeepSeek o Mistral y la asignas a ChatOptions.ApiKey, o a las opciones del fabricante, como OpenAIOptions.ApiKey. El uso lo factura ese fabricante contra tu clave, y puedes seguirlo respuesta a respuesta con Usage.PromptTokens, Usage.CompletionTokens y Usage.TotalTokens. Ollama no necesita clave, porque el modelo se ejecuta en local.
Chat y ChatStream son síncronos. En Delphi 2010 y posteriores, llama a ChatAsync en su lugar: ejecuta la petición en un hilo de trabajo y devuelve un IsgcFuture de string, así que encadenas ThenProc para recibir la respuesta, OnError para recibir una excepción y Cancel para abandonar una petición en curso. El callback ThenProc se despacha en el hilo principal, así que es seguro actualizar la interfaz desde él. Sube también HttpOptions.ReadTimeout, porque una generación larga puede durar más que un tiempo de espera de lectura por defecto.
Sí. Asigna OpenAIOptions.Provider a oapvAzure y rellena AzureOptions.ResourceName, AzureOptions.DeploymentId y AzureOptions.APIVersion. El cliente apunta entonces a tu despliegue de Azure, y las llamadas que ya escribiste se quedan exactamente igual.

¿Listo para llamar a un LLM desde tu app Delphi?

Descarga la prueba gratuita y haz tu primera llamada hoy.