Document AI — from PDF claim LLM extraction to rule-based decisions and audit trails
Walk one cycle of the VeridianLife scenario — structuring PDF claim forms via OCR + LLM extraction, applying a 6-rule decision engine to auto-approve / escalate / reject, and leaving an auditable reasoning trail.
Workshop goal
By the time you finish this Workshop, you will have walked through one full cycle of the following flow inside D.Hub.
- Load a single scenario into portal so that two sub-collections (
inboxandprocessed), 3 datasets, 3 code nodes, 3 pipelines, an ontology with 3 entities and 2 relations, a dashboard, and one knowledge are all registered together. - Inspect the metadata-only
claim_documents(object type) dataset, which holds PDF claim form metadata. - Use the
claim_extractionpipeline to run OCR + LLM extraction on one PDF at a time, surfacing structured fields like incident date, claim amount, diagnosis code, policy number, with a per-fieldconfidence_score. - Use the
decision_workflowpipeline's 6-rule engine to assign one ofAPPROVED/REJECTED/ESCALATED, and leave a why trail indecision_log. - Expand a
Document/Claimant/Policygraph to surface a single claimant's claim cluster. - Read the
claims_processingdashboard for throughput, decision distribution, and SLA compliance in one view.
The Workshop centers on the coupling pattern of LLM-driven automatic extraction with rule-based decisioning. Recommended duration: 90 minutes.
Prerequisites
- An analyst or engineer account with access to D.Hub portal (Editor or higher)
- ~42 KB of download room for one scenario zip
No terminal, Python, or dhub2-examples clone needed.
1. Load the scenario (10 min)
docai.zip Download(62 KB)Go to Collections → more (⋯) menu → Import (가져오기) and upload the zip.
Following manifest.json, the import creates the following in order:
- Two collections —
inbox(alias: Incoming Claim Documents),processed(alias: Processed Claims) - Three datasets —
claim_documents(inbox, object type),extracted_fields(processed),decision_log(processed) - Three codes (Python) —
document_parser,claim_adjudicator,build_docai_ontology - Three pipelines —
claim_extraction,decision_workflow,ontology_materialization - Ontology — three entities (
Document,Claimant,Policy), two relations (filed_by,covered_by) - One knowledge —
claims_handbook(claim processing guidelines) - One dashboard —
claims_processing
Step 1 is complete once inbox and processed show in the left tree. The received → processed time flow is intentionally expressed at the collection layer.
2. Browse the claim documents (10 min)
In the inbox collection, claim_documents is an object-type dataset. Each row corresponds to one PDF file; the columns are metadata, not the PDF body itself.
claim_id— Unique claim identifierdocument_key— PDF key in the S3 / object storeclaimant_name— Claimant's namepolicy_number— Insurance policy numberreceived_at— Timestamppage_count— Page countsource_channel—email/web_portal/mobile_app
The PDF body itself is fetched and processed by document_parser in the next step via the document key. This separation — metadata dataset + object store — is the standard pattern for large-volume unstructured data.
In the processed collection, extracted_fields and decision_log start empty (0 rows). The next-step pipelines fill the first rows.
3. LLM-driven field extraction (20 min)
In the processed collection's Pipelines section, open claim_extraction. One node — document_parser reads claim_documents row by row and processes one PDF at a time.
The document_parser script's two-stage flow:
- OCR (pdfplumber) — Extract the text layout from PDF pages. Falls back to OCR for scanned images.
- LLM extraction — Send the extracted text to the LLM with a structured-extraction prompt and receive the following fields as JSON:
incident_date— Incident dateclaim_amount— Claim amountdiagnosis_code— ICD diagnosis code (for medical claims)policy_number— Policy numberprovider_name— Provider name (when applicable)confidence_score— 0–1, the LLM's self-assessed confidence
The key column is confidence_score. The prompt is designed to elicit honest uncertainty, and the next-step decision engine auto-escalates any claim with confidence below 0.6.
Press Run. When it finishes, open the Preview tab on extracted_fields. The row count should match claim_documents, and confidence_score should distribute in the 0–1 range.
4. 6-rule decision engine (15 min)
Open the decision_workflow pipeline. One node — claim_adjudicator reads extracted_fields and produces decision_log.
The claim_adjudicator evaluates 6 rules in priority order.
| Priority | Rule | Decision |
|---|---|---|
| 1 | confidence_score < 0.6 | ESCALATED — LLM low confidence |
| 2 | Required field missing (incident_date, claim_amount, policy_number) | ESCALATED — Extraction incomplete |
| 3 | diagnosis_code in exclusion list (e.g. Z00.0 routine check) | REJECTED — Out of coverage |
| 4 | claim_amount > 5000 | ESCALATED — High-amount manual review |
| 5 | claim_amount <= 1000 AND confidence >= 0.85 | APPROVED — Low-amount auto-approval |
| 6 | Otherwise | ESCALATED — Manual review (safe default) |
The key design choice is defaulting to ESCALATED. Auto-approval only accepts high-confidence, low-amount claims; everything else goes to humans. The pattern reflects the false-positive cost ≫ false-negative cost asymmetry of insurance.
Press Run. When it finishes, open decision_log. On the seed data, decisions distribute roughly APPROVED : REJECTED : ESCALATED ≈ 4 : 2 : 4. The reason column carries a one-line explanation per row — the core column for audit and regulatory response.
5. Ontology + graph exploration (10 min)
Run ontology_materialization once. build_docai_ontology reads three datasets in batch mode and lands the following five artifacts in upsert mode.
| Artifact | Kind | Meaning |
|---|---|---|
Document | Entity | Claim PDF. Key: claim_id. Attributes: received_at, page_count, source_channel, decision, reason |
Claimant | Entity | Claimant. Key: claimant_name (normalized). Attributes: claim_count |
Policy | Entity | Insurance policy. Key: policy_number. Attributes: coverage_type |
filed_by | Relation | Document → Claimant |
covered_by | Relation | Document → Policy |
In the Graph explorer, surface a single claimant's claim cluster.
MATCH (c:Claimant)<-[:filed_by]-(d:Document)-[:covered_by]->(p:Policy)
WHERE c.claim_count >= 3
RETURN c, d, p
LIMIT 25
A claimant with three or more claims appears, with all their documents and the policies they cover. When several Document nodes share one Policy, that's the first visual signal of repeat-claim patterns.
6. Dashboard + audit trail (15 min)
Open claims_processing (alias: Claims processing dashboard). Eight widgets share the screen.
- Claims Received (statistic) —
COUNT(*)overclaim_documents - Decisions Made (statistic) —
COUNT(*)overdecision_log - Avg Extraction Confidence (statistic) —
AVG(confidence)onextracted_fields(to 2 decimal places) - SLA Met Rate (statistic) — % rate of
sla_met = trueondecision_log - Decision Distribution (donut) — Counts per
decisionondecision_log(APPROVED / REJECTED / ESCALATED distribution) - Escalations by Reason (bar) — Counts per
reasonondecision_log, descending - Claims by Channel (bar) — Counts per
source_channelonclaim_documents(email/web_portal/mobile_app) - Recent Claims (data table) — 100 most recent rows by
received_atdesc
The operational signals are two statistics + two distributions. If Avg Extraction Confidence drops below 0.7, audit the LLM prompt or OCR quality; if SLA Met Rate is low, the §4 decision engine is routing too many cases to ESCALATED. The first bar of Escalations by Reason tells you in one line which rule fires most.
7. Next steps and a retrospective (10 min)
By this point you've walked through five flows on a single scenario.
- Metadata-dataset + object-store separation (object type pattern)
- OCR + LLM structured extraction with
confidence_scoresignaling - Decision engine's ESCALATED-as-default asymmetry
- Graph view of repeat-claim clusters
- Audit trail via
reasoncolumn
Pick the most appealing direction:
- The
refund-approvalWorkshop covers the HITL agent variant of the same shape — default ESCALATED → human review → automated execution maps cleanly to insurance. - The Analyst Path Managing widgets lesson — rebuild the Escalations by Reason widget's SQL by hand.
- Map the document → structure → decision shape to your own domain (contract review, invoice processing, résumé screening).
Verification checklist
- Both
inboxandprocessedcollections appear in the collection tree, withclaim_documentsset as object type. - After
claim_extraction, theconfidence_scorecolumn onextracted_fieldsis in the 0–1 range, with at least one or two rows in 0.4–0.55. - After
decision_workflow, thedecision_logdecisions are distributed across APPROVED / REJECTED / ESCALATED and each row has a populatedreasontext. - In the Graph explorer, starting from one
Claimantyou can expand the 3-hop pathfiled_by→Document→covered_by→Policy. - The
claims_processingdashboard's Decision Distribution widget shows ESCALATED as the largest slice (a direct consequence of the default ESCALATED design).