Building AI agents for ERP and finance systems
AI agents can take over real parts of an ERP workflow, like matching invoices or preparing journal entries. But a general-purpose agent with access to the whole ERP is not a financial control system.
ERP and accounting systems are full of rules: master data, posting rules, approval steps, fiscal periods, and records that have to stay auditable. An agent that can call any ERP endpoint and reason over unlimited transaction data will sooner or later produce an action that looks right and isn’t. The safer design gives the model small, bounded decisions and leaves validation, permissions, transaction integrity and every state change to deterministic services.
The core rule
Bound the agent, not the business process. Give each agent one narrow job, scoped data, typed tools and clear states, and put a deterministic validation layer in front of every ERP change.
From copilot to controlled workflow
The real difference isn’t a smarter or less smart model. It’s whether the model drives execution or the system does.
Model-driven
- One generalist model
- A large slice of the ERP in its context
- Many overlapping tools
- Writes straight into the ERP
Invalid accounts, wrong entities, duplicate postings, unapproved payments, a thin audit trail.
System-controlled
- A router picks the workflow
- A read-only agent retrieves and reconciles
- A policy layer handles approvals
- Deterministic checks: schema, permissions, accounting rules, balances, idempotency
- One mutation service posts, then the result is verified and audited
What the architecture should optimize for
- Minimal relevant context rather than maximal context.
- Deterministic retrieval constraints before semantic retrieval.
- Typed tool contracts rather than generic “update ERP” functions.
- Server-side authorization rather than permissions encoded only in prompts.
- Explicit validation before mutation rather than trusting model output.
- Idempotent operations so retries do not create duplicate financial effects.
- Observable execution so every material decision can be reconstructed later.
Context isolation: give the model exactly what the task requires
ERP data is highly contextual. The same vendor, account, tax treatment, or cost center can have different meanings across legal entities, fiscal periods, currencies, and business units.
Dumping a large portion of an ERP database into an agent context creates more than a token-management problem. It creates an authority problem because the model may see information that is irrelevant to the current transaction and still use it when forming a decision.
Common failure modes
Context distraction
Unrelated accounts, vendors, historical transactions, and policies compete for the model’s attention.
Context contamination
A malformed, stale, or attacker-controlled record becomes part of the reasoning context and influences later actions.
Cross-entity ambiguity
Records from different subsidiaries or accounting regimes appear together even though only one legal entity is relevant.
Historical-state confusion
A valid identifier from a previous fiscal period is mistaken for an identifier that is currently active.
Better pattern
Keep the system prompt focused on operational constraints. Put dynamic business data into structured retrieval results instead.
In the prompt
- Task constraints
- Allowed workflow
- Tool boundaries
- Output contract
In scoped runtime context
- Entity, fiscal period, currency, cost centre
- Transaction identifiers
- The policy facts that apply
Engineering principle
A large context window does not compensate for poor context selection. Retrieve fewer facts with stronger provenance instead of supplying the model with an unrestricted ERP snapshot.
Scoped RAG: retrieval must preserve accounting boundaries
Retrieval for ERP agents should behave more like a database query than a generic knowledge search.
A semantic match such as “office equipment” is useful for finding descriptive text. It is not sufficient to determine which legal entity, account, tax code, or fiscal period should be used in a posting.
- Agent query
- Metadata filters
- Exact + semantic search
- Rerank
- Small result set with provenance
Retrieval rules for financial systems
Filter before retrieval
Apply authorization and business metadata constraints before semantic ranking. Retrieval should not first discover records and only later decide whether the agent was allowed to see them.
Combine exact and semantic search
Identifiers such as invoice numbers, purchase orders, tax identifiers, and account codes benefit from exact matching. Semantic retrieval is more useful for natural-language descriptions and policy text.
Return structured facts with provenance
A result should carry enough information for the application to identify where it came from.
{
"document_id": "INV-2026-01842",
"entity_code": "EU02",
"fiscal_period": "2026-09",
"vendor_id": "V-004281",
"currency": "EUR",
"source_system": "erp",
"source_version": "current"
}
Keep retrieved content separate from instructions
Invoices, supplier notes, PDFs, email bodies, and OCR output are data. They are not trusted instructions to the agent.
Tool design: expose business capabilities, not your entire ERP API
An agent should not receive an unrestricted toolbox containing dozens of overlapping CRUD-style endpoints.
The important design question is not “How many APIs does the ERP have?” It is “Which operations does this agent actually need to complete this workflow?”
A narrow tool registry reduces ambiguity. More importantly, the backend must still enforce authorization and validation independently of the model.
Weak interface
{
"name": "update_ledger",
"description": "Updates financial records in the ERP",
"parameters": {
"account": "string",
"amount": "number",
"type": "string"
}
}
The tool exposes an ambiguous mutation with almost no machine-checkable business semantics.
Stronger interface
{
"name": "post_journal_entry",
"description": "Creates a journal voucher from a validated transaction object.",
"parameters": {
"entity_code": {
"type": "string"
},
"debit_account": {
"type": "string"
},
"credit_account": {
"type": "string"
},
"amount_minor": {
"type": "integer",
"minimum": 1
},
"currency": {
"type": "string"
},
"idempotency_key": {
"type": "string"
},
"source_document_id": {
"type": "string"
}
},
"required": [
"entity_code",
"debit_account",
"credit_account",
"amount_minor",
"currency",
"idempotency_key",
"source_document_id"
]
}
The real control is not the JSON schema alone. The receiving service must verify every field against authoritative ERP state.
Tool-scoping rules
- Give each specialized agent only the capabilities required for its workflow.
- Prefer task-specific functions such as
match_invoice,read_purchase_order, orcreate_journal_draftover generic mutation functions. - Make invalid states impossible to represent where practical.
- Keep authorization checks on the server side.
- Reject unknown, stale, or inactive identifiers before executing mutations.
- Attach idempotency keys to operations that may be retried.
- Return compact, structured results instead of raw HTTP responses or database dumps.
Important distinction
Tool restrictions are an AI control. They are not an authorization boundary.
The ERP service, gateway, or policy engine must remain the final authority.
The execution cycle: parse, retrieve, validate, act, verify
A dependable ERP agent should not jump directly from natural language to a financial mutation.
- Parse
- Retrieve
- Validate
- Authorize
- Actuate
- Verify
Any check fails: abort or escalate
1. Parse
Identify the immediate workflow objective.
For example:
- identify the invoice
- determine whether a purchase order exists
- calculate the matching variance
- prepare a posting candidate
Do not allow the model to invent missing accounting facts during parsing.
2. Retrieve
Fetch only the authoritative records required for the next decision.
Typical sources include:
- vendor master
- purchase order
- goods receipt
- invoice
- payment status
- accounting policy
- account master
3. Validate
Check every value against authoritative state.
At minimum, validate:
- entity and fiscal period
- account status
- currency
- tax configuration
- cost center
- monetary precision
- debit and credit totals
- document status
- approval state
4. Authorize
Determine whether the current actor and workflow are allowed to perform the requested operation.
Authorization should be evaluated outside the model.
[Agent Request]
|
v
[Policy Engine]
|
+--> Actor
+--> Role
+--> Entity
+--> Operation
+--> Amount
+--> Approval state
|
v
[ALLOW / DENY / REQUIRE APPROVAL]
5. Actuate
Only a validated and authorized transaction should reach the ERP mutation service.
Prefer a structured transaction object:
{
"entity_code": "EU02",
"source_document_id": "INV-2026-01842",
"debit_account": "610200",
"credit_account": "200100",
"amount_minor": 128450,
"currency": "EUR",
"idempotency_key": "INV-2026-01842:v1"
}
6. Verify
Do not assume that a successful HTTP response means the business operation succeeded.
Verify the resulting voucher, transaction ID, status, and relevant accounting totals.
If the ERP rejects the operation, return the structured error to the workflow controller and stop when the failure cannot be safely recovered.
Multi-agent specialization: separate reasoning from authority
Complex ERP workflows are usually easier to control when different responsibilities are separated.
[Inbound Invoice]
|
v
[Workflow Router]
No mutation tools
|
+---------------------------+
| |
v v
[Matching Agent] [Policy / Approval]
Read-only Deterministic
|
v
[Validated Transaction Object]
|
v
[Posting Service]
Deterministic mutation
|
v
[Voucher + Audit Event]
Responsibility boundaries
Router
Classifies the workflow and selects the appropriate execution path. It should not have write privileges.
Read-only retrieval or reconciliation agent
Compares invoices, purchase orders, receipts, and master data. Its outputs should be structured and independently verifiable.
Policy and approval layer
Applies thresholds, segregation-of-duties rules, approval requirements, and other deterministic controls.
Actuation service
Consumes a validated transaction object and performs the actual ERP mutation.
Keep handoffs small
Do not transfer complete conversational histories between agents.
Transfer only the state required for the next step.
{
"workflow": "accounts_payable_match",
"entity_code": "EU02",
"invoice_id": "INV-2026-01842",
"purchase_order_id": "PO-8492",
"match_status": "matched",
"variance_minor": 450,
"currency": "EUR",
"approval_required": false
}
This makes the workflow easier to test, replay, and audit.
Reliability controls that matter more than prompt wording
Prompt engineering is useful, but it should not carry the burden of financial correctness.
Idempotency
An agent may retry after a timeout or ambiguous tool response.
Without idempotency, the same invoice can be posted twice.
Request
|
v
[idempotency_key = invoice + workflow version]
|
+--> Seen before? ---- yes ---> Return existing result
|
no
|
v
Execute mutation
|
v
Persist result against key
Transaction boundaries
A multi-step workflow should not leave a partially applied financial change because the model failed halfway through.
Use explicit transaction boundaries in the ERP or service layer and design compensating actions where true atomicity is impossible.
Approval thresholds
Not every financial operation should be autonomous.
For example, an organization may require human approval based on:
- monetary amount
- vendor risk
- unusual tax treatment
- new bank details
- cross-entity transfers
- exceptional journal types
The thresholds must be configured by the organization rather than hard-coded into the model’s prompt.
Segregation of duties
The component that detects or proposes a transaction should not automatically receive unrestricted payment or approval authority.
Separate the steps:
- Detect
- Validate
- Approve
- Execute
instead of one agent that decides, approves and executes on its own.
Security and governance: treat external data as hostile input
Financial automation expands the attack surface because the model may process documents and messages originating outside the organization.
Supplier invoices, OCR output, emails, attachments, and retrieved text must be treated as untrusted data.
Required controls
Least privilege
Give service identities only the permissions required for the specific workflow.
Prompt-injection resistance
Do not allow instructions embedded in invoices, PDFs, or supplier notes to override system policy.
Server-side authorization
Never rely on the model to enforce access control.
Human approval
Require explicit approval where policy or risk thresholds demand it.
Immutable audit records
Capture the source document, relevant inputs, tool calls, policy decisions, resulting ERP transaction, and timestamps in a tamper-evident audit trail.
Sensitive-data minimization
Do not place payroll data, bank details, or unrelated customer information into model context merely because the agent technically can access it.
Auditability rule
The system should be able to answer three questions after every material action:
What did the agent see?
Why was the action allowed?
What exactly changed in the ERP?
Failure diagnosis: inspect the control boundary, not only the model
When an agent fails, the root cause is often not the language model itself.
Recursive tool loop
Symptom
The workflow repeatedly retries the same operation.
Typical cause
The service returns an error that is difficult to interpret or the controller has no explicit termination state.
Engineering response
Use bounded retries, structured error codes, and explicit terminal states.
Attempt 1
|
v
Structured error
|
v
Can retry safely?
|
+--+--+
| |
yes no
| |
v v
Retry Abort / Escalate
A retry limit should be derived from the operation and failure mode. A universal number such as “three attempts” is only a heuristic.
Parameter hallucination
Symptom
The model produces a plausible but nonexistent account, vendor, tax code, or transaction identifier.
Typical cause
The workflow allows free-form construction before authoritative lookup and validation.
Engineering response
Resolve identifiers against the ERP master data before mutation.
Free text
|
v
Candidate identifier
|
v
Authoritative lookup
|
+--> Not found ----> Stop
|
+--> Inactive -----> Stop
|
+--> Valid ---------> Continue
Context rot
Symptom
The agent loses the original business objective after many tool calls.
Typical cause
Large raw responses accumulate in the context.
Engineering response
Store state outside the conversation and pass forward only the fields required for the next step.
Step-by-step implementation plan
1. Define workflow boundaries
Choose one concrete ERP workflow.
Examples:
- three-way invoice matching
- vendor master validation
- journal draft preparation
- payment exception classification
Do not begin with “automate accounting” as a single agent scope.
2. Define authoritative systems
For every field the agent may use, document the authoritative source.
| Field | Source of truth |
|---|---|
| Vendor ID | Vendor master |
| Account code | Chart of accounts |
| Tax code | Tax configuration |
| PO status | Purchasing system |
| Approval state | Workflow engine |
3. Define the transaction contract
Create a versioned schema for the structured object that moves between reasoning components and deterministic services.
Treat this object as an API contract, not as free-form model output.
4. Build the read-only path first
Test retrieval, matching, validation, and explanations without allowing financial mutations.
Create synthetic edge cases for:
- inactive vendors
- closed fiscal periods
- currency mismatches
- duplicate invoices
- missing purchase orders
- tax mismatches
- partial receipts
- stale master data
5. Add policy enforcement
Introduce RBAC, approval rules, segregation of duties, and monetary thresholds outside the model.
6. Enable controlled mutation
Expose only the smallest deterministic mutation service required by the workflow.
Add:
- idempotency
- transaction handling
- optimistic concurrency where appropriate
- structured errors
- audit events
7. Evaluate the complete system
Measure more than model accuracy.
Track:
- retrieval precision
- invalid identifier rate
- unauthorized action rate
- duplicate mutation rate
- validation rejection rate
- escalation rate
- mean recovery time
- audit completeness
- end-to-end task success
Quick reference checklist
Architecture
- Narrow workflow scope
- Scoped retrieval with authorization metadata
- Small, typed tool surface
- Deterministic validation before mutation
- Explicit state transitions
ERP correctness
- Authoritative identifier lookup
- Account and tax validation
- Fiscal-period checks
- Balance validation
- Idempotent mutations
- Transaction verification
Security
- Server-side RBAC
- Segregation of duties
- Prompt-injection defenses
- Sensitive-data minimization
- Approval thresholds
- Tamper-evident audit logs
Agent operations
- Bounded retries
- Structured error handling
- Externalized workflow state
- Compact agent handoffs
- Full observability
The short version
The strongest pattern for AI in ERP automation isn’t a more autonomous generalist agent. It’s a controlled system: the model handles language and bounded reasoning, and deterministic services keep authority over business rules, permissions, transaction integrity and stored state. That split is what makes the workflow testable and auditable.
Who does what
The model proposes. The system validates. The ERP stays the source of truth.