Cookbook Blueprint

Structured JSON Extractor

Train a compact local model to parse invoices, receipts, and contract text into strict, deterministic JSON payloads.

The Objective

Extract structured entity fields from arbitrary unstructured enterprise strings:

Unstructured Input

"Invoice #INV-9821 from Apex Logistics Corp for $1,450.00 due on 2026-10-15. Terms net-30."

Extracted JSON Payload
{
  "invoice_number": "INV-9821",
  "vendor": "Apex Logistics Corp",
  "amount": 1450.00,
  "currency": "USD",
  "due_date": "2026-10-15"
}
      

Training Data Formulation

cat > data/raw/invoices.jsonl << 'EOF'
{"messages": [{"role": "user", "content": "Extract JSON from: Invoice #12345 from Acme Corp for $500 due on 2024-03-15"}, {"role": "assistant", "content": "{\"invoice_number\": \"12345\", \"vendor\": \"Acme Corp\", \"amount\": 500, \"due_date\": \"2024-03-15\"}"}]}
{"messages": [{"role": "user", "content": "Extract JSON from: PO-9876 from Widget Inc for $1,250 due 2024-04-01"}, {"role": "assistant", "content": "{\"invoice_number\": \"PO-9876\", \"vendor\": \"Widget Inc\", \"amount\": 1250, \"due_date\": \"2024-04-01\"}"}]}
EOF
  

Evaluation Suite with JSON Schema Validation

Enforce 100% deterministic schema compliance using MoroAI's evaluation harness:

name: "invoice-json-eval"
tests:
  - id: "test_invoice_schema"
    prompt: "Extract JSON from: Invoice #555 from Test Co for $99 due 2026-11-01"
    expected_schema:
      type: "object"
      required: ["invoice_number", "vendor", "amount", "due_date"]
      properties:
        invoice_number:
          type: "string"
        vendor:
          type: "string"
        amount:
          type: "number"
        due_date:
          type: "string"
  

Production Python Client

import json
import httpx

def extract_invoice_json(document_text: str) -> dict:
    """Query fine-tuned local extractor via Ollama."""
    response = httpx.post(
        "http://localhost:11434/api/generate",
        json={
            "model": "json-extractor:v1.0.0",
            "prompt": f"Extract JSON from: {document_text}",
            "stream": False,
            "format": "json"
        },
        timeout=15.0
    )
    raw_completion = response.json()["response"]
    return json.loads(raw_completion)

# Example invocation:
data = extract_invoice_json("Bill #4489 from CloudHost for $89.50 due 2026-10-31")
print("Structured Data:\n", data)
print("Vendor:", data["vendor"])