Anthropic Claude in Delphi — Volledige tutorial (2026)

· Componenten

Waarom een native Delphi-component voor Claude?

Anthropic Claude is een van de meest capabele AI-families op de markt, maar elk publiek voorbeeld gebruikt Python of Node. Voor Delphi- en C++Builder-ontwikkelaars betekent het met de hand aanroepen van de REST-endpoints handmatig JSON in elkaar zetten, jongleren met Server-Sent Events, TLS beheren, rate limits afhandelen en boilerplate herschrijven telkens wanneer Anthropic een nieuwe feature uitbrengt — wat ongeveer elk kwartaal gebeurt. De TsgcHTTP_API_Anthropic-component die met sgcWebSockets wordt geleverd, neemt die frictie weg. Het is een sterk getypeerde wrapper rond het volledige Anthropic-oppervlak — messages, streaming, vision, tool use, extended thinking, prompt caching, files, batches en de Model Context Protocol-connector — die je op een formulier kunt plaatsen en kunt gebruiken vanuit elke VCL-, FMX- of console-applicatie.

Deze tutorial doorloopt elke belangrijke capability met werkende Delphi-code. Aan het eind kun je een chat-client, een vision-enabled documentanalyser, een agentic tool runner en een kostengeoptimaliseerde productie-pipeline bouwen. Alle snippets richten zich op de nieuwste claude-sonnet-4-20250514- en claude-opus-4-20250514-modellen, en ze draaien allemaal ongewijzigd op Delphi 7 t/m Delphi 13.

Een korte opmerking over filosofie voordat we erin duiken. De component stelt opzettelijk twee oppervlakken bloot. Het “snelle” oppervlak (methodes zoals _CreateMessage, _CreateMessageStream, _CreateMessageWithImage) accepteert een paar strings en geeft een string terug — perfect voor prototypes, demo’s, en de 80% van de calls waar je niet om temperature, top-p, metadata of stop sequences geeft. Het “typed” oppervlak (klassen als TsgcAnthropicClass_Request_Messages en TsgcAnthropicClass_Response_Messages) geeft je volledige controle over elke parameter die de Anthropic-API ondersteunt, met sterke typering en IDE-auto-completion. Gebruik de snelle API om te leren; promoveer naar de typed API voor productie. Dezelfde component, twee lagen, geen duplicatie.

1. Setup en je eerste message

Voeg sgcHTTP_API_Anthropic toe aan je uses-clausule, maak de component aan, stel je API-sleutel in (haal er een op via console.anthropic.com), en roep _CreateMessage aan. Dit is het absolute minimum om met Claude te praten.

uses
  sgcHTTP_API_Anthropic;

var
  oClaude: TsgcHTTP_API_Anthropic;
  vReply : string;
begin
  oClaude := TsgcHTTP_API_Anthropic.Create(nil);
  try
    oClaude.AnthropicOptions.ApiKey := 'sk-ant-api03-...';
    vReply := oClaude._CreateMessage(
      'claude-sonnet-4-20250514',
      'Write a haiku about Pascal compilers.');
    ShowMessage(vReply);
  finally
    oClaude.Free;
  end;
end;

De component doet het zware werk: hij bouwt de JSON-request-body, zet de x-api-key- en anthropic-version-headers, post naar /v1/messages, en parset het antwoord tot een gewone Delphi-string. Als je volledige controle nodig hebt over request-parameters, gebruik dan de typed TsgcAnthropicClass_Request_Messages-klasse.

Een operationele tip: bak de API-sleutel nooit in in de binary. Lees hem uit een environment-variabele, een registersleutel of een secrets manager. Anthropic scant nu GitHub op gelekte sleutels en trekt ze automatisch in — je wilt geen update om 18.00 uur op vrijdag uitbrengen omdat iemand je .pas-bestand schermafdrukt heeft.

2. Streaming responses met SSE

Synchrone calls zijn prima voor korte prompts, maar voor een chat-UI wil je dat tokens verschijnen terwijl Claude ze genereert. Anthropic streamt antwoorden als Server-Sent Events, en de component stelt ze bloot via het OnHTTPAPISSE-event.

procedure TForm1.FormCreate(Sender: TObject);
begin
  oClaude := TsgcHTTP_API_Anthropic.Create(Self);
  oClaude.AnthropicOptions.ApiKey := 'sk-ant-api03-...';
  oClaude.OnHTTPAPISSE := ClaudeSSE;
end;

procedure TForm1.ClaudeSSE(Sender: TObject;
  const aEvent, aData: string; var Cancel: Boolean);
var
  vDelta: string;
begin
  // aEvent values: message_start, content_block_delta,
  //                content_block_stop, message_stop
  if aEvent = 'content_block_delta' then
  begin
    vDelta := oClaude.SSEExtractText(aData);
    Memo1.Text := Memo1.Text + vDelta;
    Application.ProcessMessages;
  end;
end;

procedure TForm1.btnAskClick(Sender: TObject);
begin
  Memo1.Clear;
  oClaude._CreateMessageStream(
    'claude-sonnet-4-20250514',
    edtPrompt.Text);
end;

Een detail dat het noemen waard is: streaming draait op een achtergrondthread, dus update de UI via TThread.Synchronize of TThread.Queue in productiecode. De snippet hierboven gebruikt ProcessMessages voor de beknoptheid. Nog een: de SSE-stream stuurt meerdere event-types op volgorde (message_start, content_block_start, herhaalde content_block_delta, content_block_stop, message_delta, message_stop) en je zou de events die je niet nodig hebt moeten negeren. De helper SSEExtractText handelt het veelvoorkomende geval af van de tekstdelta uit content_block_delta halen; voor usage-stats en stop-redenen parse je message_delta direct.

Streaming is essentieel voor elke gebruikersgerichte chat-UI — gebruikers ervaren een antwoord dat in 400 ms begint als snel, zelfs als het volledige antwoord tien seconden duurt. Zonder streaming staren ze tien seconden naar een spinner en gaan ervan uit dat de app kapot is. De kosten zijn identiek: streaming- en non-streaming-requests worden hetzelfde gefactureerd.

3. Vision — afbeeldingen versturen

Claude kan JPEG-, PNG-, GIF- en WebP-afbeeldingen analyseren. Je geeft ze door als publieke URL of als base64-gecodeerde bytes. De component stelt _CreateMessageWithImage bloot voor het URL-geval en de typed API voor al het andere.

var
  oRequest : TsgcAnthropicClass_Request_Messages;
  oMessage : TsgcAnthropicClass_Request_Message;
  oImage   : TsgcAnthropicClass_Request_Content_Image;
  oResponse: TsgcAnthropicClass_Response_Messages;
begin
  oRequest := TsgcAnthropicClass_Request_Messages.Create;
  try
    oRequest.Model     := 'claude-sonnet-4-20250514';
    oRequest.MaxTokens := 1024;

    oMessage := oRequest.NewMessage('user');
    oMessage.AddText('Describe what you see and read any text.');

    oImage := oMessage.AddImage;
    oImage.Source.LoadFromFile('C:\invoices\inv-2026-05-12.png');
    oImage.MediaType := 'image/png';

    oResponse := oClaude.CreateMessage(oRequest);
    try
      Memo1.Lines.Add(oResponse.Content[0].Text);
    finally
      oResponse.Free;
    end;
  finally
    oRequest.Free;
  end;
end;

Vision is ideaal voor OCR op gescande facturen, screenshot-triage in supporttickets, grafiekinterpretatie en elke taak waar een deterministische OCR-engine zou worstelen met layout. Let op de token-kosten: een 1024x1024-afbeelding verbruikt grofweg 1.600 input-tokens. Anthropic verkleint alles groter dan 1568px op de lange zijde voor verwerking, dus het heeft geen zin om 4K-screenshots te uploaden — verklein aan jouw kant en bespaar de bandbreedte.

Praktische use cases die we Delphi-shops het afgelopen jaar hebben zien leveren: regelitems extraheren uit leveranciers-PDF’s die te inconsistent waren voor traditionele OCR-pipelines, medische beelden classificeren in brede categorieen voordat ze naar specialistische software werden gerouteerd, meterstanden uit field-service-foto’s lezen, en UI-bug-screenshots triageren in helpdesktickets (“laat de screenshot een layout-probleem of een data-probleem zien?”). In elk geval was de winst niet ruwe nauwkeurigheid — het was het elimineren van de noodzaak om een brosse, per-document parser te schrijven en te onderhouden.

4. Tool use (function calling)

Tool use laat Claude beslissen wanneer hij je Pascal-functies aanroept. Je declareert elke tool met een naam, beschrijving en JSON Schema voor zijn parameters. Wanneer Claude antwoordt met een tool_use-blok in plaats van platte tekst, voer je de aanroep uit en voer je het resultaat terug in het gesprek.

var
  oRequest: TsgcAnthropicClass_Request_Messages;
  oTool   : TsgcAnthropicClass_Request_Tool;
begin
  oRequest := TsgcAnthropicClass_Request_Messages.Create;
  oRequest.Model     := 'claude-sonnet-4-20250514';
  oRequest.MaxTokens := 1024;

  oTool := oRequest.NewTool;
  oTool.Name        := 'get_stock_price';
  oTool.Description := 'Return the current bid/ask for a US ticker symbol.';
  oTool.InputSchema :=
    '{"type":"object",' +
     '"properties":{"symbol":{"type":"string","description":"Ticker, e.g. AAPL"}},' +
     '"required":["symbol"]}';

  oRequest.NewMessage('user').AddText('What is Apple trading at?');

  oResponse := oClaude.CreateMessage(oRequest);
  if oResponse.StopReason = 'tool_use' then
  begin
    vSymbol := oResponse.ToolUse[0].InputAsJSON.S['symbol'];
    vPrice  := MyQuoteFeed.Quote(vSymbol);        // your code
    oClaude.SendToolResult(oResponse.ToolUse[0].Id,
      Format('{"bid":%.2f,"ask":%.2f}', [vPrice.Bid, vPrice.Ask]));
  end;
end;

Bouw agentic workflows door tools aan elkaar te koppelen: een research-agent zou web_search-, read_pdf- en send_email-tools kunnen combineren. Houd altijd een iMaxIterations-guard zodat een misdragend model niet eeuwig kan loopen. In productie cappen we op vijf tool-calls per gebruikersbeurt om kostenredenen; als Claude meer nodig heeft, is dat meestal een teken dat de prompt of het tool-ontwerp fout is.

De grootste enkele bepaler van tool-calling-kwaliteit is de beschrijvingstekst. Modellen kiezen de juiste tool met de juiste argumenten ongeveer 99% van de tijd wanneer beschrijvingen precies zijn (“Return the current bid/ask for a US ticker symbol. Use this only for equities, not for crypto or FX”); ze dalen tot misschien 70% met een vage beschrijving (“Get a price”). Neem de tijd. Voeg voorbeelden toe in de beschrijving. Stel wat de tool NIET doet. Toekomstige-jij, debuggend op een $0,40 gehallucineerde functie-aanroep om 23.00 uur, zal huidige-jij bedanken.

5. Extended thinking

Claude 4 introduceert een thinking-modus waarbij het model stapsgewijs door een probleem redeneert voor het antwoordt. Je wijst een thinking-budget toe in tokens, en Claude geeft het redeneerspoor apart van het uiteindelijke antwoord terug. Dit is een game changer voor wiskunde, code review en multi-step-analyse.

oRequest.Thinking.Enabled       := True;
oRequest.Thinking.BudgetTokens  := 8000;   // soft cap on internal reasoning
oRequest.MaxTokens              := 16000;

oRequest.NewMessage('user').AddText(
  'A train leaves Madrid at 07:00 doing 220 km/h. Another leaves ' +
  'Barcelona at 07:15 doing 250 km/h. The route is 621 km. ' +
  'Where do they meet?');

oResponse := oClaude.CreateMessage(oRequest);
MemoThinking.Lines.Text := oResponse.Thinking;   // reasoning trace
MemoAnswer.Lines.Text   := oResponse.Content[0].Text;

Gebruik extended thinking spaarzaam — reasoning tokens worden als output gefactureerd, dus een 16k-token thinking-budget op Opus 4 kan makkelijk meer kosten dan een normale call. Reserveer het voor problemen waar correctheid meer telt dan latentie. Goede fits: juridische documentanalyse, financiele reconciliatie, complexe SQL-generatie, debuggen van stack traces, multi-constraint-planning. Slechte fits: chat-antwoorden, content-classificatie, simpele lookups — de denktijd en -kosten zijn niet gerechtvaardigd.

Een nuttige truc is het redeneerspoor in je UI bloot te stellen als een uitklapbare “show thinking”-sectie, zoals de publieke Claude-app doet. Power users zijn dol op het zien hoe het model bij het antwoord kwam; casual users negeren het. Hoe dan ook heb je gratis een audit trail.

6. Prompt caching

Als je dezelfde lange system prompt, kennisbank of tool-definities blijft sturen, kan prompt caching de kosten met tot 90% verlagen en de tijd tot eerste token met 80% verkorten. Je markeert een content-blok als cachebaar; Anthropic slaat het 5 minuten aan hun kant op (of 1 uur met de uitgebreide cache) en factureert alleen de goedkopere cache-read-prijs op volgende calls.

var
  oSystem: TsgcAnthropicClass_Request_System;
begin
  oSystem := oRequest.NewSystemBlock;
  oSystem.Text         := LoadFile('C:\kb\product-manual.txt'); // 50k tokens
  oSystem.CacheControl := 'ephemeral';        // mark as cacheable

  oRequest.NewMessage('user').AddText('How do I configure SSL on the server?');
  oResponse := oClaude.CreateMessage(oRequest);

  // Inspect cache stats
  ShowMessage(Format('Cache: created=%d, read=%d, input=%d, output=%d',
    [oResponse.Usage.CacheCreationInputTokens,
     oResponse.Usage.CacheReadInputTokens,
     oResponse.Usage.InputTokens,
     oResponse.Usage.OutputTokens]));
end;

Vuistregel: alles boven de 1.024 tokens dat je binnen vijf minuten hergebruikt, is cachen waard. Grote documentatie-corpora, few-shot-voorbeelden en grote tool-schema’s zijn de voor de hand liggende kandidaten. De boekhouding: cache writes kosten 25% meer dan een normale input-token, cache reads kosten 10% van een normale input-token. Dus je breekt na de tweede hit even en begint vanaf de derde echt geld te besparen. Voor een customer support-bot die 50 vragen per minuut beantwoordt tegen een 40k-token kennisbank, snijdt prompt caching de maandelijkse Anthropic-rekening typisch met 80–85%.

Je kunt per request tot vier content-blokken als cachebaar markeren. Een veelvoorkomend patroon is: tools (cachebaar, verandert zelden), system prompt (cachebaar, verandert zelden), groot document (cachebaar, verandert per sessie), recente messages (NIET cachebaar, verandert elke beurt). De component handelt deze gelaagdheid natuurlijk af — zet gewoon CacheControl op welke blokken je gecached wilt hebben.

7. MCP-connector

Het Model Context Protocol laat Claude praten met externe tool-servers zonder dat je elke tool met de hand moet wrappen. Wijs de component naar een MCP-server-URL en Claude kan de tools ontdekken, aanroepen en de resultaten aan elkaar koppelen.

oRequest.MCPServers.Add(
  'weather-mcp',
  'https://mcp.example.com/weather',
  'Bearer ' + GetMcpToken);

oRequest.NewMessage('user').AddText(
  'What is the weather like in Madrid and should I take an umbrella?');

oResponse := oClaude.CreateMessage(oRequest);
ShowMessage(oResponse.Content[0].Text);

Combineer de MCP-connector met je eigen TsgcAI_MCP_Server (behandeld in een aparte tutorial) en je hebt een volledig Delphi-native agent die je domein-API’s blootstelt aan elke MCP-bewuste AI-client — Claude Desktop, Cursor, Continue, je eigen apps, alles dat het protocol spreekt. Authenticatie is jouw verantwoordelijkheid: geef een bearer-token of getekende header door, en valideer aan de server-kant. Anthropic ziet je credentials niet — de MCP-connector-handshake routeert de token van het request naar de doelserver.

Voor multi-tenant SaaS-deployments is het typische patroon een enkele MCP-server per tenant, met de tenant-ID ingebed in de URL of het bearer-token. Claude roept de tools van elke tenant aan zonder ooit data te cross-contamineren. We hebben productie-deployments gezien die uitwaaieren naar 200+ MCP-servers vanuit een enkel gesprek.

Productie-checklist

Voordat je een Anthropic-aangedreven Delphi-app in productie zet, loop deze korte lijst door:

ZorgHoe ermee om te gaan
Opslag van API-sleutelEnvironment-variabele of OS secret store, nooit hard-coded
Retries bij 429 / 529Exponentiele backoff met jitter, max 3 pogingen
KostenplafondsVolg Usage per request, weiger nieuwe calls voorbij dagbudget
PII-redactieStrip emails/BSN/CC-nummers voordat je naar de API stuurt
Modelversie-pinningGebruik volledige gedateerde modelnamen; vertrouw niet op “latest”-aliassen
Prompt-versioneringBewaar system prompts in source control naast code
TelemetrieLog model, input-tokens, output-tokens, latentie per call

Waar nu naartoe

Deze tutorial behandelde de acht features die je 95% van de tijd nodig hebt. De component ondersteunt ook message batches (goedkope async verwerking van duizenden prompts — 50% goedkoper dan synchrone calls, ideaal voor nachtelijke verrijkingsjobs), de Files API (een keer uploaden, voor altijd refereren — perfect voor grote PDF’s die je herhaaldelijk bevraagt), token counting (kosten schatten voor je betaalt), en gestructureerde JSON-outputs (geforceerde schema-conformiteit, geen parse-fouten meer). Blader naar de Anthropic-componentpagina voor de volledige feature-matrix en ga naar de Aan de slag-hub als je sgcWebSockets nog niet hebt geinstalleerd.

En als je iets interessants bouwt met Claude in Delphi — een agent, een copilot, een doc-analyser — vertel het ons. We zien graag wat Pascal-ontwikkelaars doen zodra de AI-frictie verdwijnt.