La plupart des logiciels d'entreprise ont encore quelqu'un quelque part qui lit un PDF et saisit ses chiffres dans un formulaire. Factures fournisseurs, tickets de caisse, le scan d'une carte d'identité à l'accueil. Les grands modèles de langage lisent bien ces documents aujourd'hui, mais demander à un modèle « les données de la facture » vous donne un texte en prose, ou du JSON dans la forme qui lui est venue à l'esprit, sans aucun moyen de savoir de quelles valeurs il n'était pas sûr.
sgcWebSockets 2026.10 ajoute TsgcAIDocumentExtractor pour Delphi, C++Builder et .NET. Vous lui donnez un PDF ou une image, il interroge le modèle que vous utilisez déjà via TsgcAIChat, et il vous rend un JSON validé contre un schéma, avec une confiance pour chaque champ. Le composant ne fait pas partie du téléchargement actuel. Il arrive avec la version 2026.10.
TsgcAIDocumentExtractor lisant une facture PDF réelle avec Anthropic Claude et renvoyant du JSON validé avec une confiance par champ. Également sur YouTube.
Un PDF en entrée, du JSON en sortie
Déposez un TsgcAIChat et un TsgcAIDocumentExtractor sur un formulaire, faites pointer l'extracteur vers le chat, choisissez un preset et appelez ExtractFile. OpenAI, Anthropic et Gemini lisent les fichiers PDF tels quels. DeepSeek, Grok, Mistral et Ollama n'acceptent que des images, donc pour ces fournisseurs vous envoyez les pages en PNG ou en 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;
C'est le flux montré dans la vidéo, et il a été vérifié en direct avec Anthropic Claude sur une véritable facture PDF. ExtractFiles envoie plusieurs pages d'un même document en une seule requête, et ExtractAttachments prend des documents que vous détenez déjà en mémoire sous forme de base64.
L'extracteur fait son travail via TsgcAIChat, qui gagne les mêmes capacités pour vos propres prompts. ChatWithDocument envoie un PDF ou une image avec un message, ChatWithAttachments en envoie plusieurs à la fois, et ChatJSONWithAttachments demande une réponse en JSON à leur sujet. Une nouvelle propriété TLSOptions définit la version d'OpenSSL, l'IOHandler et les certificats utilisés pour chaque fournisseur.
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;
Les presets et votre propre schéma
Trois presets couvrent les documents courants : dpInvoice, dpReceipt et dpIDCard. Chacun apporte son schéma JSON et ses instructions d'extraction, il n'y a donc rien d'autre à configurer. Pour tout autre document, définissez Preset sur dpCustom et écrivez vous-même le schéma.
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.';
Avec OpenAI, le schéma est envoyé en mode strict, il doit donc suivre les règles strictes : chaque objet déclare "additionalProperties": false, chaque propriété est listée dans required, et une valeur optionnelle utilise un type nullable tel que ["string", "null"]. Les presets intégrés suivent déjà ces règles. Pour partir de l'un d'eux et ajouter un champ, copiez-le avec TsgcAIDocumentExtractor.GetPresetSchema(dpInvoice).
Validation et nouvelle tentative
La réponse n'atteint jamais votre code sans vérification. L'extracteur la valide localement par rapport au schéma : types, propriétés obligatoires, objets et tableaux imbriqués, et énumérations. Quand elle ne correspond pas, le composant indique au modèle ce qui n'allait pas et le lui redemande une fois. ValidationRetries définit combien de fois, et sa valeur par défaut est 1.
Si les données restent invalides après les tentatives, l'extracteur lève une exception. Mettez RaiseOnInvalid à False pour obtenir les données quand même et lire les problèmes dans LastResult.ValidationErrors, une ligne path: message pour chacun.
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);
Confiance et révision humaine
Un JSON valide n'est pas la même chose qu'un JSON correct. Un total flou ou une date tachée peuvent quand même produire un nombre bien formé. Le modèle indique donc aussi à quel point il est sûr de chaque champ qu'il a extrait, et l'extracteur vous donne ces valeurs. LastResult.Confidence est la plus basse d'entre elles, LastResult.FieldConfidence('total') renvoie la valeur d'un chemin donné, et OnLowConfidence se déclenche une fois pour chaque champ en dessous de 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;
Cela transforme une file de révision en quelque chose qu'une personne peut traiter : elle vérifie les deux champs dont le modèle doutait, pas la facture entière.
OCR local, rien ne quitte la machine
Certains documents ne doivent aller vers aucun service cloud. Liez un composant OCR à l'extracteur et choisissez le moteur qui vous convient. TsgcAIOCRTesseract exécute le moteur OCR Tesseract installé sur la machine. TsgcAIOCRWindows utilise la reconnaissance de texte intégrée à Windows 10 et versions ultérieures, donc rien à installer. Avec OCRMode réglé sur domAlways, les images ne sont jamais envoyées au modèle. Le moteur OCR lit le texte localement, et un modèle de texte comme Ollama fait l'extraction, si bien que tout le pipeline s'exécute sur votre propre matériel.
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');
Le moteur Windows accepte une étiquette de langue BCP-47 telle que en-US, ou un Language vide pour utiliser les langues du profil utilisateur.
oWinOCR := TsgcAIOCRWindows.Create(Self);
oWinOCR.Language := 'en-US';
oExtractor.OCR := oWinOCR;
oExtractor.OCRMode := domFallback;
Memo1.Lines.Text := oExtractor.ExtractFile('invoice.png');
domFallback, utilisé dans ce second exemple, est l'autre option. L'extracteur essaie d'abord la requête de vision et n'utilise le texte reconnu que si cette requête échoue, en déclenchant OnOCRFallback pour que vous le sachiez. LastResult.UsedOCR et LastResult.OCRText vous indiquent ensuite quel chemin a produit les données. L'étape OCR lit des images, donc un PDF scanné est fourni sous forme d'images de page.
C# pour .NET
L'édition .NET de sgcWebSockets a les mêmes composants avec les mêmes noms dans l'espace de noms esegece.sgcWebSockets. Les presets, les valeurs de confiance et les événements fonctionnent de la même manière, et les deux moteurs OCR, TsgcAIOCRTesseract et TsgcAIOCRWindows, sont là aussi.
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}");
Disponibilité
TsgcAIDocumentExtractor, TsgcAIOCRTesseract, TsgcAIOCRWindows et les nouvelles méthodes de TsgcAIChat arrivent dans sgcWebSockets 2026.10, pour Delphi, C++Builder et .NET. Ils ne sont pas dans la version que vous pouvez télécharger aujourd'hui. Quand la 2026.10 sortira, elle sera sur la page de téléchargement.
La référence complète, avec chaque propriété et événement et un guide pas à pas pour une facture, se trouve dans l'aide de TsgcAIDocumentExtractor. Pour tout le reste de ce que font les composants d'IA, consultez la page produit sgcAI et la page IA de sgcWebSockets.
À lire aussi
- Un client Server-Sent Events pour Delphi et .NET, également nouveau dans la 2026.10
- Créer un agent IA en Delphi : appel de fonctions et utilisation d'outils MCP
Des questions, des retours ou besoin d'aide pour la migration ? Contactez-nous. Vous recevrez une réponse des personnes qui ont écrit le code.
