simodocs

Examples

Invoice extraction

Pull the fields you need out of an invoice (text or a scanned image), typed and validated, with a calibrated check on each value. Only the uncertain fields go to a person.

from simoai import Client, Extract, Fill, Noul, image

c = Client()

FIELDS = {
    "invoice_no": Extract("the invoice number, exactly as written", max_tokens=16),
    "date":       Extract("the invoice date, exactly as written", max_tokens=16),
    "vendor":     Extract("the name of the company that issued the invoice", max_tokens=24),
    "total":      Fill("the total amount due, in the invoice's currency", kind="number"),
    "currency":   Fill("the currency code, e.g. USD or EUR", pattern=r"[A-Z]{3}", max_tokens=4),
    "items":      Extract("every line item description", many=True, max_tokens=256),
    "paid":       Noul("The invoice is marked as paid"),
}

def read_invoice(path: str) -> dict:
    r = c.ask({"invoice": "<image:1>"}, FIELDS, media=[image(path)], self_check=True)
    out, review = {}, []
    for name, a in r.answers.items():
        out[name] = a.result
        check = a.raw.get("check")                       # set on Fill / Extract with self_check
        if (check is not None and check < 0.9) or a.raw.get("valid") is False:
            review.append(name)
    return {"fields": out, "review": review, "cost": r.cost_usd}

print(read_invoice("invoice-0193.png"))
# {'fields': {'invoice_no': 'INV-0193', 'date': '3 Oct 2026', 'total': 1240.5, 'currency': 'EUR',
#             'items': ['Design review (8h)', 'Hosting, October'], 'paid': False, ...},
#  'review': [], 'cost': 4.1e-05}

Why it works

  • Typed output. kind="number" always parses to a number and pattern forces a three-letter code, so there is no cleanup step.
  • A calibrated check per field. self_check adds check, the probability the value is right. Unlike confidence, you can threshold it.
  • Text works too. For a text invoice, put the text in the state instead of <image:1> and drop media.