Manufacturing — made-to-order fine jewelryAgentic AI & document extraction

AI-powered vision-enabled agentic solution for ERP order intake automation

How a made-to-order fine-jewelry manufacturer turned unstructured customer email into structured Business Central job cards — with a human approval gate and zero invented fields.

A safety boundary diagram. The intake service reads from the live production ERP — customer records, item data and prior orders. Anything it writes is addressed to a separate sandbox company by default, and the live write is off by default, so there are two independent safeties. The service has no write path of its own. A human approval gate spans the full width of the diagram and is the only path to a job card in the ERP: gated on permissions, required-field validation and policy checks, with every correction stored before and after.
Reads come from the live ERP; writes are addressed to a sandbox company by default, and a person is the only path to a real job card.

Project snapshot

Client
A US fine-jewelry manufacturer producing made-to-order pieces for a couple of hundred independent retail jewelers
Industry
Manufacturing — made-to-order fine jewelry
Business function
Order intake and production planning
Challenge
Custom orders arrive as free-text email with sketches, CAD files and photos attached. Staff spent 15–30 minutes keying a complex order into Business Central, and each missing detail added 1–3 days to the cycle.
Solution
An order-intake agent that reads the thread and its images, fills ~25 Business Central job-card fields with calibrated per-field confidence, writes per-role shop instructions, detects what the customer left out, drafts the follow-up question in the shop’s voice, and stops at a human approval gate.
Result
83% field-extraction accuracy and 100% customer identification across 11 real orders, 97.7% on the eight fields that must be exactly right, zero hallucinated fields, and a reviewable draft in about 79 seconds.

Key outcomes

83%
Field-extraction accuracy across 11 real orders
97.7%
Exact match on the eight critical job-card fields
0
Hallucinated fields
79 sec
Mean time to a reviewable draft order

The client

A trade shop where every order is a one-off

A US fine-jewelry manufacturer producing made-to-order pieces for a couple of hundred independent retail jewelers runs every order through Microsoft Dynamics 365 Business Central. A retail jeweler describes what their customer wants; the shop casts, sets and finishes it.

That flexibility is why the front door is a mailbox — one with six figures of history — rather than an order form.

A jeweler types what they want at 11pm and attaches a phone photo of a hand sketch, sometimes a CAD file, sometimes a competitor’s product page — often all three in one thread.

The challenge

Minutes of typing, then days of waiting

Someone on the order desk reads each thread and types it into the ERP. When a detail is unstated, staff email back and wait.

The manual path

15–30 min
to enter one complex order correctly, in the client’s own description
1–3 days
added per order cycle whenever a detail is unstated — stone sourcing, chain supplier, finger size

Two costs sit underneath that one. Every confirmed order also fans out into three linked sub-orders, hand-created, one for each shop role — and the written instructions for each role are in a different vocabulary, so the same brief has to be told four different ways.

And the rules governing all of it — material standards, per-customer preferences, when to ask versus when to assume — live in two or three people’s heads. A cost problem and a succession problem at once.

Constraints

What we had to design around

Schema

110
fields on a job card — 137 observed live
~26
that are order-entry relevant
56
generated downstream — must never be predicted
  • DataThe customer master had no email column at all, and two customer records were found sharing one address — while 100% customer identification was the hard bar.
  • SignalRoughly three conversations in ten in the mailbox are machine or internal traffic — a separate, mailbox-level measurement. Inside the pilot threads themselves, 62% of the messages were internal noise a human must discard first, and only the remaining 38% is customer signal.
  • SecurityThe shop’s own replies quote the finished ticket, so a leaky filter lets the agent copy the answer instead of extracting it — and one that reads message bodies lets a sender suppress their own message.
  • OperationalA small review team under permanent backlog pressure; anything added to their day must beat what it replaces on the first attempt.
An inbound email thread of mixed messages passes a single filter that tests the sender address only, never the message body. Customer messages — about 38% of the messages in a pilot thread — are kept and are the only text extraction ever sees. Internal and production traffic, the remaining 62%, is dropped. Two notes explain why: because the body is never read, a sender cannot get their own message dropped by pasting the internal domain into it, and the domain match is exact or sub-domain so a look-alike domain does not pass; and the dropped branch matters because the shop’s own replies quote the finished ticket, so a leak would let the agent copy the answer instead of reading the order. Measured leakage across the pilot: zero. Separately, roughly three conversations in ten in the mailbox are machine or internal traffic.
The filter that decides what the model is allowed to read tests the sender address only — never the message body.

Each of these was written into a dependency and risk register before the production phase began, with a likelihood, an impact and a mitigation per row — and one of them was ranked above all the others. The customer master had no email column, so mapping senders to accounts depended on a list only the client could produce. Our own note on it was blunt: this is the single highest-risk dependency, and the only gap the proof of concept could not close from its own data. The agreed fallback was written down at the same time — domain matching covers most accounts, unmatched senders route to a manual identification step in the review console rather than a guess, and the fully automated identification target stays unclaimed until the mapping exists. That is why the result below is reported as 100% on the pilot corpus and not as a claim about every account.

Our approach

Prove the reasoning before wiring production

10
business days to build the proof of concept, every integration mocked
0
measured leakage — the agent never reads a finished ticket during extraction

We built the proof of concept in ten business days with every integration mocked, each one behind the interface its live counterpart would later have to satisfy. In the production service that discipline became a rule with teeth: a new capability has to land in both the mock and the live adapter, because a mock that lags the real thing produces a test suite that passes while production fails.

The evaluation set came free. The ERP already held finished job cards paired with the messy email that produced them — ground truth nobody had to annotate.

The bar was not ours to set. Before the build began, the client fixed four pass conditions for phase one: customer identification had to work for known accounts and for the domain-fallback cases; extraction and clarification quality had to match what the order desk expected on the pilot set; the output had to be accepted as ERP-entry-ready by their own team; and any field not traceable to the email or an image counted as a failure — zero tolerance, not a percentage. Day ten was a demo and a written go/no-go recommendation, with iterating the same phase as an explicit, non-embarrassing option. All four conditions were met and the client proceeded to the production build.

The production phase carried its own acceptance table — a pass condition per deliverable, agreed in advance: no internal message may ever reach the agent as a source; low-confidence images are flagged, never guessed; no order reaches assembly with a critical field missing; escalation to a human after exactly two unresolved rounds; every correction captured before-and-after and exportable, with the data owned by the client.

What we chose not to do matters as much: no fine-tuning, no bigger model. When accuracy plateaued, the gains came from a deterministic verification pass and from measuring the model’s confidence rather than trusting it.

The solution

Five stages, two to three model calls, one human gate

  1. Ingest No model. Internal senders are filtered on the sender field only, never on body text; customer resolution is deterministic code against the ERP’s contact records, and an unresolved customer becomes a flag, not a guess. Images go to Gemini Flash.
  2. Extraction One Claude Sonnet call fills roughly 25 job-card fields with per-field confidence, from the filtered thread, the customer record, the image reading and the shop’s written procedure.
  3. Verification No model, and this is where the accuracy lives: canonicalization, house rules, vocabulary enforcement, per-service-type required-lane checks, a format linter, then confidence calibration.
  4. Clarification Gaps become at most three targeted questions in the shop’s voice, drafted by a smaller model and skipped when there are none. After two unresolved rounds the job escalates to a person.
  5. Assembly The approved order becomes one job card carrying fourseparately-voiced instruction lanes — CAD, jeweler, stone setter, polisher — and three linked sub-order records, one for each shop role that has to be scheduled and paid. Skipped whenever gaps remain open.
A five-stage pipeline diagram. A customer email thread enters Ingest, deterministic code that filters internal mail on the sender field and resolves the customer; attached images branch to a Gemini Flash vision step. Extraction is a single Claude Sonnet call filling about 25 job-card fields with per-field confidence. Verification is deterministic again — house rules, vocabulary, a required-lane matrix, a format linter and confidence calibration, worth 5.3 accuracy points at zero token cost. Clarification runs on a smaller model only when gaps remain, asks at most three questions, and escalates to a person after two unresolved rounds. Assembly runs only when no gaps remain, turning one brief into four instruction lanes for CAD, jeweler, stone setter and polisher. A human approval gate spans the diagram before a job card is created in the ERP.
Five stages from email to job card. Ingest and verification are deterministic code; two model calls carry a typical order, a third only when images are attached — and nothing reaches the ERP without a person.
+5.3 ptswhat the deterministic verification pass is worth — no model, measured offline at zero token cost

Every field lands in a review console showing its value, its confidence and its source.

Responsible by design

Five principles for knowing what it doesn’t know

  • Abstain

    Below threshold, it leaves the field blank and asks.

    Zero hallucinated fields was the client’s own acceptance criterion, enforced structurally rather than by prompt wording.

  • Calibrate

    The reviewer sees expected accuracy, not the model’s opinion of itself.

    Self-reported confidence is systematically overconfident; the thresholds run on a curve fitted to labelled data. Fixing this made the dashboard look worse, which was correct.

  • Attribute

    An image reading is marked, never merged.

    Tagged and shown beside the field for line-by-line confirmation, never authoring the record. Confirming one is recorded as a different event from correcting it, so the learning loop cannot mistake agreement for teaching.

  • Contain

    Read production, write sandbox.

    The service reads live ERP data but routes writes to a sandbox company by default; pointing them elsewhere is a deliberate configuration change.

  • Gate

    Nothing reaches a real job card without a person.

    Approval is gated on permissions, required-field validation and policy checks, and every correction is stored before and after.

A decision diagram for every extracted field. The field arrives with the model’s raw self-reported confidence, which is mapped through a calibration curve fitted against labelled fields — a raw 0.88 corresponds to about 0.76 actual accuracy. The calibrated score routes the field three ways: 0.90 and above is auto-populated without a flag; between 0.50 and 0.90 the value is populated and flagged so the reviewer sees it with its expected accuracy; below 0.50 the field is left blank and becomes a gap and a question to the customer. That low branch produces zero hallucinated fields, a hard acceptance gate rather than prompt wording. Image-derived fields keep a separate, uncalibrated bar; if every one falls below it, the whole order goes to a person.
Every extracted field is routed by a calibrated expected accuracy, not by the model’s opinion of itself — and the bottom band is where “zero hallucinated fields” comes from.
0.88 → 0.76fit against labeled fields, a raw model confidence of 0.88 corresponds to about 0.76 actual accuracy

What is unfinished is written down rather than called done: webhook signature verification is still a stub, and access control on some routes has known gaps.

Results

Measured against the shop’s own finished tickets

  • 83% field-extraction accuracy across 11 real orders, scored field-by-field against each order’s finalized ERP ticket. The deterministic verification pass raises the offline re-score to 88.6%.
  • 97.7% exact match on the eight critical fields (86 of 88) — customer, category, service type, metal, ring size, centre-stone responsibility. Those decide whether a card is usable.
  • 100% customer identification on the pilot corpus, without a single guess. Measured on those orders, not claimed for every trade account — the customer master still has no email column.

Beyond the numbers

What else changed

The rules that lived in two or three heads are now a versioned document a non-engineer can edit. Every field carries provenance, so a disagreement about an order is a lookup, not an argument.

~2,400tests in the suite — running with no keys and no token spend
  • About 79 seconds and eleven cents of model spend per order, over three to seven model calls.
under $5what the whole proof of concept cost to run and re-run

The order desk did not adopt the system during the engagement: the cards were correct, but not shaped the way that shop writes cards. Capturing the ticket-writing procedure is now a first-class deliverable ahead of any further extraction tuning, and the client is extending the system himself — the architecture is already being reused on a second project.

If your order desk runs on email, the first step is small

Ten days, your own historical orders, no integration work. You would know whether it works on your data before committing to a build.