Let the AI Match the Invoice, Not Release the Payment
A safe agentic workflow gives the model one bounded judgment call. Code checks the invoice, verifies the vendor, enforces policy and commits the approved record.
November 1, 2026 · 8 min read

An invoice arrives from Northline Studio, but the vendor master lists Northline Design LLC. The invoice has no purchase order number, the description resembles work from two open projects, and the sender uses a domain previously seen in correspondence but not stored as an approved vendor identifier.
This is where an agent can help. It can compare the invoice description with the two projects, inspect permitted supporting records and propose the most plausible match. It should not decide that the sender is authorized, accept new bank details or create a payable record by itself.
That division is the architecture. The model handles a bounded ambiguity. An orchestrator, meaning conventional software that controls the order of workflow steps, handles everything with a testable answer.
Draw the boundary around one decision
Teams often start by describing the whole job as “process this invoice.” That instruction hides several different operations with different failure costs. Reading a loose description requires interpretation. Checking whether a vendor ID exists does not.
Writing an approved liability into an accounting system has lasting consequences and should not depend on generated text.
Rewrite the job as a sequence. The Northline invoice first receives an internal run ID and a cryptographic hash, which is a fingerprint used to detect duplicate files. Existing document software extracts the visible fields into a fixed schema. Code then checks required fields, formats, duplicate status and arithmetic before retrieving possible vendor and project records.
Only then does the model run. It receives the invoice description and a small set of candidate records chosen by code, rather than unrestricted access to the vendor database. Its output must name one candidate or abstain, cite the supplied evidence and conform to a machine-readable schema. It cannot add a vendor, change payment instructions or call the accounting system.
After the model returns, code validates the output against the candidate set. Separate identity and policy checks determine whether the workflow may continue. An authorized service account performs the final write only after those checks pass, while ambiguous or inconsistent cases move to a review queue.
The agentic portion is small. That is useful, not embarrassing.
Put deterministic gates before the model
A deterministic step follows explicit rules and should return the same result for the same input. Before spending time and model tokens on Northline, ordinary code can reject work the model should never see: an unsupported file type, a missing invoice total, a duplicate document hash or line items that do not add up to the stated amount.
These gates reduce cost because malformed work stops early. They also improve diagnosis. A log entry that says `line_total_mismatch` gives an operator a concrete fault, whereas a model’s explanation may vary between runs even when the underlying problem is unchanged.
Schema validation matters here. A schema defines the allowed fields, types and values in a data object. If the extracted currency field contains free-form prose, or the invoice date cannot be represented in the accepted format, the workflow should fail validation rather than invite the model to repair the record by inference.
Do not quietly turn every failed gate into an agent task. A model can guess that a missing currency is probably dollars from surrounding context, but that flexibility converts absent source data into apparently valid accounting data. The appropriate fallback is a corrected document or human confirmation recorded as a separate event.
Retrieval should also remain bounded. Code can query open projects associated with the already identified vendor account and pass only those candidates to the model. If the query returns no candidates or too many to review safely, route the case elsewhere instead of expanding the model’s search permissions during the run.
Treat identity as a code and policy problem
The Northline sender’s familiar domain is evidence, not identity. Email display names can be copied, domains can be compromised, and a prior conversation does not authorize a bank-account change.
Identity checks should compare stable identifiers held by systems that own them. Depending on the organization, those may include an approved vendor ID, an authenticated supplier-portal account, stored payment instructions and a verified relationship between the submitting account and the vendor record. Code performs the comparisons, and policy decides which combinations are sufficient.
A mismatch must have a named result. If the invoice contains payment details different from the vendor master, the workflow can mark `payment_details_changed`, stop before matching or writing, and require verification through the organization’s established channel. The model may extract the differing account text for display, but it should neither judge the change legitimate nor update the trusted record.
This separation blocks a common category error. Language models evaluate resemblance and context; identity systems establish which principal, meaning a user or service acting under a recognized account, is allowed to perform an action. Similarity between “Northline Studio” and “Northline Design LLC” may support project matching, but it cannot replace authentication or authorization.
Give the model a contract, not a mission
Once the invoice passes the initial gates, the model needs a narrow contract. For the Northline case, its job is to select from the candidate project IDs supplied by the orchestrator or return `abstain`. The response can include the selected ID, references to supporting phrases and a reason code from an allowed set.
The schema prevents extra prose from being mistaken for an instruction, but structured output does not make the judgment true. Code still checks that the chosen project ID appeared in the supplied candidates, that cited fields exist and that the model did not return mutually incompatible values.
Confidence scores require caution. A model-generated number may help sort a review queue, but it is not automatically a calibrated probability. Release rules should rely on measured workflow performance and explicit evidence conditions, not a prompt telling the model to proceed when it feels highly confident.
The contract also needs a stop condition. If both Northline projects contain similar descriptions and neither has a matching date range or reference, abstention is the correct output. A forced choice may improve the apparent completion rate while moving the real work downstream, where someone must unwind a bad accounting entry.
Agent frameworks can support this pattern through tool permissions and function calling, where the model requests a predefined software function using structured arguments. The useful control is not the framework label. It is that the model can call `get_candidate_projects` but has no callable `create_payable` or `update_bank_account` function.
Make the final write boring
After a proposed match returns, conventional code rechecks the state that matters. The invoice must still be unprocessed, the vendor must remain active, the selected project must still be open, required approvals must exist, and no identity flag may be unresolved. This second validation matters because records can change while the model is working or while a case waits for review.
The write should use an idempotency key, a unique identifier that prevents the same operation from being committed twice. If a network timeout occurs after the accounting system accepts the Northline payable but before the orchestrator receives confirmation, a retry with the same key should retrieve or confirm the existing result rather than create another one.
Keep the write inside a transaction where the destination supports it. A transaction groups related database changes so they either commit together or fail together. The model’s rationale belongs in the audit record, but it should not become executable input at this stage.
This design adds database checks and orchestration steps, though those operations are usually cheaper and faster than another model call. It may also send more borderline invoices to people, lowering automation coverage in exchange for fewer unsupported writes. That is the central tradeoff: abstention preserves uncertainty instead of concealing it.
Use a repeatable test for every step
For each workflow action, write down its input, acceptable outputs, authority and failure consequence. Then try to express correctness as a predicate, a rule that evaluates to true or false. “The project ID must be one of the retrieved candidates” is a predicate. “Choose the project whose description best matches this irregular invoice” requires judgment.
Keep the step in code when an exact rule exists, when it establishes identity or permission, when it changes a system of record, or when a retry could duplicate an irreversible action. Use a model when the evidence is linguistic or incomplete, several interpretations can be reasonable, and abstention is available without corrupting state.
Some tasks contain both kinds of work. Split them. The model can propose that Northline Design LLC is the likely vendor entity; code must confirm that the proposed vendor ID exists and that the authenticated submitter is linked to it. The model can suggest an expense category; policy code must reject categories unavailable to that department.
Test the whole path with saved cases, including duplicates, changed bank details, stale approvals, malformed model output and timeouts after a successful write. Record the prompt and model configuration, candidate data, validation results, tool calls, approvals and final transaction identifier. Avoid storing unnecessary sensitive text merely because the model saw it.
The most revealing metric is not how often the agent finishes. Track where it abstains, where reviewers overturn its proposal, which deterministic gate stops the run and whether any final write lacks the approvals expected by policy. For the Northline invoice, the audit trail should show one bounded recommendation followed by independent checks, not a narrative claiming the agent processed an invoice end to end.
Questions people ask
Can the model still use tools in this design?
Yes, but expose only read operations and bounded functions needed for the ambiguous decision. The invoice matcher might retrieve approved candidate projects by vendor ID, while functions that create vendors, alter payment details or post liabilities remain unavailable to the model and callable only by the orchestrator after validation.
Should a high-confidence model result skip human approval?
Only if a separately evaluated policy permits that case and deterministic checks still pass. A confidence value written by the model is not enough. Teams need evidence from representative workflow cases, explicit thresholds owned outside the prompt and a fallback for inputs that differ from the evaluated population.
What happens when the model returns invalid structured output?
Reject the response before any state change. The orchestrator can retry under a limited policy if malformed output is the only fault, but repeated failure should enter a review queue with the original source, candidate records and validation error preserved for diagnosis.
Does this pattern still count as an AI agent?
It can, especially when the model selects among permitted tools or completes a bounded multi-step investigation. The label matters less than authority: for the Northline invoice, the model interprets ambiguous evidence, while authenticated code decides whether the recommendation may become an accounting record.
One story a day
The story of the day, in your inbox
One real story about AI each morning — no hype, no alarm, just company for the road.



