All insights
Automation

4 min read

Document parsing with LLMs: extracting data from invoices and forms

How to turn invoices and forms into reliable structured data with LLMs, schemas, validation and a review queue for the cases that need a person.

Structured extraction with LLMs: what it solves

Many operations teams still type data from documents into systems: supplier invoices into the ERP, application forms into the CRM, delivery notes into the warehouse system. Template-based extraction tools work until a supplier changes their layout. Language models, especially those that can read page images, can extract fields from layouts they have never seen.

This guide is for operations and finance leaders automating document intake, and for the engineers building it. Getting a model to return JSON is easy. Getting data you can post to a ledger without checking every document takes a strict schema, validation, confidence signals and a human review queue for everything else.

OCR or vision models

The first design choice is how the model sees the document.

ApproachHow it worksStrengthsWeaknesses
Text layerRead the embedded text of a digital PDFFast, cheap, exact charactersScans have no text layer; tables and columns can scramble
OCR, then LLMOCR produces text, often with positions, and the LLM extracts fieldsWorks on scans; positions help with highlighting and auditOCR errors pass downstream; complex layouts lose structure
Vision modelThe model reads the page images directlyUnderstands layout, tables, stamps and handwriting in contextHigher cost per page; long numbers need verifying
CombinedA vision model extracts, and the text layer or OCR confirms valuesLayout understanding with character-level checksMore moving parts

For invoices and forms we usually combine them. A vision-capable model extracts the fields, and where a text layer or OCR output exists, we check that key values such as IBANs, invoice numbers and totals appear in it. A mismatch is a signal to route the document for review.

Define the output with a schema

Describe exactly what you want as a typed schema. With pydantic, the same class generates the JSON schema you send to the model and validates what comes back. Defining a tool and forcing the model to call it makes the output follow that schema:

Python
from datetime import date
from decimal import Decimal
from anthropic import Anthropic
from pydantic import BaseModel, Field, model_validator

class Invoice(BaseModel):
    supplier_name: str
    invoice_number: str
    invoice_date: date
    currency: str = Field(pattern=r"^[A-Z]{3}$")
    net_total: Decimal
    vat_total: Decimal
    gross_total: Decimal

    @model_validator(mode="after")
    def totals_add_up(self):
        if abs(self.net_total + self.vat_total - self.gross_total) > Decimal("0.01"):
            raise ValueError("net + VAT does not equal gross")
        return self

client = Anthropic()

def extract(pdf_b64: str) -> Invoice:
    tool = {"name": "record_invoice", "description": "Record the invoice fields.",
            "input_schema": Invoice.model_json_schema()}
    response = client.messages.create(
        model="claude-sonnet-5", max_tokens=2048, tools=[tool],
        tool_choice={"type": "tool", "name": "record_invoice"},
        messages=[{"role": "user", "content": [
            {"type": "document", "source": {"type": "base64", "media_type": "application/pdf", "data": pdf_b64}},
            {"type": "text", "text": "Extract the fields from this invoice."},
        ]}],
    )
    block = next(b for b in response.content if b.type == "tool_use")
    return Invoice.model_validate(block.input)

A few schema habits improve accuracy:

  • Use precise types: date, Decimal for money, and enums for known values such as currency or document type.
  • Make fields optional only when documents genuinely omit them, and tell the model to leave them empty in that case.
  • Add short field descriptions for anything ambiguous, such as whether a total includes VAT.
  • Ask for the source text or page number of key fields, which makes review and audit much faster.

Validation beyond the schema

A schema checks shape. Business rules check sense. Run both on every extraction:

  1. 01Arithmetic: line items sum to the net total, net plus VAT equals gross, and VAT rates are ones you accept.
  2. 02Format: IBAN checksums, VAT number formats and dates within a plausible range.
  3. 03Reference data: the supplier exists in your vendor master, the bank details match those on file and the purchase order is open.
  4. 04Duplicates: the same supplier and invoice number have not been processed before.

Validation failures should never silently correct data. They route the document to review with the failed rule attached, which tells the reviewer where to look. A changed bank account on a known supplier deserves particular care, since it is a well-known fraud pattern.

Confidence without guesswork

Asking the model how confident it is produces numbers that look precise and are poorly calibrated. Build confidence from signals you can verify:

  • All schema and business validations pass.
  • Key values appear verbatim in the OCR output or text layer.
  • Two extraction passes, for example with different prompts or models, agree on the critical fields.
  • The supplier and layout have a history of clean extractions.

Combine these into a routing decision per document: straight through, review specific fields, or review the whole document. Measure the error rate of straight-through documents on a regular sample, and widen straight-through processing only as that rate supports it.

Design the human review queue

The review queue is where accuracy is protected, so design it as a product in its own right:

  • Show the document next to the extracted fields, with each field's source highlighted on the page.
  • Put flagged fields first, with the failed rule or disagreement described in plain language.
  • Let reviewers correct a field in one action and approve the rest together.
  • Record every correction. Corrections are labelled data for your eval set and show which suppliers or fields need attention.

A good queue turns review into a quick check of a few highlighted fields. Track time per review and corrections per field to see where to improve extraction next. For the wider pattern of routing automated decisions to people, see human-in-the-loop design for AI agents.

Where to start

  1. 01Collect a few hundred real documents across your suppliers or form types, including poor scans.
  2. 02Label the correct values for a sample of them. This is your eval set.
  3. 03Define the schema and business rules with the team that does the work today.
  4. 04Build extraction with validation, and measure accuracy per field.
  5. 05Launch with every document reviewed, then move segments to straight-through processing as your measurements support it.

We have built this pattern for financial document parsing and for invoice approval with policy checks. Read how we work to see how we take projects like these from the first documents to production.

All insights

Start working with Vantion.