Automating loan document processing means two things working together. First, pull each field off its document with a known source location and a confidence score. Then check that those fields agree across the whole file, and stop the file when the pay stub, the bank deposits, and the application report three different incomes. Extraction is the easy half now. Reconciliation is the work.
A modern document model pulls a gross monthly income figure off a clean pay stub with high accuracy. That is not where files go wrong. They go wrong when the numbers disagree, and an underwriter resolves that in thirty seconds because they know which source wins. Encode that judgment and the automation earns its place in the pipeline. Skip it, and you have just moved the ambiguity downstream with a confident-looking number attached.
Extraction feeds the cross-check
Treat every extracted value as a claim with a provenance rather than a fact. The output of the extraction stage is not “income: 6,400”. It is “income: 6,400, from document page 2, bounding box, confidence 0.94, method: line-item sum of YTD divided by pay periods”. Without that lineage you cannot reconcile anything, and you cannot show an examiner why a decision was made.
The document set in a mortgage or consumer loan file breaks into a few classes, and each wants a different extraction strategy:
- Structured forms with fixed layouts (the URLA, a standard tax transcript). Positional templates plus a model do better here than a model alone, because the layout is a strong prior.
- Semi-structured financials (pay stubs, bank statements) where the fields are stable but the vendor formatting is not. This is where a general document model earns its keep, and where you need entity resolution to know that “ACME CORP” on the stub and “Acme Corporation” on the deposit are the same employer.
- Free-form and legal text (the note, riders, letters of explanation). Extraction here is closer to reading than to parsing, and it is the highest-risk class because the values are covenants and dates, not line items.
Two failure modes matter more than raw accuracy. The first is confident extraction of the wrong instance: the model grabs a prior-year figure off a two-year tax document because both years sit on the same page. The second is silent omission, where a required disclosure page is missing and nothing notices. Validation catches both, which is why most of the build lives in that layer rather than in a better extractor.
Validation and cross-checks carry the decision
Once each field is a claim with lineage, you run deterministic checks over the whole file. These are ordinary rules, mostly, and they should be. A rule that says “declared income must be within tolerance of income derived from the last two pay stubs and validated against average monthly deposits” stays auditable and testable, and it will not drift the way a model does. Let the model read and normalise. Let the rules decide.
The checks we build fall into a few buckets:
- Internal consistency: does the income on the application match what the supporting documents show, does the property address on the appraisal match the title commitment and the note, do the loan amount and rate on the note match the approved terms.
- Completeness against a document checklist that depends on the loan program and the occupancy type. A conventional owner-occupied file needs a different set than a cash-out on an investment property, and the checklist is data, not code, so operations can change it without a release.
- Temporal validity: is the pay stub inside the age window at the point the file is decisioned, not at the point it was uploaded. This is a point-in-time correctness problem. If your pipeline re-evaluates staleness using today’s date on a file that was worked three weeks ago, you have introduced lookahead into your own audit trail.
- Identity and entity resolution across documents: the borrower named on the note is the borrower on the application is the account holder on the statement.
Give the validation layer a false-positive budget and hold it to that budget on a labelled eval set. A cross-check that fires on a fifth of clean files trains underwriters to ignore it. The flag that fires on real discrepancies and almost nothing else is the one that changes how the team works.
Straight-through processing is a confidence threshold you tune
Most of a loan portfolio does not need a human to touch the document mechanics. A clean W-2 borrower with consistent documents can run straight through the extraction and cross-check stages and land on an underwriter’s desk pre-verified. The point is to spend human attention on the files that actually disagree with themselves.
Routing is a policy you set and measure. Each file gets a decision: pass, review, or requeue for manual keying. The threshold is a business call about your false-positive and false-negative budgets, and you tune it on held-out files with known ground truth, then watch it for drift as document vendors change their formats and new loan programs enter the mix. When a bank changes its statement layout, extraction accuracy on that vendor drops before anyone notices, and monitoring per-source confidence over time is the only thing that catches it early.
What the audit trail has to carry
Lending decisions get examined, and the automation has to survive that. Under ECOA and its Regulation B, an adverse action has to come with specific reasons, which means every value that fed a decline has to trace back to the document it came from and the check it failed. Build the trail as a first-class artifact, not a log you reconstruct after the fact:
- The source document, page, and region for every extracted field.
- The model and version that produced it, and the confidence.
- Every validation rule that ran, its inputs, and its result.
- Any human override, who made it, and why.
Get that right and the file explains itself. An examiner or a borrower’s lawyer can follow any number on the decision back to the pixel it was read from. That is the difference between an extraction demo and a system you can run in production against real origination volume.
FAQ
Can a language model read a loan file end to end without a rules layer?
It can read it, but you should not let it decide alone. Extraction from a model is only useful once each field carries a source location and a confidence, and a deterministic layer checks the numbers against each other and against policy.
How do you handle a document type the model has never seen?
Route it to a human queue instead of guessing. A new investor overlay or a regional addendum should raise an unknown-document flag, get labelled, and enter the eval set before it ever runs straight through.
What is the right false-positive budget for validation checks?
Low enough that underwriters keep trusting the flags. If a cross-check fires on files that turn out clean more often than it catches real discrepancies, people start clicking past it, and the control is worse than useless.