Most Acumatica implementations I've worked on in East and Southern Africa end up multilingual somewhere even when the tenant is nominally English-only: an AR statement that needs Swahili, a support ticket in French from a DRC branch, a supplier note in Portuguese out of Maputo. LLMs are useful here, but only if you're precise about which layer you're pointing them at — UI chrome, structured business documents, and free-text customer conversations behave very differently under machine translation.
LLM translation vs. dedicated MT engines
It's worth being honest about what an LLM buys you over a dedicated machine translation engine like Google Cloud Translation or DeepL. For short, low-context strings — button labels, field captions, error messages — a dedicated MT engine is cheaper, faster, and just as accurate, because there's no ambiguity to resolve. Where an LLM earns its cost is context-dependent translation: a support ticket that mixes English technical terms with Swahili sentence structure (common in Nairobi office correspondence), or a paragraph where the correct translation of a word depends on business context a phrase-based engine can't see ("post" meaning ledger posting, not a mail delivery).
The failure mode to watch for is the opposite one: using an LLM for high-volume, low-context UI strings because it's the tool you already have wired up. It costs more per string, and paradoxically it's less consistent than a glossary-backed MT engine, because the model is free to choose a different phrasing for the same source string each time it sees it in isolation.
Glossaries and terminology locking
The single biggest quality problem with LLM translation in an ERP context is that the model doesn't know which words are product terminology and which are ordinary language. Left alone, an LLM will happily "translate" Sales Order, a screen name, or a custom field label like Retention % into naturally-sounding but wrong target-language text — and it will do it inconsistently, choosing a different rendering each time. Business users then can't map the translated UI back to what's in the documentation or what a colleague is describing over the phone.
The fix is a terminology glossary passed into every translation call as a hard constraint, not a suggestion. I keep a CSV of locked terms — screen names, module names, custom field captions, statutory terms (VAT, PIN, eTIMS for Kenya, EBM for Rwanda) — and instruct the model explicitly not to translate anything on that list, only to translate the surrounding sentence.
Product names, screen IDs (AR301000), and statutory abbreviations should never be left to the model's judgment. Lock them in the prompt and verify post-hoc with a regex check that they appear unchanged in the output.
Placeholders, variables, and markup that must survive intact
Business strings are rarely plain text. A dunning letter template has {CustomerName}, {InvoiceNumber}, and {DueDate} tokens; a notification email has inline HTML for a "View Invoice" button; a UI resource file has %1-style positional placeholders. An LLM asked to translate the surrounding prose will sometimes "help" by translating the placeholder text itself, reordering it in a way that breaks positional substitution, or mangling the HTML tag attributes. This is the most common cause of a translated notification going out with a broken link or a literal {0} visible to the customer.
The reliable pattern: extract placeholders and tags before sending text to the model, replace them with neutral numbered tokens, translate, then substitute the originals back in. A few extra lines of pre/post-processing per batch eliminate an entire category of production incidents.
You are translating Acumatica business UI text from English to {target_language}.
Rules:
1. Do NOT translate any term in the glossary below. Copy it exactly as given.
2. Do NOT alter tokens matching __VAR_n__ or __TAG_n__. They are placeholders
and must appear in the output in a position consistent with the source.
3. Preserve tone: formal register appropriate for financial/business
correspondence, not casual speech.
4. If a source term has no natural equivalent, prefer a widely understood
loanword over a literal translation (e.g. keep "invoice" recognisable
rather than inventing an obscure calque).
5. Output only the translated string. No commentary, no alternate options.
Glossary (do not translate):
Sales Order, Purchase Order, VAT, PIN, eTIMS, Acumatica, {{additional terms}}
Source:
{source_text}
Context window: short UI strings vs. long documents
Short strings and long documents need opposite handling. A resource file might have 3,000 short UI labels — sending each in its own API call is slow and expensive, and it also loses cross-string consistency, because the model has no memory of how it rendered a similar label two calls ago. Batching 50-100 strings per call, numbered, with the glossary included once per batch, gets consistency back and cuts cost roughly in proportion to the batch size. The trade-off is that a bad batch (one malformed source string) can affect the whole batch's output, so validate the returned count matches the input count before accepting a batch.
Long documents — a full contract, a policy document, a multi-page AR statement — are the opposite problem: too much context in one call risks the model losing track of terminology consistency between page one and page ten, or silently summarising instead of translating when it runs low on output budget. Chunk by logical section, carry the glossary and a short "translated so far" terminology recap into each chunk, and stitch the output back together rather than trusting one call to hold the whole document faithfully.
Human review workflows for customer-facing translations
Internal UI strings can ship on a spot-check basis — a native speaker skims a sample after each batch, and errors get corrected in the next pass. Customer-facing text is a different risk category entirely: a mistranslated dunning letter, a wrong currency reference, or an accidentally rude register error in a collections email reaches someone outside the company and reflects directly on the business.
For anything customer-facing I put a human-in-the-loop gate before send: the LLM produces a draft, a bilingual staff member reviews and approves or edits, and only approved translations get cached and reused. That cache is the important part — once a template's translation is human-approved, you don't re-translate it every time, you substitute the same approved copy with fresh placeholder values. This turns "review every translation" into "review every template once," which is the only version of the workflow that scales past a handful of documents.
Machine translation error rates are low enough to feel safe and high enough to occasionally embarrass you in front of a customer. Gate anything that leaves the building — statements, dunning letters, support replies — behind at least one human approval until the template is proven.
| Content type | Best approach | Review needed |
|---|---|---|
| UI labels, field captions | Dedicated MT engine + glossary | Spot-check per batch |
| Notification/email templates | LLM + placeholder extraction | Full review once, then cache |
| Support ticket replies | LLM, short context, glossary | Human approval before send |
| Long-form documents (contracts, statements) | LLM, chunked with recap | Full bilingual review |
Wrapping up
LLM translation earns its place in an ERP workflow when it's doing what dedicated MT engines can't — resolving business context, handling mixed-language support text, adapting register — not when it's replacing a glossary-backed engine for high-volume UI strings out of convenience. Lock your terminology, protect your placeholders, batch appropriately for the content length, and keep a human in the loop for anything a customer in Nairobi, Kampala, or Maputo will actually read. Get those four things right and the multilingual layer stops being a source of embarrassing tickets.
Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.