Try a sample:
Fields
| Field | Value | Confidence | Why flagged |
|---|
Checks
Attempts
Raw JSON
Fields below 0.75 confidence land here, with the reason. In a real deployment these would block the write to your accounting system or CRM until someone approves or corrects them. The queue is stored in this browser.
| Time | Type | Model | Attempts | Valid | Latency | Tokens in / out | Cost | Flagged |
|---|
- Schema first. Each document type has a Zod schema: required fields, ISO dates, 3-letter currency codes, numbers without separators, at least one line item.
- Extract. A free LLM (via OpenRouter, rotating models if one is busy) returns
{"data": …, "confidence": {field: 0–1}}in JSON mode. - Validate and retry. If the JSON doesn't parse or fails the schema, the exact errors go back to the model ("invoice_date: must be YYYY-MM-DD") and it tries again, up to 3 attempts. Every attempt is shown.
- Check. The model's confidence is only a starting point. Code checks the arithmetic (quantity × price, subtotal, total), that invoice numbers, emails and amounts actually appear in the text, and that dates make sense. A failed check caps that field's confidence.
- Review. Fields under 0.75 go to the review queue with the reason. Latency, tokens and cost for every run are in the log (the models are free, so cost is $0).
Source code and write-up: github.com/yashharkawat/llm-extract. Sample documents are made up.