Why a DAG
The pipeline is a directed acyclic graph: every step runs once per invoice, depends only on earlier steps, and the branch taken depends on the data. The orchestrator gives each step a retry policy, a timeout and a run history, and it stops a failed step from hiding inside a prompt. See ADR-001.
The graph
Two steps use a model for extraction. Classification uses a smaller model. The exception agent and the human reviewer are the only steps that handle non-routine cases.
Node specification
| Node | Kind | Input | Output | Retry | Timeout |
|---|---|---|---|---|---|
| Ingest | deterministic | email connector or portal upload | raw document + metadata | 3 × exponential | 2 min |
| Normalize | deterministic | raw document | pages, text, SHA-256 (Secure Hash Algorithm, 256-bit) | 3 × | 2 min |
| Classify | LLM (small) | page text | document_type + confidence | 2 × | 30 s |
| Extract | LLM (frontier) | pages + invoice.v3 schema | validated JSON (JavaScript Object Notation), per-field confidence | 2 × | 3 min |
| Validate | deterministic | extracted JSON | pass / fail with reasons | none | 10 s |
| Enrich | tool (MCP) | vendor_id | vendor status, bank, terms | 3 × | 30 s |
| Match 3-way | deterministic | invoice, PO (Purchase Order), GRN (Goods Receipt Note) via MCP (Model Context Protocol) | match table, tolerance result | 3 × | 1 min |
| Resolve exception | agent (MCP + RAG (Retrieval-Augmented Generation)) | match table, clauses | resolution draft with citations | 1 × | 10 min |
| Human review | human | resolution draft | approve, reject or query | none (SLA (Service-Level Agreement) 1 business day) | — |
| Approval route | deterministic | amount, cost centre, exception type | approver role | none | 10 s |
| Post to ERP (Enterprise Resource Planning) | tool (MCP) | approved invoice | ERP document ID (identifier) | 3 × with idempotency key | 2 min |
| Schedule payment | tool (MCP) | ERP document ID, due date | payment run entry | 3 × | 1 min |
| Archive audit | deterministic | all outputs and trace | immutable audit record | 5 × | 2 min |
Retry counts are attempts including the first. Timeouts are per attempt. Human review has a service-level target rather than a timeout.
The definition
The DAG is code, so it is versioned and reviewed like any other change. The sketch below is illustrative: the same structure maps onto Airflow, Dagster, Prefect or Temporal, and the graph and retry policies would stay the same.
@dag(id="ap_invoice", schedule="on_event:invoice.received", max_active_runs=50)
def ap_invoice():
doc = ingest()
pages = normalize(doc)
kind = classify(pages) # LLM, small tier
if kind.document_type != "invoice":
route_to_review_queue(doc, kind)
return
fields = extract(pages) # LLM, frontier tier; schema-validated
checked = validate(fields)
vendor = enrich(checked) # MCP: vendor.lookup
match = match_three_way(checked) # MCP: po.get, grn.search; rules only
if match.within_tolerance:
decision = approval_route(checked, match)
else:
draft = resolve_exception(checked, match) # agent, MCP tools, RAG
decision = human_review(draft) # blocks until a person decides
decision = approval_route(checked, match, decision)
if decision.approved:
erp_doc = post_to_erp(checked, decision, idempotency_key=doc.sha256) # MCP: invoice.post
schedule_payment(erp_doc) # MCP: payment.schedule
archive_audit(doc, fields, match, decision)Behaviour under failure
- A retried node is safe to run twice: posting uses the document hash as an idempotency key, so the ERP cannot record the invoice twice.
- If extraction fails schema validation twice, the invoice goes to review with the raw output attached, not to the ERP.
- If the gateway or ERP is down, the post node waits and retries; the invoice stays approved and nothing is lost.
- Human review does not time out into approval. Overdue reviews escalate to the AP (Accounts Payable) lead.
- Every run has a trace ID that appears in the audit record, the gateway log and the ERP document.
Build this for your business
This example uses a generic invoicing system, but the same pattern — orchestrated steps, governed tools, grounded knowledge and a documented lifecycle — fits most back-office processes. We can scope a pilot on your own documents and systems.
Book a discovery call