Skip to content

Make AI useful with documents and data

Get the text out cleanly, say exactly what you want back, and check it with something better than another AI. Worked through on a real invoice extraction, with the real outputs.

Level
Intermediate
Reading time
14 minutes
Sources checked
11 Nov 2026
Status
Draft, awaiting editorial review

Who it’s forPeople who want answers, tables or summaries from PDFs, Word files and spreadsheets without retyping them.

Before you startComfortable with a chat tool. The optional conversion step uses Python; you can skip it and paste text instead.

By the end you'll be able to

  • Convert a document to clean text and check what the conversion lost
  • Write an extraction spec that says what to return, and what to do when something's missing
  • Check extracted data with arithmetic or a script, not another AI

Three steps that make document work reliable

  1. 11. Get the text outAI tools read text best. Convert the file, then look at what the conversion produced before you trust it.
  2. 22. Ask for a fixed shapeSay exactly which fields you want, in what format, and what to do when one is missing. Free-form summaries are hard to check.
  3. 33. Check with something better than AITotals should add up, dates should exist, every value should be in the original. Arithmetic and a short script check these perfectly.

Sort it

AI, or a formula?

Which tool should do each job?

  1. 1.Pull the supplier name and invoice number from 50 differently laid-out invoices
  2. 2.Add up the line totals
  3. 3.Check that a date is a real date
  4. 4.Sort customer comments into themes
Choose a category for every item to check.

Step 1: Get the text out

Many chat tools accept files directly, and for one-off questions that's fine. For repeatable work, converting first lets you see exactly what the AI will read. Microsoft's MarkItDown is one free option: "a lightweight Python utility for converting various files to Markdown for use with LLMs and related text analysis pipelines". It handles PDF, Word, PowerPoint, Excel, HTML, CSV and more.

For our worked example we made a short invoice in Word for a fictional print shop, then ran markitdown invoice.docx. Here's the real output:

MarkItDown 0.1.9 output for our fictional invoice
INVOICE

Hollow Lane Print Co.
14 Mill Street, Exampletown
VAT no. GB000 0000 00

Invoice number: HL-2291
Invoice date: 3 November 2026
Bill to: Riverside Community Café

Payment terms: 30 days from invoice date

|  |  |  |  |
| --- | --- | --- | --- |
| Item | Qty | Unit price | Line total |
| A5 menus, 350gsm | 200 | £0.45 | £90.00 |
| Table tent cards | 40 | £1.20 | £48.00 |
| Design time (hours) | 2 | £35.00 | £70.00 |

Subtotal: £208.00
VAT at 20%: £41.60
Total due: £249.60

Thank you for your business. Please quote the invoice number with your payment.

Step 2: Write an extraction spec

An extraction spec says what to return, in a fixed shape, and what to do when something isn't there. The shape is often described with JSON Schema, "a declarative format for describing the structure of other data". Some APIs can enforce it: Anthropic's structured outputs "constrain Claude's responses to follow a specific schema", and OpenAI's Structured Outputs "ensures the model will always generate responses that adhere to your supplied JSON Schema". A schema guarantees the shape, not that the values are right.

The spec we used (pasted above the converted invoice)
Extract these fields from the invoice below. Reply with JSON only, no other text.

Rules:
- Use only what the invoice says. If a field isn't stated, use null. Never calculate or guess a value.
- Copy amounts as numbers in pounds, without the £ sign.
- Dates as written in the invoice.

Fields:
{
  "supplier": string,
  "invoice_number": string,
  "invoice_date": string,
  "due_date": string or null,
  "lines": [{"item": string, "qty": number, "unit_price": number, "line_total": number}],
  "subtotal": number,
  "vat": number,
  "total": number
}
The real response (claude-sonnet-5-5, 12 Nov 2026), formatted for reading
{
  "supplier": "Hollow Lane Print Co.",
  "invoice_number": "HL-2291",
  "invoice_date": "3 November 2026",
  "due_date": null,
  "lines": [
    {"item": "A5 menus, 350gsm", "qty": 200, "unit_price": 0.45, "line_total": 90.0},
    {"item": "Table tent cards", "qty": 40, "unit_price": 1.2, "line_total": 48.0},
    {"item": "Design time (hours)", "qty": 2, "unit_price": 35.0, "line_total": 70.0}
  ],
  "subtotal": 208.0,
  "vat": 41.6,
  "total": 249.6
}

Knowledge check

Why null?

The invoice says "Payment terms: 30 days from invoice date". Why was due_date returned as null, and was that right?

Before and after

From "summarise" to a spec

Vague request

Summarise this invoice for me.

Extraction spec

Extract supplier, invoice number, invoice date, due date, each line (item, qty, unit price, line total), subtotal, VAT and total, as JSON. Use only what the invoice says; if a field isn't stated, use null. Never calculate or guess.

Step 3: Check with arithmetic, not another AI

An invoice checks itself: each line's quantity times price should equal its line total, the lines should add up to the subtotal, and subtotal plus VAT should equal the total. This short script tests all of that. You can ask an AI to write one for your own documents; then test the script, as the coding lesson shows.

check_invoice.py
import json, sys

inv = json.load(open(sys.argv[1]))
problems = []
for line in inv["lines"]:
    if round(line["qty"] * line["unit_price"], 2) != line["line_total"]:
        problems.append(f"{line['item']}: qty x price doesn't match line total")
if round(sum(l["line_total"] for l in inv["lines"]), 2) != inv["subtotal"]:
    problems.append("line totals don't add up to the subtotal")
if round(inv["subtotal"] + inv["vat"], 2) != inv["total"]:
    problems.append("subtotal + VAT doesn't equal the total")
for field in ["supplier", "invoice_number", "invoice_date"]:
    if not inv.get(field):
        problems.append(f"missing {field}")
print("\n".join(problems) if problems else "All checks passed.")

On the real extraction it printed "All checks passed." To be sure the check could fail, we changed the subtotal from 208 to 280, the kind of digit swap that happens in real data entry. It printed "line totals don't add up to the subtotal" and "subtotal + VAT doesn't equal the total". A check you've never seen fail isn't proven.

Before you upload anything

  • Check your organisation allows that tool for that kind of document. Invoices, contracts and HR files often contain personal or confidential data.
  • Free and paid plans can have different data terms. Read the current terms for the plan you're on.
  • Converting with a local tool such as MarkItDown keeps the conversion on your computer. Sending the text to an AI service still sends it.

Try it

Guided practice

Extract and check one real document type

About 40 minutes0 of 5 steps ticked

You’re done when

  • Your spec lists every field, its format and a rule for missing values
  • All three results have been checked against the originals
  • You've written down at least one thing the check caught or one thing it can't catch

What you’ll get from it: A tested extraction spec for a document you really handle, and a clear view of where it needs a human check.

Free worksheet

The extraction spec

Define exactly what to pull from a document, what to do when something's missing, and how you'll check the result.

The online version saves your answers only in this browser. The PDF is A4 and prints on US Letter too.

What to remember

  • Look at the converted text before you trust it. Conversions can quietly rearrange tables.
  • A fixed shape and a rule for missing values make AI output checkable.
  • Check numbers with arithmetic and text against the original. Don't ask another AI to check the first.
  • Our example is one simple document and one run. Scanned, handwritten or complex documents fail more often.

Tools for this guide

  • MarkItDown: A Python tool from Microsoft that converts PDF, Word, PowerPoint, Excel and other files into Markdown text for AI tools. (We tested)
  • Gemini Notebook (NotebookLM): A research notebook that answers questions using the documents you add, with citations back to the passages it used. (Researched from docs)

Your progress

You’ve finished 0 of 4 activities in this lesson.

When you've tried the practice task on your own work, mark the lesson complete. It's your call: finishing the activities shows you've practised, not that you've mastered the skill.

Progress is saved only in this browser, on this device. There’s no account, and nothing is sent to us or anyone else. Clearing your browser data, or using another browser or device, starts you afresh. We save which activities you finished, never what you type.

Suggested next lesson

AI-assisted coding without losing the plotA ten-line checking script did the most reliable work here. Next, write small scripts like it with AI help, safely.Beginner, 15 minutes

Next steps

Sources and evidence

The method is our editorial advice. The worked example is real: on 12 November 2026 we made a fictional invoice, converted it with MarkItDown 0.1.9, asked Claude (claude-sonnet-5-5, through the Claude Code command line) to extract it, and checked the result with a short script. The files are kept with our research notes. One document, one run, one model.

  1. Microsoft MarkItDown (GitHub README) (opens in a new tab)Checked 11 Nov 2026
  2. JSON Schema: What is JSON Schema? (opens in a new tab)Checked 11 Nov 2026
  3. OpenAI: Structured Outputs (opens in a new tab)Checked 11 Nov 2026
  4. Anthropic: Structured outputs (opens in a new tab)Checked 11 Nov 2026

This guide is a draft and hasn’t been through editorial review yet. How we review guides

One useful email a week.

Important model releases, a tool worth trying, one practical workflow and a few useful links, each with its source. Free, and easy to leave.

Signups aren’t open yet.

We won’t collect any email addresses until the newsletter launches, and there’s no form here to fill in. Until then, new guides and videos go out on our channels:

Questions in the meantime? understandingaihq@gmail.com