La mayoría del software empresarial todavía tiene a alguien que lee un PDF y escribe sus cifras a mano en un formulario. Facturas de proveedores, tickets de caja, el escaneo de un carné de identidad en la recepción. Hoy los grandes modelos de lenguaje leen bien esos documentos, pero pedirle a un modelo "los datos de la factura" te da un texto en prosa, o un JSON con la forma que le apeteciera escribir, sin ninguna manera de saber de qué valores no estaba seguro.
sgcWebSockets 2026.10 añade TsgcAIDocumentExtractor para Delphi, C++Builder y .NET. Le das un PDF o una imagen, él pregunta al modelo que ya usas a través de TsgcAIChat, y te devuelve JSON validado contra un esquema, con una confianza para cada campo. El componente no forma parte de la descarga actual. Llega con la versión 2026.10.
TsgcAIDocumentExtractor leyendo una factura PDF real con Anthropic Claude y devolviendo JSON validado con una confianza por campo. También en YouTube.
Entra un PDF, sale JSON
Coloca un TsgcAIChat y un TsgcAIDocumentExtractor en un formulario, apunta el extractor al chat, elige un preset y llama a ExtractFile. OpenAI, Anthropic y Gemini leen archivos PDF tal cual. DeepSeek, Grok, Mistral y Ollama solo aceptan imágenes, así que para esos proveedores envías las páginas como PNG o 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;
Este es el flujo que se muestra en el vídeo, y se verificó en vivo contra Anthropic Claude con una factura PDF real. ExtractFiles envía varias páginas de un mismo documento en una sola petición, y ExtractAttachments toma documentos que ya tienes en memoria como base64.
El extractor hace su trabajo a través de TsgcAIChat, que gana las mismas capacidades para tus propios prompts. ChatWithDocument envía un PDF o una imagen con un mensaje, ChatWithAttachments envía varios a la vez, y ChatJSONWithAttachments pide una respuesta en JSON sobre ellos. Una nueva propiedad TLSOptions establece la versión de OpenSSL, el IOHandler y los certificados usados por cada proveedor.
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 y tu propio esquema
Tres presets cubren los documentos habituales: dpInvoice, dpReceipt y dpIDCard. Cada uno trae su esquema JSON y sus instrucciones de extracción, así que no hay nada más que configurar. Para cualquier otro documento, pon Preset en dpCustom y escribe tú mismo el esquema.
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.';
Con OpenAI el esquema se envía en modo estricto, así que tiene que seguir las reglas estrictas: todo objeto declara "additionalProperties": false, toda propiedad aparece en required, y un valor opcional usa un tipo anulable como ["string", "null"]. Los presets incorporados ya siguen esas reglas. Para partir de uno de ellos y añadir un campo, cópialo con TsgcAIDocumentExtractor.GetPresetSchema(dpInvoice).
Validación y reintento
La respuesta nunca llega a tu código sin comprobar. El extractor la valida localmente contra el esquema: tipos, propiedades obligatorias, objetos y arrays anidados, y enums. Cuando no coincide, el componente le dice al modelo qué falló y se lo pide una vez más. ValidationRetries establece cuántas veces, y su valor por defecto es 1.
Si los datos siguen siendo inválidos después de los reintentos, el extractor lanza una excepción. Pon RaiseOnInvalid en False para obtener los datos de todos modos y leer los problemas en LastResult.ValidationErrors, una línea path: message por cada uno.
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);
Confianza y revisión humana
JSON válido no es lo mismo que JSON correcto. Un total borroso o una fecha manchada pueden seguir produciendo un número bien formado. Por eso el modelo también informa de lo seguro que está de cada campo que extrajo, y el extractor te da esos valores. LastResult.Confidence es el más bajo de todos ellos, LastResult.FieldConfidence('total') devuelve el valor de una ruta concreta, y OnLowConfidence se dispara una vez por cada campo por debajo 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;
Eso convierte una cola de revisión en algo que una persona puede terminar: revisa los dos campos de los que el modelo dudaba, no la factura entera.
OCR local, nada sale de la máquina
Algunos documentos no deben ir a ningún servicio en la nube. Enlaza un componente OCR al extractor y elige el motor que prefieras. TsgcAIOCRTesseract ejecuta el motor OCR Tesseract instalado en la máquina. TsgcAIOCRWindows usa el reconocimiento de texto integrado en Windows 10 y versiones posteriores, así que no hay nada que instalar. Con OCRMode en domAlways, las imágenes nunca se envían al modelo. El motor OCR lee el texto localmente, y un modelo de texto como Ollama hace la extracción, así que todo el proceso corre en tu propio hardware.
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');
El motor de Windows admite una etiqueta de idioma BCP-47 como en-US, o un Language vacío para usar los idiomas del perfil de usuario.
oWinOCR := TsgcAIOCRWindows.Create(Self);
oWinOCR.Language := 'en-US';
oExtractor.OCR := oWinOCR;
oExtractor.OCRMode := domFallback;
Memo1.Lines.Text := oExtractor.ExtractFile('invoice.png');
domFallback, usado en este segundo ejemplo, es la otra opción. El extractor prueba primero la petición de visión y solo usa el texto reconocido cuando esa petición falla, disparando OnOCRFallback para que lo sepas. LastResult.UsedOCR y LastResult.OCRText te dicen después qué camino produjo los datos. El paso de OCR lee imágenes, así que un PDF escaneado entra como imágenes de página.
C# para .NET
La edición .NET de sgcWebSockets tiene los mismos componentes con los mismos nombres en el espacio de nombres esegece.sgcWebSockets. Los presets, los valores de confianza y los eventos funcionan de la misma manera, y los dos motores OCR, TsgcAIOCRTesseract y TsgcAIOCRWindows, también están ahí.
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}");
Disponibilidad
TsgcAIDocumentExtractor, TsgcAIOCRTesseract, TsgcAIOCRWindows y los nuevos métodos de TsgcAIChat llegan en sgcWebSockets 2026.10, para Delphi, C++Builder y .NET. No están en la versión que puedes descargar hoy. Cuando salga la 2026.10, estará en la página de descargas.
La referencia completa, con cada propiedad y evento y una guía paso a paso para facturas, está en la ayuda de TsgcAIDocumentExtractor. Para todo lo demás que hacen los componentes de IA, consulta la página de producto sgcAI y la página de IA de sgcWebSockets.
Sigue leyendo
- Un cliente Server-Sent Events para Delphi y .NET, también nuevo en 2026.10
- Crea un agente de IA en Delphi: function calling y uso de herramientas con MCP
¿Preguntas, comentarios o ayuda con la migración? Ponte en contacto. Recibirás respuesta de las mismas personas que escribieron el código.
