Direct Answer
A reliable document workflow is a versioned state machine:
receive -> quarantine -> validate -> normalize -> extract
-> business checks -> human review when needed
-> commit -> retain or delete
Every output must point back to an immutable source and the exact processor configuration that produced it. OCR, a multimodal model, or an LLM may propose text and fields; deterministic code and authorized reviewers decide whether those fields may change a business system.
“Split PDFs, call AI, and save the JSON” is not an end-to-end design. It omits untrusted-file handling, provenance, retries, uncertainty, review, authorization, and correction.
Define the Document Contract
Begin with one document class and one outcome. For an invoice:
document_type: supplier-invoice
accepted_inputs: [pdf]
source:
immutable: true
max_bytes: policy-defined
required_fields:
- supplier_id
- invoice_number
- currency
- total_minor_units
business_oracles:
- supplier_exists
- purchase_order_matches
- line_sum_matches_total
- invoice_not_previously_committed
human_review:
- missing_required_field
- conflicting_evidence
- high-impact_policy
commit:
idempotent: true
authorized_principal: required
This contract distinguishes syntactic extraction from business acceptance. A model can read “1,000.00” correctly but still attach it to the wrong supplier or currency. That is an extraction success and a business failure.
Model the Artifacts and States
Keep the original immutable. Derived artifacts should have their own identity:
| Artifact | Purpose | Required lineage |
|---|---|---|
| Original bytes | Evidence and reprocessing source | source channel, owner, digest |
| Sanitized or normalized file | Safer parser input | parent digest, sanitizer revision |
| Page image | OCR or visual-model input | parent, page, render configuration |
| OCR text and layout | Searchable text and coordinates | engine, model, language, page |
| Extracted fields | Candidate business data | schema, evidence spans, confidence |
| Reviewed record | Human decision | reviewer, reasons, changed fields |
| Committed record | Downstream effect | idempotency key, target version |
The W3C PROV model provides reusable concepts for entities, activities, agents, usage, generation, and derivation. A workflow does not have to store RDF, but it should be able to answer the same questions: what was used, what was produced, by which process, under whose responsibility, and when.
State transitions should be explicit:
Do not infer completion from “the last function returned.” Persist each transition and its evidence so an interrupted worker can resume without repeating a side effect.
Secure Intake Before Parsing
Documents are hostile input. The OWASP File Upload Cheat Sheet recommends layered controls because no single validation is sufficient.
At intake:
- authenticate and authorize the uploader;
- allow only business-required extensions;
- canonicalize the filename, then generate a server-side storage name;
- compare extension, declared media type, detected type, and file signature;
- cap compressed and expanded size, page count, dimensions, and processing time;
- store outside the web root in quarantine;
- scan or apply content disarm where appropriate;
- parse in an isolated worker with no production credentials;
- reject encrypted, malformed, active, or unsupported content according to policy.
Content-Type: application/pdf is user-controlled metadata. A %PDF- prefix is not proof that every embedded object is safe. Malware scanning is also not a semantic validator.
Archive extraction requires separate limits on entry count, depth, total expanded bytes, and path traversal. A 5 MB upload can expand far beyond its compressed size.
Separate Normalization, OCR, and Interpretation
These stages have different outputs and failure modes:
- Normalization creates a parser-compatible representation without changing the authoritative original.
- OCR maps pixels to text and layout coordinates.
- Document parsing extracts native text, tables, forms, attachments, and structure.
- Classification selects the document contract.
- Semantic extraction proposes typed business fields and evidence spans.
- Validation compares proposals with source evidence and external systems.
Digital PDFs may already contain text, but that text can have broken reading order or hidden layers. Scanned PDFs need OCR. Mixed documents may need both native parsing and page rendering. Never assume every PDF is one kind.
For AI-assisted extraction, preserve:
- page and bounding box for every field;
- verbatim evidence span;
- OCR and model revisions;
- prompt and schema revision;
- source language and normalization;
- alternative candidates or uncertainty;
- validation and reviewer decisions.
The AI image understanding pipeline covers coordinate and evidence handling in more depth.
Validate Fields, Not Just JSON
Structured output proves syntax. It does not prove meaning.
For an invoice, deterministic checks can include:
currency is from the supported code set
total_minor_units >= 0
sum(line_amounts) + tax == total within defined rounding policy
supplier_id resolves in the current tenant
purchase_order is open and belongs to that supplier
invoice_number is not already committed for the supplier
date and payment terms are within allowed ranges
Validation should produce typed reasons. “Confidence below 0.8” is not enough. The system should distinguish missing evidence, parse failure, cross-system conflict, duplicate, policy denial, and model uncertainty.
Confidence Is a Routing Signal
A model confidence number becomes useful only after calibration on representative data. Measure observed error by confidence bucket, document class, source, language, and field.
High-impact fields may require review even at high confidence. Low-impact fields may be accepted with a lower threshold if downstream correction is easy. Route by expected error cost, not one global number.
Human Review Is a First-Class State
A review queue needs:
- the original page beside the proposed field;
- highlighted evidence and coordinates;
- prior values and conflict reasons;
- allowed corrections and reviewer identity;
- segregation of duties where required;
- no model-generated instruction that can approve itself;
- a durable decision and audit event.
Measure reviewer agreement and correction rate. If reviewers disagree, the problem may be an ambiguous policy or source document, not a weak model.
Human corrections are not automatically training data. They need consent, provenance, quality review, deduplication, and a leakage-safe split before reuse.
Make Retries and Commits Idempotent
Use an idempotency identity such as:
source_digest + stage + processor_revision + configuration_digest
The same stage with the same inputs can return the prior artifact. A changed OCR model or schema creates a new artifact rather than overwriting history.
For downstream writes:
approved_record_digest + target_system + operation
If a request times out after dispatch, mark the outcome unknown and reconcile with the target system before retrying. Blind retries can create duplicate invoices, cases, notifications, or payments.
A Runnable Go State Machine
This dependency-free example creates content-addressed artifacts and rejects invalid state transitions. It models orchestration only; a real parser still belongs in an isolated worker.
package main
import (
"crypto/sha256"
"encoding/hex"
"fmt"
)
type State string
const (
Received State = "received"
Quarantined State = "quarantined"
Validated State = "validated"
Extracted State = "extracted"
Reviewed State = "reviewed"
Committed State = "committed"
Rejected State = "rejected"
)
var transitions = map[State]map[State]bool{
Received: {Quarantined: true},
Quarantined: {Validated: true, Rejected: true},
Validated: {Extracted: true, Rejected: true},
Extracted: {Reviewed: true, Rejected: true},
Reviewed: {Committed: true, Rejected: true},
}
type Document struct {
ID string
SourceSHA string
State State
Revision int
CommittedID string
}
func digest(data []byte) string {
sum := sha256.Sum256(data)
return hex.EncodeToString(sum[:])
}
func advance(document Document, next State) (Document, error) {
if !transitions[document.State][next] {
return document, fmt.Errorf(
"invalid transition %s -> %s",
document.State,
next,
)
}
document.State = next
document.Revision++
return document, nil
}
func commitKey(document Document, target string) (string, error) {
if document.State != Reviewed || target == "" {
return "", fmt.Errorf("reviewed document and target are required")
}
return digest([]byte(document.SourceSHA + "|" + target)), nil
}
func main() {
source := []byte("%PDF-1.7 fixture")
document := Document{
ID: "doc-42",
SourceSHA: digest(source),
State: Received,
Revision: 1,
}
var err error
for _, next := range []State{Quarantined, Validated, Extracted, Reviewed} {
document, err = advance(document, next)
if err != nil {
panic(err)
}
}
document.CommittedID, err = commitKey(document, "erp.invoice.create")
if err != nil {
panic(err)
}
document, err = advance(document, Committed)
if err != nil {
panic(err)
}
fmt.Printf(
"id=%s state=%s revision=%d source=%s commit=%s\n",
document.ID,
document.State,
document.Revision,
document.SourceSHA[:12],
document.CommittedID[:12],
)
}
Expected output begins with:
id=doc-42 state=committed revision=6 source=
The source and commit identifiers are deterministic. Re-running the same approved operation can look up the existing result instead of creating another side effect.
Evaluate the Whole Workflow
Evaluate by document class, source, language, layout, quality, and risk:
| Layer | Useful measures |
|---|---|
| Intake | reject reasons, malicious samples, expanded-size failures |
| OCR | character/word error, reading order, coordinate coverage |
| Classification | per-class precision, recall, abstention |
| Extraction | field precision/recall, exact value, evidence location |
| Validation | conflict detection, false acceptance, false rejection |
| Review | queue age, correction rate, reviewer agreement |
| Commit | duplicate rate, unknown outcomes, downstream correction |
| Operations | p50/p95 latency, throughput, retries, cost per accepted document |
| Governance | deletion completion, lineage coverage, unauthorized access |
Do not publish “document accuracy” as one average. A wrong invoice total and a missing optional note do not have the same cost.
Operate and Evolve the Pipeline
Version the parser, OCR engine, model, prompt, schema, validators, and routing policy. Shadow a new version on existing documents, compare field-level regressions, and keep the previous path for rollback.
Treat every external document as potential prompt injection if extracted text reaches an LLM. The AWS ingestion security guidance explains why controls are needed before knowledge-base ingestion as well as at inference.
Retention applies separately to originals, page images, OCR text, embeddings, extracted records, prompts, logs, review snapshots, and training data. Deletion is complete only when policy-required copies and indexes are handled.
Frequently Asked Questions
What is an intelligent document processing workflow?
It is a governed pipeline that turns untrusted files into validated business records through intake, isolation, parsing or OCR, extraction, deterministic checks, review, and an authorized commit. The workflow also owns provenance, retries, retention, deletion, and recovery.
Should low confidence always trigger human review?
No. Confidence must first be calibrated against observed errors, and routing should include field impact, business-rule conflicts, source quality, disagreement, and correction cost. Some high-impact fields still require review even when a model is confident.
Is a file safe after MIME and malware checks?
No. Each check reduces a different risk, and parsers may still contain vulnerabilities or active content. Keep layered validation, isolated processing, resource limits, immutable originals, and separate authorization for any downstream effect.
How should retries work?
Reuse completed artifacts when the source, stage, processor, and configuration are identical. Retry only classified transient failures. Reconcile any write with an unknown outcome before attempting it again.
Which metric best represents workflow quality?
No single metric does. Report field-level correctness and business acceptance by slice, false acceptance, review load, downstream corrections, latency, cost per accepted document, duplicate effects, and recovery and deletion completion.
Common Failure Modes
- trusting extension or browser
Content-Type; - parsing documents in a privileged application process;
- overwriting the original with a converted file;
- using one confidence threshold for every field;
- accepting valid JSON without business validation;
- redacting sensitive data only with regular expressions;
- retrying a timed-out write without reconciliation;
- storing logs without source and processor revisions;
- training on reviewer corrections without provenance or consent;
- measuring average OCR quality but not financial or safety errors;
- claiming “zero human review” while exceptions accumulate;
- recommending a library list without a support and patching owner.
Production Checklist
- [ ] Define one document class, schema, business outcome, and failure policy.
- [ ] Quarantine uploads and apply layered validation before parsing.
- [ ] Keep originals immutable and identify every derived artifact.
- [ ] Record parser, OCR, model, prompt, schema, and configuration revisions.
- [ ] Preserve page, coordinates, and evidence spans for extracted fields.
- [ ] Validate against authoritative business systems before commit.
- [ ] Route by calibrated risk and error cost, not raw confidence alone.
- [ ] Make stages and downstream effects idempotent.
- [ ] Reconcile unknown outcomes before retrying writes.
- [ ] Test quality, security, review load, latency, cost, recovery, and deletion.
Related Resources
- AI Image Understanding: OCR, Parsing, and VQA
- RAG Pipeline Engineering
- Prompt Injection Defense
- Convert Images to PDF
Primary Sources
- OWASP File Upload Cheat Sheet
- W3C PROV-O Recommendation
- AWS: Securing the RAG Ingestion Pipeline
- Microsoft: Secure Intelligent Document Processing
Conclusion
Document automation is reliable when it preserves evidence and controls effects. Quarantine the source, create versioned artifacts, separate OCR and interpretation, validate fields against business truth, route uncertainty to review, and commit with idempotency. Optimize only after the workflow can explain what happened to every document and recover safely when a stage fails.