Wywołanie LLM z Delphi

Wyślij prompt z aplikacji VCL, FMX lub konsolowej i odbierz odpowiedź, z modelu hostowanego takiego jak OpenAI czy Anthropic Claude, albo z modelu działającego na twojej własnej maszynie przez Ollama. Ta strona prowadzi cię od pustego formularza do działającego wywołania, a potem do trzech rzeczy, na które trafia każdy projekt: strumieniowania, tool calling i wyboru między modelem hostowanym a lokalnym.

OpenAI, Claude, Gemini, Grok, DeepSeek, Mistral, Ollama
Strumieniowanie przez Server-Sent Events
Delphi 7 do RAD Studio 13

Dwa sposoby na wykonanie wywołania

Jest komponent czatu neutralny wobec dostawcy, i jest dedykowany klient REST dla każdego dostawcy. Oba są w tej samej bibliotece, więc możesz zacząć od jednego i zejść do drugiego bez zmiany projektu.

TsgcAIChat, jedno API dla każdego dostawcy

Ustaw Provider, klucz API i model, a potem wywołaj Chat. Komponent buduje JSON dostawcy, przechowuje historię rozmowy i zwraca tekst asystenta. Przełączenie się z OpenAI na Claude, albo na lokalny model Ollama, to jedno przypisanie. Zaimplementowany przez TsgcAI_Chat w module sgcAI_Chat, a na palecie zarejestrowany jako TsgcAIChat.

Klienty REST dla poszczególnych dostawców

TsgcHTTP_API_OpenAI, TsgcHTTP_API_Anthropic i TsgcHTTP_API_Ollama udostępniają API każdego dostawcy w całości, łącznie z częściami, których żadna neutralna warstwa nie obejmie: wejście wizyjne, wejście dokumentowe, rozszerzone myślenie, wsady, pliki, embeddingi, generowanie obrazów i transkrypcja. Użyj ich, gdy potrzebujesz konkretnego endpointu.

Edycja i platforma

Klienty AI i LLM to funkcja Enterprise w sgcWebSockets, nie Standard i nie Professional, albo możesz kupić samodzielny pakiet sgcAI.

Platforma ma tu znaczenie. Trzy klienty REST kompilują się na Windows, macOS, Linux, iOS i Android. TsgcAIChat nie: jest kompilowany tylko dla Windows, więc w usłudze na Linuksie, w kompilacji macOS albo na celu mobilnym wywołujesz klienta REST bezpośrednio. Przykłady na tej stronie są napisane tak, żeby działała każda z tych dróg.

Twoje pierwsze wywołanie, w około dziesięciu liniach

Upuść komponent, ustaw klucz i model, wyślij prompt. Wybierz zakładkę dostawcy, od którego zaczynasz. Ostatnia zakładka nie potrzebuje w ogóle klucza API, bo model działa na twojej maszynie.

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;

Zmiana dostawcy to jedna linia. Provider przyjmuje aicpOpenAI, aicpAnthropic, aicpGemini, aicpDeepSeek, aicpOllama, aicpGrok i aicpMistral. Cała reszta twojego kodu zostaje na miejscu.

Tylko Windows. TsgcAI_Chat i jego komponent paletowy TsgcAIChat są kompilowane dla Windows, Win32 i Win64. Na macOS, Linuksie, iOS i Androidzie moduł nie jest w ogóle kompilowany, więc jeśli twoim celem jest usługa na Linuksie albo aplikacja mobilna, użyj klientów REST dostawców z pozostałych trzech zakładek. Te nie mają żadnych ograniczeń platformowych.

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;

Metody z podkreśleniem to skróty łańcuchowe, które zwracają surowe ciało odpowiedzi. Gdy chcesz sparsowany obiekt, zbuduj TsgcOpenAIClass_Request_ChatCompletion i wywołaj CreateChatCompletion, pokazane dalej na tej stronie.

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 wymaga nagłówka z wersją API, więc ustaw AnthropicVersion obok klucza. _CreateMessageWithSystem dodaje prompt systemowy, a _CountTokens wycenia prompt, zanim go wyślesz.

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 domyślnie wskazuje http://localhost:11434, więc przy domyślnej instalacji możesz go zostawić. _PullModel pobiera model, _GetTags wypisuje to, co już jest na dysku, a _ShowModel odczytuje szczegóły modelu.

Pokaż odpowiedź w trakcie jej pisania

Pojedyncze wywołanie blokuje, dopóki model nie skończy, co przy długiej odpowiedzi sprawia wrażenie awarii. Strumieniowanie dostarcza odpowiedź we fragmentach, więc tekst pojawia się w twoim polu memo, gdy model jeszcze myśli. To jest część, na której najwięcej osób utyka, więc poniżej są oba jej poziomy.

Z TsgcAIChat, delty już zdekodowane

Wywołaj ChatStream zamiast Chat i obsłuż OnChatStream. Komponent prosi dostawcę o odpowiedź strumieniowaną, parsuje każde zdarzenie Server-Sent Event i podaje ci aChunk, czyli nowy tekst i nic więcej. Dopisujesz go, i to jest cała implementacja.

Każdy dostawca strumieniuje inny kształt JSON. OpenAI, DeepSeek, Ollama, Grok i Mistral umieszczają tekst w choices[0].delta.content, Claude w delta.text, a Gemini jeszcze głębiej, wewnątrz candidates. TsgcAIChat już wie, który z nich dotyczy wybranego przez ciebie dostawcy, więc twoja procedura obsługi nigdy nie widzi JSON.

Ustaw Cancel na True wewnątrz procedury obsługi, żeby zatrzymać rozpędzoną odpowiedź. Żądanie jest w tym momencie porzucane i żadne kolejne fragmenty nie przychodzą. Gdy strumień się kończy, złożony tekst trafia do historii i jest zwracany przez ChatStream, a OnChatMessage zgłasza się raz z kompletną odpowiedzią.

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;

Z klientem dostawcy, surowe zdarzenia

Klienty REST też strumieniują. Przypisz OnHTTPAPISSE i wywołaj skrót strumieniowy: _CreateMessageStream w Claude i w Ollama, a w OpenAI TsgcOpenAIClass_Request_ChatCompletion z Stream ustawionym na True. Zdarzenie daje ci aEvent, czyli nazwę zdarzenia Server-Sent Event, oraz aData, czyli ładunek tego zdarzenia, dokładnie tak, jak wysłał go dostawca.

Na tym poziomie sam parsujesz JSON, i o to chodzi: widzisz delty wywołań narzędzi, powody zatrzymania, zapisy zużycia i wszystko inne, co dostawca wysyła na łącze. Częściowe odczyty sieciowe są już za ciebie składane, więc zdarzenie rozbite na dwa odczyty TCP i tak przychodzi w całości, a JSON rozdzielany znakami nowej linii z Ollama jest dostarczany przez to samo zdarzenie.

Znaczniki końca różnią się między dostawcami. OpenAI zamyka dosłownym [DONE], Claude zdarzeniem o nazwie message_stop. Obsłuż oba, jeśli twój kod celuje w obu.

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;

Wątki. Chat i ChatStream są synchroniczne, więc wywołanie ich prosto z kliknięcia przycisku zamraża formularz na czas trwania żądania. W Delphi 2010 i nowszych ChatAsync uruchamia wywołanie w wątku roboczym i zwraca IsgcFuture<string>. Podłącz ThenProc dla wyniku i OnError dla błędów, a Cancel wywołaj, żeby porzucić żądanie w locie. Wywołanie zwrotne ThenProc jest wysyłane w wątku głównym, więc możesz z niego bezpośrednio dotykać interfejsu.

Pozwól modelowi wywołać twój kod Pascal

Tool calling, nazywane też function calling, to sposób, w jaki model prosi twoją aplikację o wyszukanie czegoś albo wykonanie akcji. Opisujesz funkcję za pomocą JSON Schema, model odpowiada argumentami, których chce, ty uruchamiasz kod Pascal i odsyłasz wynik. To jest mechanizm stojący za każdym użytecznym asystentem wewnątrz aplikacji biznesowej.

Claude, z typowanymi obiektami narzędzi

Zbuduj TsgcAnthropicClass_Request_Messages, dołącz jeden lub więcej wpisów TsgcAnthropicClass_Request_Tool i wywołaj CreateMessage. Każde narzędzie niesie Name, Description i InputSchema, czyli JSON Schema dla jego argumentów.

Odpowiedź to TsgcAnthropicClass_Response_Messages, którego Content jest tablicą bloków. Blok z ContentType równym 'tool_use' niesie Name narzędzia, argumenty w Input oraz Id. Uruchom swoją funkcję, a potem wyślij kolejną wiadomość zawierającą TsgcAnthropicClass_Request_Content_Block z ContentType ustawionym na 'tool_result', tym samym ToolUseId i twoją odpowiedzią w Content. Ustaw IsError, gdy wywołanie się nie powiodło, żeby model mógł się pozbierać zamiast zgadywać.

Zwróć uwagę na własność: żądanie Anthropic nie jest właścicielem dołączanych wiadomości i narzędzi, więc zwolnij je sam, tak jak w przykładzie.

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, z typowanym żądaniem

Ta sama idea, inny kształt. Wypełnij TsgcOpenAIClass_Request_ChatCompletion, przypisz tablicę Messages, umieść definicje narzędzi w Tools jako tablicę JSON i opcjonalnie steruj modelem przez ToolChoice. ParallelToolCalls decyduje, czy model może poprosić o kilka narzędzi naraz, a ResponseFormat przypina odpowiedź do JSON, gdy musisz ją sparsować.

CreateChatCompletion zwraca sparsowany TsgcOpenAIClass_Response_ChatCompletion. Odczytaj odpowiedź z Choices[0]._Message.Content, żądane wywołania z Choices[0]._Message.ToolCalls, powód zatrzymania modelu z Choices[0].FinishReason, a koszt z Usage.PromptTokens, Usage.CompletionTokens i Usage.TotalTokens. W odróżnieniu od żądania Anthropic, to jest właścicielem dołączanych obiektów wiadomości i zwalnia je razem z sobą.

Starsze właściwości Functions i FunctionCall nadal tam są, dla kodu napisanego pod pierwotny kształt function calling w 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;

Model hostowany czy model lokalny

Jeśli twoje prompty zawierają dane klientów, dane medyczne, umowy albo cokolwiek objętego umową powierzenia przetwarzania danych, to nie jest pytanie o wydajność, tylko o zgodność z przepisami. Oto zestawienie.

Hostowany, OpenAI lub Claude Lokalny, Ollama
Dokąd trafia prompt Do dostawcy, przez HTTPS, na jego warunkach Nigdzie. Żądanie idzie do http://localhost:11434
Poświadczenia Klucz API, który musisz trzymać poza kontrolą wersji i poza binarium Domyślnie żadne. OllamaOptions.ApiKey istnieje dla instancji za proxy lub zdalnej
Jakość odpowiedzi Najmocniejsze modele dostępne dzisiaj Dobre i coraz lepsze, wyraźnie za czołówką przy trudnym rozumowaniu
Koszt Za token, bez końca. Obserwuj Usage.TotalTokens Twój sprzęt, jednorazowo. Użyteczny model chce dużo RAM albo GPU
Opóźnienie Podróż w obie strony przez sieć, plus kolejkowanie u dostawcy w godzinach szczytu Brak sieci. Szybkość jest taka, jaką daje twoja maszyna
Offline i w sieci odciętej Nie Tak
Limity zapytań i awarie Po stronie dostawcy. Użyj RetryOptions i respektuj Retry-After Tylko twoja własna przepustowość
Komponent TsgcHTTP_API_OpenAI, TsgcHTTP_API_Anthropic TsgcHTTP_API_Ollama

Częstą odpowiedzią jest jedno i drugie. Ponieważ TsgcAIChat stawia każdego dostawcę za jednym API, możesz kierować ruch według klasyfikacji danych w czasie działania: lokalnie wszystko, co dotyka rekordu klienta, hostowany dostawca dla reszty. Przełącznikiem jest Provider, plus ChatOptions.BaseUrl, gdy dostawcą jest 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);

Ustawienia, które mają znaczenie na produkcji

Demo, które działa na twoim biurku, to nie to samo, co klient, który przeżyje limit zapytań, wolny model i zgłoszenie do wsparcia o treści "po prostu przestało działać".

Ponowienia i backoff

Każdy klient ma blok RetryOptions: Enabled, Retries, Wait, Multiplier, MaxInterval, Jitter i HonorRetryAfter. Włącz go, a przejściowa awaria zostanie ponowiona z wykładniczym backoffem, zamiast wypłynąć jako wyjątek. HonorRetryAfter sprawia, że klient słucha nagłówka Retry-After od dostawcy, zamiast zgadywać.

Limity czasu

HttpOptions.ReadTimeout to ten, który warto podnieść. Długie generowanie, zwłaszcza na modelu lokalnym, może trwać dłużej niż domyślny limit odczytu HTTP i przerwać się w połowie odpowiedzi, która szła dobrze.

Logi

LogOptions.Enabled plus LogOptions.FileName zapisuje ruch do pliku. Gdy prompt zachowuje się inaczej na produkcji, to jest najszybszy sposób, żeby zobaczyć JSON, który twój kod naprawdę wysłał.

Historia rozmowy

TsgcAIChat przechowuje wymianę zdań i odtwarza ją przy następnym wywołaniu, i to właśnie sprawia, że pytanie uzupełniające działa. Ogranicz ją przez MaxHistoryMessages, żeby długa sesja nie powiększała promptu, a więc i rachunku, bez końca. ClearHistory zaczyna od nowa, a GetHistory udostępnia Count i poszczególne wiadomości.

Azure OpenAI

Ustaw OpenAIOptions.Provider na oapvAzure i wypełnij AzureOptions.ResourceName, AzureOptions.DeploymentId oraz AzureOptions.APIVersion. Reszta twojego kodu zostaje bez zmian, co ma znaczenie, gdy dział zakupów wymaga, żeby ruch pozostał wewnątrz twojego tenanta Azure.

Błędy i bezpiecznik

OnHTTPAPIException wydobywa błędy z klientów REST, a OnChatError robi to samo dla TsgcAIChat. Błąd HTTP przychodzi jako EsgcHTTPAPIProtocolException, który nadal dziedziczy po EIdHTTPProtocolException i dodatkowo niesie nagłówki odpowiedzi. CircuitBreaker i RateLimit są dostępne na kliencie dla wywołań, które wykonujesz sam.

Co ludzie budują po pierwszym wywołaniu

Okienko czatu to dopiero początek. Oto cztery kierunki, w których zwykle idzie ta praca, i każdy z nich jest już w bibliotece.

Odpowiadaj na podstawie własnych danych

Zamień swoje dokumenty na wektory za pomocą TsgcAIOpenAIEmbeddings, przechowaj je w TsgcAIDatabaseVectorFile albo TsgcAIDatabaseVectorPinecone i pobieraj najbliższe fragmenty, żeby wstawić je do promptu. To jest retrieval augmented generation, i tak powstrzymujesz model przed wymyślaniem odpowiedzi o twojej firmie.

Embeddingi i bazy danych wektorowych

Mów do niego i pozwól mu odpowiadać

TsgcAIOpenAIChatBot łączy rejestrator dźwięku, transkrypcję, wywołanie czatu i syntezę mowy w jeden komponent, więc użytkownik może prowadzić rozmowę głosową z twoją aplikacją. TsgcAIOpenAITranslator robi to samo dla tłumaczenia na żywo.

AI ChatBot i AI Translator

Udostępnij swoją aplikację agentowi AI

Model Context Protocol to sposób, w jaki asystenci odkrywają i wywołują narzędzia. TsgcWSServer_API_MCP zamienia twoją aplikację Delphi w serwer MCP, którym mogą sterować Claude i inne klienty, a TsgcWSAPI_Client_MCP konsumuje inne serwery z poziomu twojego kodu. Na palecie pojawiają się jako TsgcWSAPIServer_MCP i TsgcWSAPIClient_MCP.

Warto wiedzieć: w odróżnieniu od komponentu czatu, moduły MCP nie są ograniczone do Windows, więc serwer MCP napisany w Delphi może działać na Linuksie.

przegląd MCP, serwer MCP i klient MCP

Wykorzystaj resztę API każdego dostawcy

Generowanie obrazów, transkrypcja, moderacja, wsady i dostrajanie w OpenAI. Wizja, dokumenty, rozszerzone myślenie, wyszukiwanie w sieci i liczenie tokenów w Claude. Embeddingi i zarządzanie modelami w Ollama. Strona każdego dostawcy wymienia to, co udostępnia jego klient.

OpenAI, Claude i Ollama

Dokumentacja referencyjna, dema i samouczki

Dokumentacja referencyjna komponentów opisuje każdą właściwość i każde zdarzenie. Gotowe do uruchomienia projekty demo są dołączone do biblioteki, w katalogu Demos\AI.

Dokumentacja referencyjna, klient OpenAI Każda metoda, opcja i zdarzenie w TsgcHTTP_API_OpenAI.
Dokumentacja referencyjna, klient Anthropic Wiadomości, narzędzia, wizja, wsady i liczenie tokenów w TsgcHTTP_API_Anthropic.
Samouczek, Claude z Delphi Obszerne omówienie klienta Anthropic, od początku do końca.
Samouczek, modele lokalne w Ollama Pobierz model, skieruj klienta na localhost i uruchom go offline.
Samouczek, function calling Podłączanie modelu do twoich własnych funkcji Pascal, krok po kroku.
Podręcznik użytkownika (PDF) Kompletny podręcznik obejmujący każdy komponent w bibliotece.

Więcej do przeczytania: klient OpenAI z Delphi, budowanie chatbota AI, budowanie agenta AI i klient MCP. Strony docelowe komponentów to klient OpenAI dla Delphi i API Anthropic.

Ta strona jest jednym z przypadków użycia Delphi, z których każdy prowadzi jedno zadanie od początku do końca. Pozostałe jak dotąd to logowanie użytkownika za pomocą OAuth2 i PKCE oraz połączenie dwóch aplikacji peer to peer przez WebRTC.

Najczęściej zadawane pytania

Utwórz TsgcAI_Chat z modułu sgcAI_Chat, ustaw Provider na wybranego dostawcę, ustaw ChatOptions.ApiKey i ChatOptions.Model, a potem wywołaj Chat('your prompt'), co zwróci odpowiedź jako łańcuch znaków. Jeśli wolisz rozmawiać bezpośrednio z API jednego dostawcy, użyj TsgcHTTP_API_OpenAI, TsgcHTTP_API_Anthropic lub TsgcHTTP_API_Ollama i wywołaj _CreateChatCompletion albo _CreateMessage. Oba podejścia są dostarczane w sgcWebSockets i w samodzielnym pakiecie sgcAI, i działają od Delphi 7 do RAD Studio 13.
Wywołaj ChatStream zamiast Chat i obsłuż OnChatStream, które zgłasza się z aChunk, czyli zdekodowanym tekstem każdej delty, oraz z flagą Cancel, którą możesz ustawić, żeby zatrzymać się wcześniej. Na poziomie klienta REST przypisz OnHTTPAPISSE i wywołaj _CreateMessageStream na klientach Claude i Ollama, albo ustaw Stream na True w TsgcOpenAIClass_Request_ChatCompletion. To zdarzenie daje ci surową nazwę i dane zdarzenia Server-Sent Event, z już poskładanymi częściowymi odczytami sieciowymi.
Tak. Zainstaluj Ollama, pobierz model, a potem skieruj na niego TsgcHTTP_API_Ollama. OllamaOptions.Host domyślnie wskazuje już http://localhost:11434, więc przy domyślnej instalacji wybierasz tylko model i wywołujesz _CreateMessage. Nic nie opuszcza maszyny, klucz API nie jest potrzebny, a aplikacja działa offline. Przez TsgcAIChat ten sam serwer osiągniesz, ustawiając Provider na aicpOllama oraz, gdy serwer nie jest na localhost, ChatOptions.BaseUrl.
Opisz funkcję za pomocą JSON Schema i dołącz ją do żądania. W Claude dodaj TsgcAnthropicClass_Request_Tool z Name, Description i InputSchema do tablicy Tools w TsgcAnthropicClass_Request_Messages. Odpowiedź zawiera wtedy blok treści, którego ContentType to tool_use, niosący Name, Input i Id, a ty odpowiadasz blokiem tool_result przywołującym ten sam ToolUseId. W OpenAI umieść definicje we właściwości Tools obiektu TsgcOpenAIClass_Request_ChatCompletion i odczytaj żądane wywołania z Choices[0]._Message.ToolCalls.
Klienty AI i LLM to funkcja Enterprise w sgcWebSockets. Nie są zawarte w edycjach Standard ani Professional. Jeśli nie potrzebujesz reszty sgcWebSockets, samodzielny pakiet sgcAI zawiera te same komponenty razem z potrzebnym im środowiskiem uruchomieniowym. Biblioteka wspiera Delphi 7 do RAD Studio 13 oraz odpowiadające im wersje C++ Builder. Co do platform, klienty REST TsgcHTTP_API_OpenAI, TsgcHTTP_API_Anthropic i TsgcHTTP_API_Ollama kompilują się dla Windows, macOS, Linux, iOS i Android, natomiast TsgcAIChat jest kompilowany tylko dla Windows, Win32 i Win64. Klient i serwer MCP też nie są ograniczone do Windows.
W przypadku dostawców hostowanych tak. Komponenty są klientami REST, więc przynosisz klucz z własnego konta OpenAI, Anthropic, Google, xAI, DeepSeek lub Mistral i przypisujesz go do ChatOptions.ApiKey albo do opcji dostawcy, takich jak OpenAIOptions.ApiKey. Zużycie jest rozliczane przez tego dostawcę na twój klucz, a możesz je śledzić dla każdej odpowiedzi przez Usage.PromptTokens, Usage.CompletionTokens i Usage.TotalTokens. Ollama nie potrzebuje klucza, bo model działa lokalnie.
Chat i ChatStream są synchroniczne. W Delphi 2010 i nowszych wywołaj zamiast tego ChatAsync: uruchamia żądanie w wątku roboczym i zwraca IsgcFuture typu string, więc podłączasz ThenProc, żeby odebrać odpowiedź, OnError, żeby odebrać wyjątek, i Cancel, żeby porzucić żądanie w locie. Wywołanie zwrotne ThenProc jest wysyłane w wątku głównym, więc można z niego bezpiecznie aktualizować interfejs. Podnieś też HttpOptions.ReadTimeout, bo długie generowanie może przeżyć domyślny limit odczytu.
Tak. Ustaw OpenAIOptions.Provider na oapvAzure i wypełnij AzureOptions.ResourceName, AzureOptions.DeploymentId oraz AzureOptions.APIVersion. Klient celuje wtedy w twoje wdrożenie Azure, a wywołania, które już napisałeś, zostają dokładnie takie same.

Gotowy, żeby wywołać LLM ze swojej aplikacji Delphi?

Pobierz bezpłatną wersję próbną i wykonaj swoje pierwsze wywołanie już dziś.