AI Hallucination Guardrails for ERP Agents: How to Make an Agent Cite the Record It Read in Odoo 20 and MYOB Acumatica
AI hallucination guardrails for ERP agents: cite the record, say so when it is missing, recompute the numbers, hold the draft for a person. Odoo 20 and MYOB.
By Bill Alvarez, Practice Manager, Auboros ·
AI hallucination guardrails for ERP agents are rules that stop a plausible but false statement reaching a record or a customer: the agent states only what it can cite to a record it read, says so when it finds nothing, and a person approves the draft. As at 3 November 2026, Odoo 20 builds source citations into its agents; MYOB Acumatica 2026.1 leaves citing to your prompt.
At a glance
- Who it is for: CFOs, finance managers and ops managers of Australian businesses on Odoo or MYOB Acumatica who are about to let an agent draft anything a customer, supplier or auditor will read: dunning emails, order confirmations, service replies, variance commentary.
- Problem it solves: a language model writes fluent, confident text whether or not the fact behind it exists, and an ERP is full of numbers, dates and names that look fine until someone checks them against the ledger.
- Platforms: Odoo 20 Enterprise (AI agents with sources, Restrict to Sources, inline citations, Helpdesk helper, MCP server, all on IAP credits); MYOB Acumatica 2026.1 (AI Automation prompts with data masking and the AI Studio History log, AI Assistant); any bring-your-own-model build over an ERP API.
- The five guardrails: read before you write (the agent’s facts come from records it fetched, not from the model’s memory); cite the record on every factual claim; abstain instead of guessing when the record is missing; recompute every number from the rows the agent cited before a person sees it; and hold every draft in a field a person edits and approves.
- Approval gate: one person per draft, every time. A draft whose citations fail the recompute step is held and never shown as ready.
- Audit trail: the draft, the cited record references and the recompute result sit on the ERP record with the approval, which is the “data and system used to generate the AI output” the OAIC asks you to be able to point to.
- Typical cost: a scoped pilot from A$5,000 ex GST per our AI agents for ERP in Australia hub, as at 3 November 2026; adding the citation and recompute checks to an existing drafts-first agent is usually days, not weeks.
- Typical timeline: one agent, one document type, in a sandbox first; two to four weeks to a draft that cites and recomputes, then a month of measuring how often the checks hold a draft back before you trust the pattern.
- Last verified: 3 November 2026 against the Odoo 20 AI agents documentation, the Odoo 20 Enterprise source (ai and ai_helpdesk modules), MYOB’s data masking documentation, the OAIC’s guidance on commercially available AI products and the National AI Centre’s Guidance for AI Adoption.
A credit controller at a Queensland building products distributor opens a drafted reminder email on a Tuesday morning. It reads well. It names the overdue invoice, the amount, the due date, and then adds a line she doesn’t remember: “as per the payment plan agreed on 20 October”. There was no payment plan. The customer had asked about one in a phone call that was never logged, the agent had seen the word “plan” in a chatter note about the customer’s building schedule, and the model did what models do with a gap. It filled it.
That is a hallucination inside an ERP, and it is more dangerous than the ones that make the news, because it is small, specific and surrounded by true facts. This post is about the guardrails that catch it: what they are, how Odoo 20 and MYOB Acumatica help, what you still have to build, and what Australian regulators already expect.
What is an AI hallucination, and why is it worse inside an ERP?
OpenAI’s own research note on why language models hallucinate (5 September 2025) defines hallucinations as “plausible but false statements generated by language models”, and says standard training and evaluation “reward guessing over acknowledging uncertainty”. That is the whole problem in two sentences. A model is scored on sounding right, so when the record is missing it produces the most likely-sounding record instead of stopping.
Inside an ERP that failure has three particular shapes. The invented fact, like the payment plan above, where the model adds a detail no record holds. The near-miss number, where $4,812.50 becomes $4,182.50 and nobody notices because both look like an invoice. And the confident summary, where five chatter messages become “the customer confirmed delivery” when one of them actually said the opposite. The OAIC’s guidance on commercially available AI products puts it plainly: AI outputs “can often appear credible even when they produce errors or false information”.
The usual advice is “use retrieval” or “ground the model in your data”. That helps, and both platforms do it. It is not enough on its own, because a model that has read the right invoice can still misquote it. The guardrails below are about making every claim traceable and every number checkable, so the person approving the draft is checking citations, not re-doing the work.
The five guardrails, in the order we build them
- Read before you write. The agent’s facts come from records it fetched during the run, through read-only tools, never from what the model remembers about your business from an earlier conversation or from training. Odoo 20’s MCP server and MYOB Acumatica’s REST API under a limited role are the read path; the Model Context Protocol draws the same line, with tools as “functions that your LLM can actively call” and resources as “passive data sources that provide read-only access to information”.
- Cite the record on every factual claim. Every amount, date, name and status in the draft carries the reference of the record it came from: the invoice number, the sales order, the ticket, the Knowledge article. A claim with no citation is a claim the checker rejects.
- Abstain instead of guessing. When the record is not there, the agent says so and asks, in those words. Its instructions have to say this explicitly, because the model’s default is to guess.
- Recompute before a person sees it. A small piece of ordinary code, not the model, reopens each cited record, re-adds the totals and compares them with the numbers in the draft. If the outstanding balance in the email does not equal the sum of the cited invoice rows less the cited receipts, the draft is held.
- Hold every draft for a person. The draft lands in a field or a stage a person owns, with the citations and the recompute result beside it, and nothing is sent, posted or changed until they approve. This is the approval gate we build into every agent, and the recompute step is what makes the approval fast instead of a re-audit.
Four of the five are plumbing you can build on any platform with an API. The second one is where the two platforms differ most, so that is where the next two sections go.
How does Odoo 20 make an agent cite its sources?
Odoo 20 builds citation into the agent itself, and because every Odoo Enterprise subscriber can read the source, you can check how. In the ai module, an agent that has sources configured is given a knowledge protocol that instructs the model that every factual claim taken from a source “MUST be immediately followed by an inline citation” in the form [SOURCE: id], citing all sources when a claim draws on several, and adding no citations if no source chunks were used. Odoo then parses those tags, replaces them with numbered, clickable citations, and lists the source names and links under the answer. It only links sources the current user has access to, so a citation never becomes a way to read a document you could not open yourself.
Turn on Restrict to Sources and the second guardrail arrives with the third. The Odoo 20 agents documentation says the agent “can only utilize information from the uploaded and active sources”. The source adds the abstention rule: for anything but a greeting, the agent answers only from the provided sources, conversation history, loaded skills, tool results and what the user typed; if that is not enough it asks for the missing information or says the provided sources do not contain the answer; and if no sources were provided at all it replies, in a fixed sentence, that no source information has been provided for it to reference. That last line is the one to watch for in a sandbox. If you see it in production, somebody deleted a source.
The Helpdesk helper that ships with Odoo 20 applies the same rules to tickets. Its default prompt tells the agent that tickets are its source of truth, to answer from the tickets, chatter messages and records it retrieves and “never from assumptions about the product, the procedures or the policies”, to always cite the tickets it used by reference and subject so the operator can open them, and, when it finds no solution, to say so plainly and ask before offering anything from its own knowledge, labelling that suggestion as not backed by past tickets. The service triage agent post covers what that looks like on a support desk. The live chat agent has the same rule for website visitors: when it lacks information it “does not guess or fabricate a response” and moves the conversation toward a person.
Now the limits, because they decide what you still build. The inline citation protocol covers knowledge sources: the PDFs, web links, Documents files and Knowledge articles you attach to the agent. The same protocol tells the model to cite “only the claims taken from RAG context” when an answer mixes sources with Odoo data and tool results. So an invoice amount the agent fetched through a tool is not cited by the platform; that is your instruction to add (“quote the invoice number and the field you read for every amount”), and your recompute step to check. The response style called Slow & Rigorous “cites reasoning clearly”, which is reasoning, not records. And every one of these features draws IAP credits, so a recompute check that runs in plain Python costs nothing where a second model call would.
What does MYOB Acumatica give you, and what do you write yourself?
MYOB Acumatica takes the other approach: the prompt is yours. In AI Automation (the feature MYOB announced as AI Studio and renamed in version 2026.1.1), an administrator writes a prompt on a form and inserts the fields the model may see. That is the first guardrail by construction: the model receives the fields you inserted from the record on screen and the related records you looped over, not the whole database and not its memory. MYOB’s data masking adds a second property that matters for accuracy as much as privacy: masked values are swapped back into the response from the real record, so an account number or a price inside a masked field cannot be mistyped by the model on the way through. The documented exception is a value buried inside a larger text field such as an email reply, which the model sees as written.
What MYOB’s pages do not say, as at 3 November 2026, is that a prompt’s output cites the record it came from, or that the AI Assistant, which answers plain-language questions about revenue, customers, invoices and inventory from live data, references the documents behind an answer. So in MYOB Acumatica the second guardrail is a sentence in your prompt: for every amount, date or status, name the document type and Reference Nbr it came from, and if the inserted fields do not contain the fact, write “not in the record” instead. The Trace page shows what was sent, the Response tab shows what came back with the real values restored, and the AI Studio History form (ML400000) adds a record for each prompt run, so the run record your agent register points to has something to join to. The built-in Refine Reply and Closure Notes prompts write into fields a person edits, which is the fifth guardrail already in place; our prompt hand-off post walks through it.
Globally, Acumatica 2026 R2, generally available from 1 October 2026, adds an MCP connection so outside AI tools can read the ERP under the user’s existing role-based permissions and field-level masking. Global features typically reach MYOB Acumatica 6 to 9 months later. When it lands in ANZ it changes the first guardrail (the read path) and nothing about the other four.
| Guardrail | Odoo 20 Enterprise | MYOB Acumatica 2026.1 | What you add on either |
|---|---|---|---|
| Read before you write | MCP server read tools, agent sources, tool results | Inserted fields and looped records in the prompt; REST API under a limited role | A dedicated read-only user per agent |
| Cite the record | Inline [SOURCE] citations rendered as numbered links for knowledge sources; Helpdesk helper cites tickets | Not documented; the prompt instructs it | Citation rule for tool-fetched records in the system prompt |
| Abstain instead of guessing | Restrict to Sources: “the provided sources do not contain the answer”; live chat does not fabricate | Not documented; the prompt instructs it | A test set of questions with no answer in the data |
| Recompute before showing | Not shipped | Not shipped | Plain code that reopens cited records and re-adds the totals |
| Hold for a person | Drafts in fields, stages and automation chats; interactive agent responses | Prompt output in editable fields; Refine Reply and Closure Notes | The approval stage and who owns it |
The table is the honest version of the vendor slide. Both platforms give you the first and the last. Odoo 20 gives you most of the second and third for documents. Nobody gives you the fourth, and the fourth is the one that catches the near-miss number.
A worked example: the overdue reminder that cited its way to approval
Back to the credit controller. Here is the same reminder with the guardrails in place, on a MYOB Acumatica site with a bring-your-own-model agent reading through the REST API; the Odoo 20 version differs only in where the reads come from.
- The agent reads. For the customer it fetches open AR documents, receipts in the last 60 days, and the last ten activities on the account. It is running as a user who can read AR and CRM and cannot release, email or edit anything.
- It drafts with citations. “Invoice INV004231 for $4,812.50 was due on 14 October 2026 [INV004231, Due Date]. A payment of $2,000.00 was received on 28 October [PMT002877]. The outstanding balance is $2,812.50.” Every number carries the document it came from. There is no line about a payment plan, because the activities contain no record of one, and the instruction says to write “not in the record” instead of inferring.
- The checker recomputes. A short script reopens INV004231 and PMT002877, reads the amounts and dates from the fields, sums them and compares: $4,812.50 less $2,000.00 is $2,812.50, due date matches, receipt date matches. The draft is marked “citations verified” and moves to the controller’s review stage. Had the model written $2,182.50, the draft would have been held with the mismatch shown.
- The person decides. The controller reads the draft in thirty seconds, because the only thing left to judge is tone and whether to call instead of email. She remembers the phone conversation, logs the activity the agent could not find, adds one sentence about the payment plan herself, and approves. The email goes out under her name and the activity, the draft and the verification result stay on the customer record.
The agent did the reading and the writing. The checker did the arithmetic. The person did the one thing that needed a person, and the thing the agent got wrong on Tuesday could not have happened, because there was no record to cite.
“A citation is there so the person approving the draft can click once, see the invoice and stop reading. If they still have to open the ledger to check a number, the agent hasn’t saved anyone anything.”
Bill Alvarez, Practice Manager, Auboros
What do Australian regulators expect you to be able to show?
Nothing in Australian law names hallucination, and the National AI Plan of December 2025 kept guardrails voluntary. Three sets of guidance still describe exactly this pattern.
The OAIC’s guidance on commercially available AI products (published 21 October 2024, updated 17 January 2025) says that under Australian Privacy Principle 10 organisations must take reasonable steps to ensure the personal information they collect, use and disclose is accurate, that a human should be responsible for verifying the accuracy of any personal information obtained through AI, and that your records should clearly indicate where information is the product of an AI output “and therefore a probabilistic assessment rather than fact”, together with the data and system used to generate it. A draft that carries its citations and its recompute result is that record. A draft that does not is a guess with a logo on it.
The National AI Centre’s Guidance for AI Adoption (21 October 2025) sets out six essential practices, and two of them are this post. Test and monitor, because “AI systems can change their behaviour over time or act in ways that are less predictable than conventional software”; and maintain human control, because an organisation needs to “make sure a human appropriately oversees any AI systems in use”. The guidance lists inaccurate information among the harms to plan for. Count how often the recompute step holds a draft, review that count monthly, and you have the monitoring it asks for.
The ACCC’s page on false or misleading claims says the rule applies to any communication by a business, listing staff statements and websites alongside advertising. An overdue amount in a reminder email is a claim. In Moffatt v Air Canada (February 2024) a Canadian tribunal rejected the airline’s argument that its chatbot was a separate legal entity responsible for its own words. Australian courts are not bound by it; the ACCC’s position does not need them to be.
Where anti-hallucination guardrails go wrong
- Citation theatre. The draft cites INV004231 and the invoice says something else. A citation proves the agent looked, not that it read correctly. Fix: the recompute step opens the cited record and compares values; a citation that does not match is a failed check, not a pass.
- Restrict to Sources on the wrong copy. Someone duplicates the agent for a new team and the checkbox does not come with the context they expected. Fix: the agent register records the setting per agent and the monthly review re-checks it.
- Stale sources. The returns policy in the sources is the 2023 one, so the agent cites it correctly and is still wrong. Fix: date every source, make a named person own each one, and reprocess sources in Odoo 20 when they change.
- Recompute that trusts the draft. The checker reads the numbers from the email instead of from the record and compares them with themselves. Fix: the checker takes only record references from the draft and fetches every value itself.
- Abstention that nobody sees. The agent correctly writes “not in the record” and the template hides it. Fix: an abstention is an exception in the approval queue, with the question the agent could not answer shown to the person.
- Numbers inside free text. In MYOB Acumatica a masked field is restored exactly, but an amount typed inside an email body goes through the model as text. Fix: treat any number in free text as unverified until the recompute step finds it in a record.
Goes well with
- Sandbox-first AI agents: how to test the abstention and recompute checks on a copy of your database before an agent drafts anything real.
- The approval gate is in the code: how to make an Odoo AI server action wait for a person instead of writing.
- AI agent governance for Australian businesses: the register, permission and review controls the guardrails sit inside.
An agent that cites the invoice, and a person who still signs
We build drafts-first agents over Odoo 20 and MYOB Acumatica from Brisbane, with citation and recompute checks in front of every approval, as part of our AI agents for ERP in Australia practice for businesses across Queensland and beyond.
If an agent is already drafting emails or commentary from your ERP and nobody can say which record each number came from, book a free 1-hour scoping call. We’ll take one week of its drafts, trace every claim to a record, and show you what a checker would have held back.
FAQ
Frequently asked questions
What is an AI hallucination guardrail for an ERP agent?
It is a rule that stops a plausible but false statement from reaching a record or a customer. The five we build are: the agent reads the record before it writes, cites the record on every factual claim, says "not in the record" instead of guessing, has its numbers recomputed from the cited records by ordinary code, and hands every draft to a person who approves it. The person checks citations, not the whole job.
Does Odoo 20 make AI agents cite their sources?
Yes, for knowledge sources. The Odoo 20 Enterprise source instructs an agent with sources to follow every factual claim from a source with an inline citation, which Odoo renders as numbered, clickable links to sources the user is allowed to see. With Restrict to Sources on, the agent must say the sources do not contain the answer rather than guess. Facts fetched through tools, such as an invoice amount, are not cited by the platform, so that rule goes in your own instructions.
Does MYOB Acumatica AI cite the records it uses?
Not as a documented feature as at November 2026. In AI Automation the prompt is yours, so you instruct it to name the document type and Reference Nbr behind every amount, date or status and to write "not in the record" when the inserted fields do not hold the fact. Data masking restores masked values from the real record, the Trace page shows what was sent, and the AI Studio History form (ML400000) logs each run.
How do you stop an AI agent making up numbers from ERP data?
Do not rely on the model to check itself. Require a record reference on every number, then have a short piece of ordinary code reopen each cited record, re-add the totals and compare them with the draft before a person sees it. A mismatch holds the draft. This catches the near-miss number that a citation alone cannot, because a citation proves the agent looked, not that it copied correctly.
Is a business liable if its AI agent gives a customer wrong information in Australia?
The ACCC says the rule against false or misleading claims applies to any communication by a business, including staff statements and websites, and a Canadian tribunal in Moffatt v Air Canada (2024) rejected the argument that a chatbot is a separate legal entity. Australian courts are not bound by that case, but the ACCC's position does not depend on it. The OAIC also expects a human to verify personal information obtained through AI. Drafts-first with a person approving is the cheapest way to comply.