AI Agents · Ai

AI Agent for Vendor Onboarding

AI Agent for Vendor Onboarding is the work that defines the next phase of enterprise software. ERP systems hold the most valuable business data in the company — customers, orders,.

John Kihiu12 min read

Vendor onboarding is a document-extraction problem wearing an ERP costume. A new supplier sends a W-9 (or equivalent tax form outside the US), a business registration certificate, and a bank confirmation letter — usually as scanned PDFs or phone photos — and someone on the AP team retypes the same dozen fields into the vendor master. An AI agent can do the retyping. It should never be trusted to do the approving, especially on the two fields that matter most: the tax ID and the bank account.

The actual workflow

Onboarding, as distinct from ongoing supplier risk monitoring, is a bounded intake process: a document comes in, structured fields come out, and a human either accepts or corrects them before the vendor record goes live. The agent's job is narrow — turn unstructured documents into a proposed Vendor record — and the system's job is to make sure nothing proposed by the agent reaches a live payment run without a person having looked at it.

In practice this is three stages: extraction (OCR plus an LLM pass to pull named fields out of the document), matching (does this vendor already exist under a different name or address), and staging (writing the proposal somewhere a human reviews it, not directly into the vendor master).

Document extraction: OCR plus a schema, not a chatbot

The extraction step is OCR (or a vision-capable model reading the PDF/image directly) followed by an LLM call constrained to a fixed schema — legal name, tax ID, registered address, bank name, account number, routing/SWIFT code, and a confidence score per field. The model is not asked to "summarize the document" or "tell me about this vendor"; it is asked to fill in a schema and to say when it isn't sure. A tax ID it can't read clearly should come back null with low confidence, not a guessed digit.

PYTHON · EXTRACTION SCHEMA
class VendorDocExtraction(BaseModel):
    legal_name: str | None
    tax_id: str | None
    tax_id_confidence: float          # 0-1, from the model
    registered_address: str | None
    bank_name: str | None
    bank_account_last4: str | None    # never extract the full number into logs
    routing_or_swift: str | None
    bank_field_confidence: float
    source_document_type: Literal["w9", "reg_certificate", "bank_letter", "other"]

def extract_vendor_fields(document_bytes: bytes, doc_type_hint: str) -> VendorDocExtraction:
    text = ocr_or_vision_extract(document_bytes)
    result = llm_extract(text, schema=VendorDocExtraction, doc_type_hint=doc_type_hint)
    if result.tax_id_confidence < 0.85 or result.bank_field_confidence < 0.85:
        result = flag_for_manual_entry(result)
    return result

Confidence thresholds matter more than model choice here. A field extracted at 60% confidence and silently written to the vendor record is worse than no extraction at all, because it looks authoritative to whoever reviews it next.

Mapping extracted fields to the Acumatica vendor master

Once you have clean fields, the mapping to Acumatica's Vendors (AP303000) screen is mostly mechanical: legal name to the vendor name, tax ID to the Tax Registration ID field (with the tax zone set based on jurisdiction, not guessed by the model), registered address to the primary address, and bank details to a new, unconfirmed row in the vendor's payment instructions — not the active default payment method. Vendor class and terms are business decisions, not extractable facts, so the agent should leave them on defaults and let AP assign them. The mapping step is a good place for a deterministic validator, not another LLM call: check tax ID format against the jurisdiction's known pattern, check IBAN/routing checksums, and reject anything that fails before it's even shown to a reviewer.

Duplicate vendor detection

New-vendor forms are also how duplicate vendors get created — a supplier changes its trading name, a subsidiary submits its own paperwork, or someone simply doesn't check before creating a new record. Before staging a new vendor, run the extracted tax ID and normalized legal name against existing vendors: exact match on tax ID is a hard stop (surface the existing vendor, don't create a new one), and a fuzzy name/address match above a similarity threshold is a soft flag for the reviewer to confirm rather than a block. Skipping this check is how AP ends up with three vendor records for the same company, each with different payment details, which is exactly the confusion that makes fraud harder to catch later.

Why bank and tax fields never auto-approve

This is the section that matters most. Business email compromise scams specifically target vendor onboarding and vendor bank-detail changes — an attacker submits a "vendor update" with legitimate-looking letterhead and a bank account that isn't the real supplier's. An AI agent extracting fields from a convincing forged document will extract them accurately and confidently. Extraction accuracy says nothing about whether the document is genuine.

Extraction is not verification

The agent can tell you what a document says. It cannot tell you whether the document is real, whether the bank account belongs to the vendor, or whether the request came from the actual supplier and not an attacker. Payment-related fields — bank account, routing/SWIFT, and any change to an existing vendor's payment instructions — must always route to a human step outside the document itself: a callback to a known phone number, a check against a secondary source, or your organization's existing vendor-verification policy. No confidence score from the extraction model substitutes for that.

The practical control is structural, not procedural: the agent writes to a staging table or an unapproved vendor state, never directly to an active Vendor record with payable status. A human with AP authority reviews the proposed fields side-by-side with the source document, corrects what's wrong, and only then promotes the record — and that promotion step is exactly where the bank-detail callback belongs, not before.

What a reasonable version of this looks like

StageAutomatedHuman-required
Document intakeOCR/vision extraction into a fixed schema
Field mappingDeterministic mapping + format validation
Duplicate checkTax ID exact match, fuzzy name matchConfirm soft matches
Non-payment fieldsPre-filled for reviewApprove or correct
Bank/tax fieldsPre-filled, flaggedVerify via out-of-band channel, then approve
Record activationSign-off before vendor is payable

The value the agent adds is real — it turns a 20-minute manual data-entry task into a two-minute review — but the value is in the time saved on the boring fields, not in removing the person who checks the dangerous ones. Build it so the fastest path is still the one where a human confirms the bank account before the first payment goes out.

John Kihiu
Acumatica ERP Developer · Laravel Engineer

Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.