Estrazione dati da documenti: chi lavora in contabilità, segreteria, sanità, logistica conosce bene la fatica. Foto di scontrini, scansioni di contratti, PDF di fatture, moduli di richiesta da archiviare. Fino a un paio d'anni fa l'unica strada era un software OCR rigido e poi un'ora di pulizia manuale. Oggi i modelli di intelligenza artificiale con visione fanno meglio in pochi secondi, se gli si chiede nel modo giusto. Questa guida spiega come, scegliendo tra i tre migliori modelli del mercato a maggio 2026.
A chi serve, cosa otterrai
Il tutorial è scritto per chiunque debba processare regolarmente documenti scritti o stampati: piccoli studi commercialisti, segreterie aziendali, professionisti che gestiscono nota spese, sviluppatori che costruiscono un'app per i clienti. Al termine saprai: distinguere quando conviene un modello e quando un altro; preparare i file (formato, qualità, multipagina); scrivere un prompt che restituisce JSON pulito; costruire un piccolo script Python da 30 righe che processa un'intera cartella di PDF; gestire i casi limite (timbri, sigle, dialetto).
Quale modello scegliere
Le tre alternative principali a maggio 2026 sono Gemini 2.5 Pro di Google, Claude Opus 4.7 di Anthropic e GPT-5 di OpenAI. Ognuna ha pro e contro su questo specifico compito.
Gemini 2.5 Pro (Google)
Pro: il migliore rapporto qualità/prezzo per documenti lunghi. Accetta PDF nativi fino a 1.000 pagine e 50 MB direttamente via API, senza dover spezzare il file. Ottimo riconoscimento dei numeri e delle tabelle. Costo: 1,25 dollari per milione di token di input, 5 dollari per milione di token di output.
Contro: a volte "riempie" campi mancanti inventando valori plausibili (allucinazione). Meno robusto sulla calligrafia.
Quando sceglierlo: fatture, contratti, bilanci, moduli stampati. Prima scelta per la maggior parte dei casi italiani.
Claude Opus 4.7 (Anthropic)
Pro: dopo l'aggiornamento del 16 aprile 2026 supporta immagini fino a 2.576 pixel sul lato lungo (~3,75 megapixel), il triplo di prima. Eccellente nel restituire "non lo so" invece di inventare. Migliore di tutti sulla calligrafia. Costo: 5 dollari/milione input, 25 dollari/milione output.
Contro: il PDF deve essere convertito prima in immagini (una per pagina). Limite di 100 immagini per richiesta.
Quando sceglierlo: ricevute scritte a mano, certificati medici, documenti dove la precisione conta più del prezzo.
GPT-5 (OpenAI)
Pro: ottima vision e integrazione con le "Structured Outputs" che garantiscono che il JSON di output rispetti uno schema dato. Eccellente con loghi, marchi, layout complessi.
Contro: prezzo più alto sui task lunghi (10 dollari/milione input, 30 dollari/milione output). PDF da convertire come Claude.
Quando sceglierlo: quando hai bisogno di garanzie strutturali sul formato di uscita (per esempio per integrare il risultato in un gestionale che ha schema rigido).
Prerequisiti
Servono: Python 3.10 o superiore; un account su almeno uno dei tre fornitori (Google AI Studio è il più rapido da attivare e ha un buon piano gratuito); le librerie pdfplumber e Pillow per la conversione dei PDF; circa 10 minuti di tempo. Per la demo qui sotto useremo Gemini 2.5 Pro perché è la scelta che bilancia meglio costo e capacità per documenti italiani.
1) Setup ambiente
pip install -U google-generativeai pillow pdf2image# Su Linux servono anche poppler-utilssudo apt install poppler-utils# macOSbrew install poppler# Imposta la chiave APIexport GOOGLE_API_KEY="la_tua_chiave_qui"Per ottenere la chiave: vai su Google AI Studio (ai.google.dev), accedi con un account Google, clicca su "Get API key" e crea una nuova chiave. Il piano gratuito di Gemini 2.5 Pro consente fino a 5 richieste al minuto e 25 al giorno: sufficiente per il tutorial.
2) Preparare il documento
Tre cose contano: risoluzione, qualità della scansione, orientamento. Per fatture o ricevute, una scansione a 300 DPI in scala di grigi è sufficiente. Se hai foto fatte col telefono in condizioni di luce scarsa, ritagliale e raddrizzale con un'app prima di mandarle al modello: l'accuratezza migliora del 15-20%.
3) Il prompt che funziona
Il punto cruciale è scrivere un prompt che imponga un formato strutturato e dia al modello la possibilità di rispondere "non lo so". Esempio per una fattura italiana:
Sei un assistente di contabilità italiano. Analizza l'immagine della fattura e restituisci un JSON con questa struttura esatta:
{
"numero_fattura": stringa,
"data_emissione": "AAAA-MM-GG",
"fornitore_ragione_sociale": stringa,
"fornitore_piva": stringa di 11 cifre,
"cliente_ragione_sociale": stringa,
"cliente_piva_o_cf": stringa,
"voci": [{"descrizione": stringa, "quantita": numero, "prezzo_unitario": numero, "iva": numero}],
"imponibile": numero,
"iva_totale": numero,
"totale": numero,
"note": stringa
}
Se un campo non è leggibile o non è presente, scrivi null. Non inventare valori. Restituisci solo il JSON, senza markdown.
4) Lo script Python passo passo
import os, json, base64from pathlib import Pathimport google.generativeai as genaifrom pdf2image import convert_from_pathgenai.configure(api_key=os.environ["GOOGLE_API_KEY"])model = genai.GenerativeModel("gemini-2.5-pro")PROMPT = open("prompt_fattura.txt").read() # il prompt sopra, salvato su filedef analizza_pdf(path_pdf: str) -> dict: pagine = convert_from_path(path_pdf, dpi=200) contenuti = [PROMPT] + pagine # multi-immagine risposta = model.generate_content(contenuti, generation_config={ "response_mime_type": "application/json", "temperature": 0 }) return json.loads(risposta.text)# Loop su una cartellaout = []for f in Path("fatture/").glob("*.pdf"): try: dati = analizza_pdf(str(f)) dati["_file"] = f.name out.append(dati) print(f"OK: {f.name}") except Exception as e: print(f"KO {f.name}: {e}")with open("risultati.json", "w") as fp: json.dump(out, fp, indent=2, ensure_ascii=False)Lo script: converte ogni PDF in immagini (200 DPI è un buon compromesso); manda prompt e immagini al modello; salva il JSON di output; raccoglie tutto in un file finale. Su 100 fatture italiane standard, su un MacBook Air M2, gira in circa 6 minuti e costa meno di 0,40 dollari con Gemini 2.5 Pro.
5) Lo stesso processo con Claude Opus 4.7
Per chi preferisce Claude la struttura è identica, cambia solo la libreria. Bisogna installare anthropic con pip install anthropic e impostare ANTHROPIC_API_KEY:
import anthropic, base64from pathlib import Pathclient = anthropic.Anthropic()def img_to_b64(img): from io import BytesIO buf = BytesIO() img.save(buf, format="PNG") return base64.b64encode(buf.getvalue()).decode()def analizza_pdf_claude(path_pdf): pagine = convert_from_path(path_pdf, dpi=200) blocchi = [{"type":"image", "source":{"type":"base64", "media_type":"image/png", "data":img_to_b64(p)}} for p in pagine] blocchi.append({"type":"text", "text": PROMPT}) r = client.messages.create( model="claude-opus-4-7", max_tokens=2000, messages=[{"role":"user", "content": blocchi}] ) import json return json.loads(r.content[0].text)6) Stesso processo con GPT-5 e Structured Outputs
Con OpenAI la differenza è che si può forzare uno schema JSON pydantic come output. Il vantaggio: nessuna riga di codice per validare la risposta.
from openai import OpenAIfrom pydantic import BaseModelfrom typing import List, Optionalclass Voce(BaseModel): descrizione: str quantita: float prezzo_unitario: float iva: floatclass Fattura(BaseModel): numero_fattura: Optional[str] data_emissione: Optional[str] fornitore_ragione_sociale: Optional[str] fornitore_piva: Optional[str] voci: List[Voce] totale: floatclient = OpenAI()def analizza_pdf_gpt5(path_pdf): pagine = convert_from_path(path_pdf, dpi=200) content = [{"type": "input_text", "text": PROMPT}] for p in pagine: content.append({"type": "input_image", "image_url": f"data:image/png;base64,{img_to_b64(p)}"}) r = client.responses.parse( model="gpt-5", input=[{"role":"user", "content": content}], text_format=Fattura ) return r.output_parsed.model_dump()7) Errori comuni e come risolverli
- "JSON malformed": aggiungi al prompt "Restituisci solo JSON valido, senza testo introduttivo". Per Gemini imposta
response_mime_type: application/json. Per OpenAI usa Structured Outputs. - P.IVA inventate: aggiungi al prompt "La P.IVA è di 11 cifre italiane. Se non vedi 11 cifre consecutive nel documento, scrivi null". Aggiungi una validazione di lunghezza nel codice.
- Date in formato sbagliato: nel prompt imponi "AAAA-MM-GG" e fai notare gli esempi italiani comuni: "15 maggio 2026 → 2026-05-15; 15/05/26 → 2026-05-15".
- Documenti multipagina molto lunghi: spezza il PDF in chunk di max 20 pagine, processa separatamente, poi unisci i risultati con un piccolo merger Python.
- Documenti con calligrafia: usa Claude Opus 4.7 invece di Gemini. La differenza si vede a occhio sulle ricevute scritte a mano.
8) Varianti e casi avanzati
Quattro casi tipici per cui ho ricevuto domande nei mesi scorsi:
- Scontrini termici sbiaditi: applica prima un filtro di contrasto con Pillow (
ImageEnhance.Contrast(img).enhance(1.4)) prima di mandare l'immagine al modello. - Fatture in inglese e tedesco: aggiungi al prompt "Il documento può essere in italiano, inglese o tedesco. Riconoscilo automaticamente e standardizza i nomi dei campi nel JSON".
- Tabelle con righe ripetute: chiedi al modello di restituire un array
vocicon un elemento per riga, anche se la descrizione si ripete. - Estrazione di firme: la presenza di una firma può essere rilevata, ma non considerare il modello uno strumento legale. Per validità giuridica usa una firma digitale certificata.
9) Quando non usare un LLM
Per casi con altissimo volume (oltre 10.000 documenti al giorno) e schema fisso, un OCR tradizionale di buon livello (Google Document AI, AWS Textract, Azure Form Recognizer) può costare meno e essere più prevedibile. Per documenti molto particolari (etichette industriali, codici a barre, prescrizioni mediche) un modello dedicato addestrato col tuo dataset spesso vince. Per documenti normali, però, i tre modelli di questa guida coprono il 95% dei casi reali.
10) Prossimi passi
Per produzione vera tre raccomandazioni: log strutturato dei risultati (timestamp, file, modello, costo) per misurare ROI; double-check umano sui campi critici (importi, P.IVA) almeno per i primi cento documenti; archiviazione del prompt esatto usato accanto al risultato. La precisione di un sistema basato su LLM non è mai uguale per sempre: ogni modificato modello o prompt va misurato.
La documentazione di riferimento per i tre modelli è in costante aggiornamento: la pagina vision di Anthropic, la guida Gemini API di Google AI for Developers, e l'OpenAI Cookbook. Per chi vuole evitare di scrivere il proprio codice, esistono già wrapper SaaS come Reducto, Unstructured e Mathpix che fanno questa stessa cosa con un'interfaccia. Ma capire i mattoni resta indispensabile: ti permette di scegliere e di correggere ciò che la SaaS non sa fare.




