Sales quoting in Acumatica is one of the better-scoped AI-agent use cases in the whole ERP-plus-LLM space, because the inputs (a customer's request, in an email or a call transcript) and the outputs (a structured SOQuote (SO304000) record with line items and pricing) are both well-defined. The agent's job is bridging unstructured intent to a structured record, which is exactly what LLMs are good at — as long as pricing stays out of the model's hands.
Parse intent, price with the system
Let the LLM extract structured intent from an unstructured request — which items, what quantities, what special terms were mentioned, who the customer is — and hand that structured extraction to Acumatica's own pricing engine (price classes, price lists, volume discounts already configured in the system) to compute the actual quoted price. Never let the model itself state a price; if it hallucinates a discount percentage or misreads a unit price, that error goes straight onto a document a customer sees, and a wrong quote is a worse customer-facing failure than an internal report being wrong.
Treat quote generation with the same rigor as invoice generation, not like a chatbot response. Every number on the quote should trace back to a query against Acumatica's pricing tables, never to LLM-generated text, even when the LLM is very confident.
Handling ambiguous requests
Real customer requests are messy — "the usual setup but for the Nairobi office, add two more licenses" requires resolving "the usual setup" against quote history for that customer. This is where the agent earns its value: querying prior quotes and orders for the customer, identifying the most likely referenced configuration, and presenting it back for confirmation rather than guessing silently. An agent that asks "did you mean the configuration from quote Q-004821 from March?" before generating a document is far safer than one that silently interprets ambiguity and ships a wrong quote.
def generate_quote_draft(customer_request_text, customer_id):
extracted = llm.extract_structured(
text=customer_request_text,
schema=QuoteIntentSchema, # items, quantities, references, special terms
)
if extracted.has_ambiguous_reference:
candidates = find_similar_prior_quotes(customer_id, extracted.reference_text)
return {"status": "needs_confirmation", "candidates": candidates}
# pricing computed entirely by Acumatica's pricing engine, not the LLM
priced_lines = [price_line_item(customer_id, item) for item in extracted.line_items]
return create_draft_quote(customer_id, priced_lines, status="pending_review")
Always land as a draft, never auto-send
Every agent-generated quote should land in Acumatica as a draft pending sales rep review, not go out to the customer automatically. This isn't excessive caution — it's the same principle as any agent action with external, hard-to-reverse consequences: a sales rep catches the case where the extraction was subtly wrong in about a minute, versus the much more expensive cleanup of a wrong quote already in the customer's inbox.
Close the loop with outcomes
Log every agent-generated quote against whether the rep edited it before sending, and what specifically they changed. A pattern of the same field being corrected repeatedly — say, the agent consistently misreading which price class a specific customer falls under — is a concrete, fixable extraction bug, not a mysterious "AI accuracy" problem. This feedback loop is what turns a quoting agent from static to steadily improving.
Respect approval thresholds
If a quote's discount level or total value crosses a threshold that would normally require manager approval on a manually-created quote, the agent-generated path must trigger the same approval workflow — no exception for AI-originated documents. Routing around existing approval hierarchies because "the agent drafted it" is a control gap that shows up in the first audit.
| Step | Owner |
|---|---|
| Parse customer intent from unstructured text | LLM |
| Resolve ambiguous references | LLM query + human confirmation |
| Compute pricing | Acumatica pricing engine, never the LLM |
| Approval routing | Existing Acumatica workflow, unchanged |
| Send to customer | Human, always |
Wrapping up
A sales quoting agent works when it sticks to what LLMs are good at — turning messy customer language into structured intent — and defers entirely to Acumatica's own pricing engine and approval workflow for anything involving actual numbers. Land every quote as a draft, resolve ambiguity by asking rather than guessing, and track what reps correct so the extraction gets better over time instead of staying a fixed guess.
Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.