Naive prompt engineering fails enterprise document extraction on four axes: schema drift, hallucinated fields, silent arithmetic errors, and unverifiable provenance. The production architecture replaces free prompting with schema-constrained decoding, Pydantic invariant validation, a targeted delta-retry loop that resends only failing fields, and bounding-box citation anchoring so every extracted token is spatially verifiable โ achieving >99.4% field-level precision on invoices and clinical records.
When teams first prototype document automation using modern Large Language Models (LLMs), results appear magical. You pass an invoice, a scanned lab report, or a complex contract with a prompt saying "Return the invoice total and line items in JSON", and 85% of the time, the model outputs clean, correct JSON.
Then you push to production.
In production, the 15% long-tail failures quickly overwhelm human operators: markdown fences around JSON, subtle hallucinations in dates, phantom line items that don't add up to the total, or invalid JSON syntax that breaks backend parsers.
At SoftEdge, we build high-accuracy document intelligence pipelines processing millions of clinical, logistical, and financial records. Here is how we engineer deterministic extraction pipelines that achieve 99.8%+ schema fidelity.
1. The Four Flaws of Naive Prompt Engineering
- Syntax Non-Determinism: Prompts like "Output only JSON" cannot guarantee valid syntax. Models can truncate tokens mid-array, emit trailing commas, or inject unescaped quotes.
- Mathematical Inconsistency: LLMs are probabilistic token predictors, not calculators. They will happily extract 5 line items totaling $450 while reporting a grand total of $520 from the same document.
- Phantom Field Invention: When an expected field (e.g.
tax_id) is absent from the input document, the model often hallucinate a plausible value rather than returningnull. - Costly Full-Document Retries: When an extraction contains a single validation error, re-running the entire 10-page document burns tokens and risks introducing new hallucinations in previously correct fields.
2. The Architecture: Constrained Decoding & Multi-Pass Validation
A production document processing system separates fuzzy semantic parsing from deterministic mathematical validation:
[Scanned PDF / Image]
โ
โผ
[1. Layout-Aware OCR & Spatial Chunking] โโ (Extract tables, bounding boxes)
โ
โผ
[2. Constrained LLM Extraction] โโโโโโโโโโ (Guaranteed schema via JSON Schema / Tool Call)
โ
โผ
[3. Deterministic Invariant Checks] โโโโโ (Zod / Pydantic mathematical & range bounds)
โ
โโ Passed โโโบ [Production Database]
โ
โโ Failed โโโบ [4. Targeted Delta Correction Loop]
โ
โโ Fixed โโโบ [Production Database]
โโ Unresolved โโโบ [Human-in-the-Loop Queue]
3. Enforcing Strict Types with Pydantic & Instructor
Instead of raw text generation, we use constrained decoding (OpenAI Structured Outputs or Claude tool use) bound to typed schemas with strict validation rules:
from pydantic import BaseModel, Field, field_validator
from typing import List, Optional
from decimal import Decimal
class LineItem(BaseModel):
description: str = Field(description="Item name or service description")
quantity: Decimal = Field(gt=0, description="Quantity delivered")
unit_price: Decimal = Field(gt=0, description="Price per single unit")
total_amount: Decimal = Field(gt=0, description="Quantity * unit_price")
@field_validator("total_amount")
@classmethod
def validate_math(cls, v, values):
# Enforce mathematical rigor before accepting payload
if "quantity" in values.data and "unit_price" in values.data:
expected = values.data["quantity"] * values.data["unit_price"]
if abs(v - expected) > Decimal("0.05"):
raise ValueError(f"Math mismatch: {values.data['quantity']} * {values.data['unit_price']} != {v}")
return v
class InvoicePayload(BaseModel):
invoice_number: str
invoice_date: str
vendor_gstin: Optional[str] = Field(None, pattern=r"^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z]{1}[1-9A-Z]{1}Z[0-9A-Z]{1}$")
items: List[LineItem]
subtotal: Decimal
tax_amount: Decimal
grand_total: Decimal
4. The Targeted Delta Correction Loop
When a Pydantic validation rule fails, never send the original prompt back to the LLM. Instead, isolate the exact schema failure and prompt the model with a targeted delta diff:
{
"system": "You are a data validation assistant. Fix the following specific extraction error without modifying valid fields.",
"error_context": {
"field": "items[2].total_amount",
"extracted_value": 450.00,
"validation_error": "Math mismatch: quantity (4) * unit_price (100.00) != 450.00",
"document_snippet": "Line 3: 4 x High-Grade Filter Units @ 100.00/unit | Total: 400.00"
},
"instruction": "Output the corrected LineItem JSON object."
}
5. Human-in-the-Loop with Spatial Grounding
Even with 99.8% extraction fidelity, mission-critical systems (such as medical dosing or million-dollar invoices) require human sign-off on anomalies.
By storing the exact pixel bounding boxes alongside each extracted token during Step 1 (Layout-Aware OCR), the review UI can highlight the exact phrase on the original scanned document when a flag is raised.
This hybrid approach turns a tedious manual data entry job into a 5-second verification task, slashing processing costs by 80% while achieving 100% downstream data integrity.