In den meisten Geschäftsanwendungen gibt es noch immer jemanden, der eine PDF-Datei liest und ihre Zahlen von Hand in ein Formular tippt. Lieferantenrechnungen, Kassenbons, der Scan eines Personalausweises am Empfang. Die großen Sprachmodelle lesen solche Dokumente heute gut, aber wer ein Modell nach "den Rechnungsdaten" fragt, bekommt Fließtext oder JSON in einer Form, die sich das Modell gerade ausgedacht hat, und keine Möglichkeit zu erkennen, bei welchen Werten es sich unsicher war.
sgcWebSockets 2026.10 fügt TsgcAIDocumentExtractor für Delphi, C++Builder und .NET hinzu. Sie übergeben eine PDF-Datei oder ein Bild, die Komponente fragt das Modell, das Sie bereits über TsgcAIChat verwenden, und liefert JSON zurück, das gegen ein Schema validiert wurde, mit einer Konfidenz für jedes Feld. Die Komponente ist nicht Teil des aktuellen Downloads. Sie kommt mit dem Release 2026.10.
TsgcAIDocumentExtractor liest eine echte Rechnungs-PDF mit Anthropic Claude und liefert validiertes JSON mit einer Konfidenz pro Feld. Auch auf YouTube.
Eine PDF hinein, JSON heraus
Platzieren Sie ein TsgcAIChat und ein TsgcAIDocumentExtractor auf einem Formular, verweisen Sie den Extraktor auf den Chat, wählen Sie ein Preset und rufen Sie ExtractFile auf. OpenAI, Anthropic und Gemini lesen PDF-Dateien so, wie sie sind. DeepSeek, Grok, Mistral und Ollama nehmen Bilder entgegen, daher senden Sie bei diesen Anbietern die Seiten als PNG oder JPEG.
uses
sgcAI, sgcAI_Chat, sgcAI_DocumentExtractor;
procedure TForm1.btnExtractClick(Sender: TObject);
begin
oChat := TsgcAIChat.Create(Self);
oChat.Provider := aicpAnthropic;
oChat.ChatOptions.ApiKey := 'your-api-key';
oExtractor := TsgcAIDocumentExtractor.Create(Self);
oExtractor.AIChat := oChat;
oExtractor.Preset := dpInvoice;
Memo1.Lines.Text := oExtractor.ExtractFile('invoice.pdf');
end;
Das ist der im Video gezeigte Ablauf, und er wurde live gegen Anthropic Claude an einer echten Rechnungs-PDF verifiziert. ExtractFiles sendet mehrere Seiten eines Dokuments in einer einzigen Anfrage, und ExtractAttachments nimmt Dokumente entgegen, die Sie bereits als Base64 im Speicher halten.
Der Extraktor erledigt seine Arbeit über TsgcAIChat, das dieselben Fähigkeiten auch für Ihre eigenen Prompts erhält. ChatWithDocument sendet eine PDF-Datei oder ein Bild mit einer Nachricht, ChatWithAttachments sendet mehrere auf einmal, und ChatJSONWithAttachments fragt nach einer JSON-Antwort dazu. Eine neue Eigenschaft TLSOptions legt die OpenSSL-Version, den IOHandler und die Zertifikate für jeden Anbieter fest.
Memo1.Lines.Text := oChat.ChatWithDocument('Summarize this contract', 'contract.pdf');
oFiles := TsgcAIChatAttachments.Create;
try
oFiles.AddFile('page1.png');
oFiles.AddFile('page2.png');
Memo1.Lines.Text := oChat.ChatJSONWithAttachments(
'List every line item as JSON', oFiles);
finally
oFiles.Free;
end;
Presets und Ihr eigenes Schema
Drei Presets decken die gängigen Dokumente ab: dpInvoice, dpReceipt und dpIDCard. Jedes bringt sein eigenes JSON-Schema und seine eigenen Extraktionsanweisungen mit, sodass nichts weiter zu konfigurieren ist. Für jedes andere Dokument setzen Sie Preset auf dpCustom und schreiben das Schema selbst.
oExtractor.Preset := dpCustom;
oExtractor.SchemaName := 'purchase_order';
oExtractor.Schema.Text :=
'{"type": "object", "additionalProperties": false,' +
' "required": ["order_number", "supplier", "total"],' +
' "properties": {' +
' "order_number": {"type": "string"},' +
' "supplier": {"type": ["string", "null"]},' +
' "total": {"type": "number"}}}';
oExtractor.Instructions.Text := 'Write every amount without a currency symbol.';
Bei OpenAI wird das Schema im Strict-Modus gesendet, daher muss es den Strict-Regeln folgen: jedes Objekt deklariert "additionalProperties": false, jede Eigenschaft steht in required, und ein optionaler Wert verwendet einen nullbaren Typ wie ["string", "null"]. Die eingebauten Presets folgen diesen Regeln bereits. Um von einem davon auszugehen und ein Feld hinzuzufügen, kopieren Sie es mit TsgcAIDocumentExtractor.GetPresetSchema(dpInvoice).
Validierung und Wiederholung
Die Antwort erreicht Ihren Code nie ungeprüft. Der Extraktor validiert sie lokal gegen das Schema: Typen, erforderliche Eigenschaften, verschachtelte Objekte und Arrays sowie Enums. Stimmt sie nicht überein, teilt die Komponente dem Modell mit, was falsch war, und fragt noch einmal. ValidationRetries legt fest, wie oft, und der Standardwert ist 1.
Sind die Daten nach den Wiederholungen immer noch ungültig, löst der Extraktor eine Exception aus. Setzen Sie RaiseOnInvalid auf False, um die Daten trotzdem zu erhalten und die Probleme aus LastResult.ValidationErrors zu lesen, jeweils eine Zeile path: message.
oExtractor.ValidationRetries := 1;
oExtractor.RaiseOnInvalid := False;
Memo1.Lines.Text := oExtractor.ExtractFile('invoice.pdf');
if not oExtractor.LastResult.Valid then
Memo1.Lines.AddStrings(oExtractor.LastResult.ValidationErrors);
Konfidenz und menschliche Prüfung
Gültiges JSON ist nicht dasselbe wie korrektes JSON. Ein verschwommener Gesamtbetrag oder ein verwischtes Datum kann trotzdem eine wohlgeformte Zahl ergeben. Deshalb meldet das Modell auch, wie sicher es sich bei jedem extrahierten Feld ist, und der Extraktor gibt Ihnen diese Werte weiter. LastResult.Confidence ist der niedrigste davon, LastResult.FieldConfidence('total') liefert den Wert für einen Pfad, und OnLowConfidence feuert einmal für jedes Feld unter MinConfidence.
oExtractor.MinConfidence := 0.8;
oExtractor.OnLowConfidence := OnLowConfidenceEvent;
Memo1.Lines.Text := oExtractor.ExtractFile('invoice.pdf');
if oExtractor.LastResult.FieldConfidence('total') < 0.8 then
ShowMessage('Check the total by hand');
procedure TForm1.OnLowConfidenceEvent(Sender: TObject; const aField: string;
aConfidence: Double);
begin
lstReview.Items.Add(Format('%s: %.2f', [aField, aConfidence]));
end;
Das macht aus einer Prüfwarteschlange etwas, das eine Person tatsächlich bewältigen kann: Sie prüfen die zwei Felder, bei denen das Modell gezweifelt hat, nicht die ganze Rechnung.
Lokale OCR, nichts verlässt die Maschine
Manche Dokumente dürfen überhaupt nicht an einen Cloud-Dienst gehen. Verknüpfen Sie eine OCR-Komponente mit dem Extraktor und wählen Sie die Engine, die zu Ihnen passt. TsgcAIOCRTesseract führt die auf der Maschine installierte Tesseract-OCR-Engine aus. TsgcAIOCRWindows nutzt die in Windows 10 und höher eingebaute Texterkennung, sodass nichts installiert werden muss. Mit OCRMode auf domAlways gesetzt, werden die Bilder nie an das Modell gesendet. Die OCR-Engine liest den Text lokal, und ein Textmodell wie Ollama übernimmt die Extraktion, sodass die gesamte Pipeline auf Ihrer eigenen Hardware läuft.
oOCR := TsgcAIOCRTesseract.Create(Self);
oOCR.Language := 'eng';
oChat.Provider := aicpOllama;
oChat.ChatOptions.Model := 'llama3.1';
oExtractor.OCR := oOCR;
oExtractor.OCRMode := domAlways;
oExtractor.Preset := dpReceipt;
Memo1.Lines.Text := oExtractor.ExtractFile('receipt.png');
Die Windows-Engine nimmt ein BCP-47-Sprach-Tag wie en-US entgegen, oder ein leeres Language, um die Sprachen des Benutzerprofils zu verwenden.
oWinOCR := TsgcAIOCRWindows.Create(Self);
oWinOCR.Language := 'en-US';
oExtractor.OCR := oWinOCR;
oExtractor.OCRMode := domFallback;
Memo1.Lines.Text := oExtractor.ExtractFile('invoice.png');
domFallback, verwendet in diesem zweiten Beispiel, ist die andere Option. Der Extraktor versucht zuerst die Vision-Anfrage und verwendet den erkannten Text erst, wenn diese Anfrage fehlschlägt, wobei OnOCRFallback feuert, damit Sie es mitbekommen. LastResult.UsedOCR und LastResult.OCRText verraten Ihnen im Nachhinein, welcher Pfad die Daten geliefert hat. Der OCR-Schritt liest Bilder, daher geht eine gescannte PDF als Seitenbilder ein.
C# für .NET
Die .NET-Edition von sgcWebSockets hat dieselben Komponenten mit denselben Namen im Namespace esegece.sgcWebSockets. Die Presets, die Konfidenzwerte und die Ereignisse funktionieren genauso, und beide OCR-Engines, TsgcAIOCRTesseract und TsgcAIOCRWindows, sind ebenfalls dabei.
using esegece.sgcWebSockets;
var chat = new TsgcAIChat();
chat.Provider = TsgcAIChatProvider.aicpAnthropic;
chat.ChatOptions.ApiKey = "your-api-key";
var extractor = new TsgcAIDocumentExtractor();
extractor.AIChat = chat;
extractor.Preset = TsgcAIDocumentPreset.dpInvoice;
extractor.MinConfidence = 0.8;
extractor.OnLowConfidence += (sender, field, confidence) =>
Console.WriteLine($"review {field}: {confidence:0.00}");
string json = extractor.ExtractFile("invoice.pdf");
Console.WriteLine(json);
Console.WriteLine($"valid: {extractor.LastResult.Valid}, confidence: {extractor.LastResult.Confidence:0.00}");
Verfügbarkeit
TsgcAIDocumentExtractor, TsgcAIOCRTesseract, TsgcAIOCRWindows und die neuen TsgcAIChat-Methoden kommen in sgcWebSockets 2026.10, für Delphi, C++Builder und .NET. Sie sind nicht in der Version enthalten, die Sie heute herunterladen können. Wenn 2026.10 erscheint, wird es auf der Download-Seite stehen.
Die vollständige Referenz, mit jeder Eigenschaft, jedem Ereignis und einer schrittweisen Anleitung für Rechnungen, steht in der TsgcAIDocumentExtractor-Hilfe. Für alles andere, was die KI-Komponenten können, siehe die sgcAI-Produktseite und die sgcWebSockets-KI-Seite.
Weiterlesen
- Ein Server-Sent-Events-Client für Delphi und .NET, ebenfalls neu in 2026.10
- Einen KI-Agenten in Delphi bauen: Function Calling und MCP-Tool-Nutzung
Fragen, Feedback oder Hilfe bei der Migration? Nehmen Sie Kontakt auf. Sie erhalten eine Antwort von den Leuten, die den Code geschrieben haben.
