貨運代理如何以 AI 處理提單、發票,並由持牌人員提交海關申報
AI document processing for freight forwarders: bills of lading, invoices and the customs sign-off
指南提出貨運代理可用 AI 從提單、發票等文件抽取結構化資料,經規則校驗後將異常交由人員覆核,海關申報則由持牌人員提交。以每月 2,500 票、25,000 頁為例,模型費用估算約 $490(AED 1,800),計入覆核人手後每月成本約 AED 5,400,估算可節省約 AED 21,600。上線前應以 300 至 500 份真實文件建立固定測試集,並要求連續兩輪測試均沒有未被標記的識別碼錯誤。
A Dubai forwarder's AI project that pays for itself: read the document pack into structured records, flag what does not reconcile, and keep the customs declaration with a licensed human. Here is how to scope it, what it costs per page, and what accuracy to demand before you go live.
Freight forwarding in the Gulf is document work wearing a logistics badge. Every consignment arrives as a pack: commercial invoice, packing list, bill of lading or air waybill, certificate of origin, delivery order, and finally a WhatsApp photo of the signed delivery note. Someone re-types the fields your systems need; a licensed person files the customs declaration. Reading that pack into structured data is the clearest AI return a forwarder can get this year: it removes typing hours per consignment, catches mismatches before they reach customs, and leaves the legally sensitive step with a person. Vendors are pitching exactly this across Dubai in 2026, from document automation to WhatsApp status bots (Soluvide, Runbook). This piece covers the pipeline, the engines and their published per-page prices, the accuracy bar to demand before go-live, how "where is my shipment" gets answered from live data, and a scope you can hand straight to an IT partner.
What AI reads, and what a person still signs
"Reading" a shipping document is three steps, and the second one is where the money is:
- Extraction. Pull the fields: shipper, consignee, container or AWB number, description, weights, values, incoterms, HS codes where present. Every document type has its own schema. A bill of lading carries carrier, ports and references; a commercial invoice carries lines, quantities and values.
- Validation. Check what was extracted against what you already know. Does the container number on the B/L match the packing list? Does the consignee match the customer record? Do the line totals add up? Is the HS code plausible for the description?
- Routing. Clean records go into your shipment record or TMS. Anything that does not reconcile goes to a review queue, with the discrepancy highlighted and the source page attached.
Extraction alone only moves errors faster. Extraction plus validation catches the mismatched container number before it reaches the declaration, which is where the cost lives: a wrong identifier in a customs filing means amendment fees, delay, and often storage or demurrage on top. The DCSA makes the same point about the bill of lading: it is the most important trade document in container shipping, and its electronic B/L standard exists so B/L data flows straight through without manual re-entry.
The boundary is fixed, and vendors who claim otherwise deserve caution. AI prepares and checks data. A licensed person submits the customs declaration and carries the declarant's responsibility, through the relevant system, whether that is Dubai Customs' Mirsal 2 or the equivalents in other emirates and in Saudi Arabia. Check the current guidance from the authority you file with (Dubai Customs). The same rule covers anything with legal weight: issuing the B/L as a carrier, approving invoices and credit notes, committing to delivery dates your data does not support, and signing anything.
The pipeline: extract, validate, flag, approve
The build that works has four stages, and it is mostly unglamorous code:
- Intake. Email attachments, portal uploads and WhatsApp media land in one queue. Classify each file: B/L, invoice, packing list, certificate of origin, delivery order, or unknown.
- Extraction. OCR the page, then have the model emit a JSON record that conforms to a strict schema. Version the schema and pin the model version: change either and you re-run the test set.
- Deterministic validation. Rules in your code, not in the model. Cheap, transparent, and they never hallucinate.
- Exception routing. Every field carries a confidence score. Below threshold, or any failed rule, and the pack routes to a person with the source image and the extracted value side by side.
The schema is where you decide what a "field" means. A short Pydantic model for the invoice side of the pack:
from typing import Annotated, Literal
from pydantic import BaseModel, Field, StringConstraints
ContainerNumber = Annotated[str, StringConstraints(pattern=r"^[A-Z]{4}\d{7}$")]
class LineItem(BaseModel):
description: str
hs_code: str | None = None # suggestion only, never final
quantity: float | None = None
unit: str | None = None
net_weight_kg: float | None = None
gross_weight_kg: float | None = None
unit_value: float | None = None
currency: Literal["AED", "USD", "EUR", "GBP", "CNY", ""] | None = None
class ShipmentPack(BaseModel):
document_type: Literal["bl", "invoice", "packing_list",
"coo", "delivery_order", "other"]
bl_number: str | None = None
container_numbers: list[ContainerNumber] = Field(default_factory=list)
incoterm: str | None = None # closed list, checked downstream
consignee_name: str | None = None
lines: list[LineItem]
flags: list[str] = Field(default_factory=list)
Then the checks the model never gets to vote on. Container numbers carry an ISO 6346 check digit, so a wrong digit is provable in ten lines of Python:
def iso_6346_valid(container: str) -> bool:
if len(container) != 11:
return False
vals, v = {}, 10
for ch in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
if v % 11 == 0: # 11, 22 and 33 are skipped by the standard
v += 1
vals[ch] = v
v += 1
body = container[:10]
total = sum(
vals[c] * (2 ** i) if c.isalpha() else int(c) * (2 ** i)
for i, c in enumerate(body)
)
expected = "0" if total % 11 == 10 else str(total % 11)
return container[10] == expected
Beyond format checks, cross-document rules do the real work: container numbers must agree across the B/L, packing list and delivery order; parties must match the customer record; line values times quantities must recompute; gross weight must be at least net weight; the B/L date must precede arrival; incoterms must come from the 2020 set and currencies from ISO 4217. Any miss raises a named flag on the pack, and the pack stops.
Choosing the extraction engine
OCR is a commodity. The interesting choice is what turns OCR text into fields. Four viable patterns, at the list prices published on each vendor's pricing page (check them, they move):
| Approach | Example tools | Published price | Where it wins | Watch-outs |
|---|---|---|---|---|
| General OCR plus LLM structured output | Google Document AI Enterprise Document OCR ($1.50 per 1,000 pages) feeding a hosted LLM | roughly $20 per 1,000 pages all in (see the worked example) | messy, varied layouts, five or more document types, bilingual pages | token costs and vendor data terms; keep validation in your code |
| Specialised invoice parsing | Textract Analyze Expense ($0.01 per page), Google's pretrained invoice parser ($0.10 per 10 pages) | $10 per 1,000 pages | high-volume commercial invoices | tuned on consumer-style invoices, not carrier B/L layouts |
| Form and table parsing | Textract Forms ($0.05 per page) plus Tables ($0.015 per page), Google Form Parser ($30 per 1,000 pages) | $65 per 1,000 pages for Textract combined | fixed templates, clean scans | brittle across carriers and customers |
| Open-weights vision models on your own GPUs | vision variants from families such as Qwen2.5-VL, Llama 3.2 and Granite | no per-page fee; GPU and operations cost instead | data locality and PDPL posture | you own the MLOps |
The usual right answer for a forwarder is the first row. Document AI and Textract both charge pennies for raw OCR ($1.50 per 1,000 pages for Google's Enterprise Document OCR, $0.0015 per page for Textract's Detect Document Text), and a hosted LLM handles the messy part: carrier-specific B/L layouts, stamps over printed fields, mixed Arabic and English. The specialised parsers are cheaper per page but tuned for invoices, so you end up running them alongside something else anyway. If consignee data cannot leave your estate, run open-weights vision models on your own GPUs and pay in operations instead of per page.
One pattern worth copying: run the system inside your own cloud account, under your name, and go live only after it passes a test set built from your hardest real consignments and frozen before the build starts.
Worked example: 2,500 consignments a month
A mid-sized Dubai forwarder clearing imports through Jebel Ali and Dubai South. Assumptions: 2,500 consignments a month, an average pack of 10 pages, so 25,000 pages a month (300,000 a year), arriving as a mix of clean PDFs, scans and WhatsApp photos.
Model spend. OCR on Google Enterprise Document OCR at $1.50 per 1,000 pages: 25 x $1.50 = $37.50 a month. LLM extraction: roughly 2,000 input tokens per page (OCR text plus schema and instructions) and 800 output tokens, so 50M input and 20M output tokens a month. At $3 per million input and $15 per million output, a typical mid-tier hosted model price: $150 in, $300 out, $450 a month. Total model spend about $490 a month (AED 1,800), under $0.02 per page. The same volume on Textract Forms plus Tables ($0.05 plus $0.015 per page) would be $1,625 a month; the specialised expense parser ($0.01 per page) $250.
Current manual cost. Assume the documentation team spends 12 minutes re-typing and checking each pack: 30,000 minutes, about 500 hours, roughly 3 full-time people. At AED 9,000 a month fully loaded per documentation officer, AED 27,000 a month (about $7,350).
After go-live. Expect 60 to 70 per cent of packs to pass clean if the mix is mostly clean PDFs, fewer if WhatsApp photos dominate; take 60 per cent straight through. The other 40 per cent, 1,000 packs, need about 4 minutes each in the review UI: about 67 hours, 0.4 of an FTE, AED 3,600 a month. Post-go-live total: about AED 5,400 a month (models plus a part-time reviewer) against AED 27,000. The saving is roughly AED 21,600 a month (about $5,900), before you count faster quotes or the wrong-container incidents that never happened. A build costing six figures of dirhams pays back inside a year at those numbers. The review queue never disappears; it gets much shorter.
The accuracy bar: the gate before go-live
Vendors quote "95 per cent accuracy", which means nothing without definitions. Demand these instead:
| Field class | Examples | Gate before go-live | Enforcement |
|---|---|---|---|
| Identifiers | container, B/L, AWB, invoice, booking | 99 per cent or better exact match on the golden set; 100 per cent format check | any format failure stops the pack |
| Arithmetic | totals, quantities, weights, values | 100 per cent recomputed, no silent tolerance | mismatch means exception |
| Closed lists | incoterms, currencies, countries, ports | 99.5 per cent or better; anything off-list flags | enum failure means exception |
| Tariff | HS codes | suggestion only, quoting the tariff line | a human classifies, always |
| Free text | goods descriptions, marks | no numeric gate; confidence threshold | low confidence routes to review |
Three definitions make those numbers real:
- The golden set. 300 to 500 of your real documents, spanning every intake channel: mostly clean PDFs, a third scans, a fifth phone photos, including the bilingual Arabic-English ones. Include your worst cases, the consignments your team argued about. Freeze it before the build, and re-run it after every prompt, model or schema change, so a second team can be measured on the same set.
- Field-level accuracy. Exact match per field per document type, reported separately for identifiers and free text. A 95 per cent blend is a way of hiding a 60 per cent identifier failure rate.
- Silent errors. The metric that matters at the end: an extracted value that is wrong, passes every check, and reaches the declaration unflagged. A typo in a goods description is cosmetic. A wrong container number on a customs filing is a claim.
The gate to set before go-live: zero silent identifier errors across two consecutive golden-set runs, and a straight-through touch rate that has stopped improving week on week. Pin model versions, log every approval (who, when, which model version, which prompt), and keep a human sign-off screen between the extracted record and anything that touches customs, a bank or a customer's money.
Answering "where is my shipment?" on WhatsApp
The status question is not a document problem, it is a data problem, and the model's job in it is small. The answer lives in your TMS or freight system and in carrier feeds; the assistant only turns the question into a lookup and the record into a reply. The design that works:
- Identity first. The customer's WhatsApp number maps to a customer record; only then may shipment details be shared. Sharing consignee shipment data with an unverified number is a data protection failure, not a bot quirk.
- Verified facts only. The assistant replies with milestones your systems actually contain (vessel arrived, clearance in progress, out for delivery, with timestamps and source). It does not invent an ETA the data does not support, and if the customer is chasing a delay or disputing a charge, it hands the conversation to an operator with the history attached.
- Tool calls enforced server-side. The customer context is injected in your code, never chosen by the model:
{
"name": "shipment_status",
"description": "Return verifiable milestones for one shipment owned by the verified customer.",
"parameters": {
"type": "object",
"properties": {
"reference": {"type": "string", "description": "BL, booking or PO number"}
},
"required": ["reference"]
}
}
- Proactive updates through templates. Milestone messages go out as approved WhatsApp templates on your Business API number. Meta's template rules and the customer service window change, so check the current policy when you scope rather than trusting a vendor's screenshot.
The prerequisite is honest: a status bot is only as current as your shipment events. If milestones live in a shared drive and a WhatsApp group, wiring the bot to live data is the actual project, and the document pipeline above is what fills that data in the first place.
Compliance: PDPL, data residency and the declarant
Three rules keep this build safe in the UAE.
Personal data applies to shipping documents. Consignee names, addresses and phone numbers are personal data, and Federal Decree-Law No. 45 of 2021 (the PDPL, effective 2 January 2022) covers controllers and processors in the UAE and anyone processing the data of subjects inside the State. It imposes purpose limitation, accuracy, security measures and retention limits, and it leaves free zones with their own regimes, such as DIFC and ADGM, so confirm which regime applies to your licence before you pick a model API. Sending consignee records to an overseas model endpoint is a cross-border transfer: prefer in-region endpoints or self-hosted models, and paper the data processing terms before the first page is read.
The declarant stays liable. AI can draft the declaration and check the pack against the documents, but submission and the declarant's responsibility stay with your licensed staff. Put that in writing in the design, and make the sign-off screen impossible to bypass.
Standards pay twice. Align your internal shipment record with the DCSA electronic B/L standard (open APIs for straight-through B/L data, aligned with IMO, ISO and UN/CEFACT). Carrier eBL data then flows into the same record your document pipeline fills, and you enter it once instead of three times.
The scope to hand an IT partner
Copy this, fill the brackets, and you have a pilot scope an engineering team can quote against:
AI document processing for freight forwarding: pilot scope
1. Volume: [N] consignments/month, [M] pages/month, channels: email, portal, WhatsApp.
2. Document types: B/L, air waybill, commercial invoice, packing list,
certificate of origin, delivery order, declaration draft.
3. Fields: [list per document type; ~40 on the invoice].
4. Extraction: OCR + LLM structured output; schema versioned; model versions pinned.
5. Validation: ISO 6346 check, cross-document container and party match,
totals recomputed, incoterm/currency/country closed lists, date sanity.
6. Exceptions: named flags; queue UI with source page beside extracted value; SLA [4] hours.
7. Outputs: shipment record into [TMS/FMS]; declaration draft, never submitted; API/CSV.
8. WhatsApp: status lookup on [number]; identity via [CRM]; template list; human hand-off rules.
9. Compliance: PDPL review; data residency [UAE or self-hosted]; retention [X] months; DPAs signed.
10. Acceptance: golden set of 300+ documents frozen before build; gates per field class;
zero silent identifier errors in two consecutive runs; licensed person submits every filing.
What to do next
Pull 300 real documents across your channels and freeze the golden set. Define your field lists and validation rules. Pick the engine and the data residency. Pilot one lane with the review queue running in parallel with manual entry. Only then widen the funnel and switch on the WhatsApp status replies. Time spent at the front on the golden set and the rules buys a pipeline your documentation team will actually thank you for, and a customs sign-off that never once left human hands.
If you want the review queue and the integration built around your own systems rather than bolted onto a vendor's, that is our kind of work: Azrty builds AI engineering projects on your infrastructure and connects them to your systems, from our team in Dubai, with your developers able to extend what we leave behind. Where several model providers are in play, one gateway in front of them (FastLLM Proxy) keeps routing, budgets and access control in one place instead of scattered across services.
Originally published on Azrty.
來源:DEV Community · dev.to