Document Extractor
Turns an invoice, packing list, or bill of lading into structured, reviewable line items.
Single-purpose LLM agent (vision). Turns a PDF or image of a customs document into structured fields, ready for downstream agents.
What it does
Reads a commercial invoice, packing list, bill of lading, or PO image and returns a strict Zod-validated structure: supplier, importer, Incoterms, ports, dates, line items (description, qty, unit price, COO, HS hint), totals. This is the input every other agent depends on — if extraction fails, nothing downstream runs.
Inputs
{
filename: string; // "INV-22041.pdf"
mimeType: string; // "application/pdf" | "image/png" | …
bytes: Buffer; // raw file
source?: 'upload' | 'inbox' | 'po-portal';
}
The model (Claude Sonnet, vision) receives the file directly via document/image content blocks — no OCR pre-processing step. Claude handles the vision natively, reading printed layout, tables, and stamps straight from the PDF or image.
Outputs
{
meta: {
documentType: 'commercial_invoice' | 'packing_list' | 'bill_of_lading' | 'po',
issueDate: '2026-05-24',
invoiceNumber: 'INV-22041',
incoterms: 'FOB',
currency: 'USD',
},
parties: {
supplier: { name: 'Hangzhou Lanyu Textile Co., Ltd.', country: 'CN', city: 'Hangzhou' },
importer: { name: 'Northwell Outfitters', country: 'US' },
consignee: { name: 'Northwell Outfitters', country: 'US' },
},
shipment: {
originPort: 'CNNGB', // Ningbo
destinationPort: 'USLAX',
mode: 'ocean_fcl',
eta: '2026-06-15',
},
lines: [
{
lineNumber: 1,
description: "Men's 100% cotton crew-neck T-shirts, knit, size M",
quantity: 12000,
unitOfMeasure: 'EA',
unitPriceCents: 100, // $1.00 / unit
valueCents: 1_200_000,
countryOfOrigin: 'CN',
htsHint: '6109.10', // if printed on the doc; classifier still re-runs
},
// … more lines
],
totals: {
subtotalCents: 12_000_000,
freightCents: 380_000,
insuranceCents: 60_000,
invoiceTotalCents: 12_440_000,
},
}
Schema validation. Every field is optional in the extraction schema, by design: because nothing is required, the model is never forced to fill a field it can't actually read, so it never invents a value to satisfy the structure. It returns what it can read and leaves the rest empty. Every extracted field is broker-reviewable in the drawer, and missing fields are flagged by downstream services so the broker knows what to ask the supplier for.
When it runs
- Drag-drop upload on Dashboard / Simulation / New entry wizard (
uploadsource) → fires immediately, surfaces the structured result in the inbox row. - Email inbox parse — when a packet arrives, every attachment runs through the extractor on receipt.
- Re-extract on demand — broker clicks "Re-parse" in the drawer when the source PDF is updated.
Dependencies
- Vision-capable model (
Claude Sonnet) that accepts PDF and image input directly. - No retrieval, no DB lookups at extract time. Pure vision-to-structure. The HTS hint surfaced from the document is only a hint; the classifier re-runs from the description regardless.
What success looks like
High-accuracy structured extraction across the fields a broker needs to open an entry — document type, parties, ports, dates, line items with quantities and values, and totals — from real commercial invoices, packing lists, bills of lading, and POs. Every field is surfaced for review rather than trusted blindly: we do not auto-file based on extracted data alone. The broker reviews every field in the drawer before transmit.
What it does NOT do
- Does not invent values. Empty fields stay empty; the schema makes this explicit (every leaf is optional). The drawer shows missing fields to the broker as "Missing — broker to confirm".
- Does not classify HTS codes. It surfaces any HS hint printed on the document, but the HTS Classifier re-runs from the description for every line regardless.
- Does not translate documents. Foreign-language invoices are extracted in the original language; translation is a separate concern.
- Does not read handwriting reliably. Scanned and printed text only. Handwritten amendments are flagged for broker review.
- Does not stitch multi-document packets (invoice + packing list + BoL) into a single record. Each document is extracted independently; the customs-clearance module reconciles them at the entry level.
Roadmap
- Q3 2026 — Multi-document packet reconciliation: when invoice + packing list + BoL arrive together, merge into one entry draft so the broker isn't reconciling line numbers manually.
- Q3 2026 — Handle handwritten amendments by surfacing the raw region to the broker instead of guessing.
- Q4 2026 — Auto-detect when a document is a revised version of one already in the inbox (same supplier + invoice number, different totals) and prompt the broker to diff.
- 2027 — Language hints: detect non-English documents and surface a "translate" affordance in the drawer for the broker.
Put your own book of entries through Commers.