One free-text glass line in — quantity, dimensions, and every glass/spacer/gas slot out, each tagged with the engine that produced it and why. Best of both worlds: 97.6% Glass AGI pass rate at 85.9% field accuracy, ~400ms warm.
A glass order line like 15 x 4/16/4 LowE 1200x800 carries two very
different kinds of information. Structure — the quantity, the dimensions, the
a/b/c composition — is positional and regular; a deterministic parser
(/random) nails it. Meaning — that LowE is a
low-emissivity coating on the second pane, that a bare 16 between two
glasses is the spacer — is semantic; an LLM-style parser (/understandable)
reads it far better than any regex.
Run them head-to-head field by field and neither dominates. /random
crushes dims and v1; it collapses on qty when
the count is implicit. /understandable reads gas and
composed panes, but hallucinates structure it should have read literally. The green
bars below are /comprendre: for every field it lands at or above
the better of the two — because it picks the better of the two, per slot.
Ground truth: 18 real glass order lines, per-field exact match.
/comprendre ≥ max(/random, /understandable) on
all six fields, and strictly wins qty, v2, and
gas — the fields where the two base parsers disagree most.
Both parsers run on the same text. merge_sources() then chooses a
winner for each slot by a fixed, auditable rule — never a blend:
| Slot | Rule | Why |
|---|---|---|
qty | /random, unless it defaulted to "1" → then /understandable | count is structural, but an implicit count needs reading |
dims | always /random | purely positional — 1200x800 is never ambiguous |
verre1 / verre2 / intercalaire / gas | /random if its match confidence ≥ 80%, else /understandable | trust the deterministic match when it's sure; fall back to meaning when it isn't |
The threshold is DEFAULT_RANDOM_THRESHOLD = 0.8. Every choice is
recorded in xai.source_selection so the answer is explainable down to
the slot.
Input 15 x 4/16/4 LowE 1200x800 → POST /comprendre:
{
"qty": "15", # source: understandable (/random defaulted)
"dims": "1200x800", # source: random (always structural)
"verre1": {"num_article":"1004", "denomination":"4 rFloat", "confidence":1.0, "source":"random"},
"verre2": {"num_article":"2004", "denomination":"4 rTherm", "confidence":1.0, "source":"random"},
"intercalaire": {"num_article":"99190", "denomination":"Interc. TPS 16 mm", "confidence":1.0, "source":"random"},
"gas": null
}
# quality_score 0.875 · 3/4 slots matched · avg confidence 1.0
A second, prose-style line resolves all four slots at confidence 1.0:
POST /comprendre {"text":"8 DV 44.2/16 argon/4 planitherm en 1500x1000","factory_id":4}
→ qty 8 · dims 1500x1000 · verre1 44.2 · verre2 4 rFloat
· intercalaire alu 16 mm · gas Argon # quality 1.0 · 134ms
The recurring question: "how does a CPU do the LLM comprehension we pay for?" The honest answer is that the LLM was doing two jobs, and only one of them needs a neural net.
| Job | Needs an LLM? | Why |
|---|---|---|
| Transcribe — pixels → faithful text | YES | Reading ink off a scan is irreducibly perceptual. This is the one place a VLM earns its cost. |
| Comprehend — text → structured JSON with a resolved article per slot | NO | This is deterministic classification over a finite catalogue — exactly what Snake SAT does, sub-ms and auditable. |
You have been paying LLM rates for both. The knowledge engine already does job
two on CPU; /comprendre/v2 shrinks the LLM to job one and hands 100% of the
comprehension to the on-prem SAT suite.
The knowledge engine keeps no model
resident. Each unseen slot shells out to inference.py (load one
<field>.snake.json → get_probability → the process exits —
OOM-safe, no hot swarm), then the outcome is cached to disk and S3. Every repeat
of that slot is a pure lookup. A first stage — a monce_db designation vLookup — resolves
exact catalogue identity (#num, bare num>1000, exact
denomination) at confidence 1.0 before Snake is ever consulted.
Live today: 16 factories · 76 field-Snake models · ~52,000 cached
resolutions, S3-durable across restart/resize. Matching (/query,
/batch) is already 100% CPU/SAT — no LLM in the hot path.
/comprendre/v2, /comprendre/extract)One document in. An LLM (document.aws/describe, Opus) does
structured OCR only — it fills a fixed JSON schema and is explicitly forbidden from
interpreting or matching anything. Then the CPU suite takes over:
CLIENT_NAME / CLIENT_LOGO / CLIENT_ADRESSE / CLIENT_SIRET
→ /query_client (SIRET-first, factory-scoped) → enriched with monce_db client
metadata (ville, code postal, siret).QUANTITY · HEIGHT · WIDTH · REFERENCE · REPERE ·
GLASS_COMPOSITION. The dimensions and counts are kept verbatim; only
GLASS_COMPOSITION is handed on for comprehension.comprendre splits the composition into slots and
assess resolves each through the 400-point ensemble (snake 200 +
knowledge 100 + fuzzy 50 + lookup 50), per field, then attaches the article's
monce_db metadata (type, coating).match: null with its candidate pool and a reason, never a confidently-wrong
article. Reliability by construction.No cross-factory leakage is possible: /query_client and
assess are both per-factory_id, over per-factory models. The same
text resolves to a different article in each factory — that is structural, not a tuned
guardrail. The only LLM spend is the transcription (hundreds of output tokens); every
downstream match is CPU and store-cached toward zero marginal cost.
The single most important concept: a glass line is one string that encodes an ordered
insulated glass unit (IGU). comprendre splits it into typed slots, and
each slot is resolved against its own field model — a verre text never
competes with an intercalaire catalogue.
| Concept | What it is | In 4/16/4 LowE | Field model |
|---|---|---|---|
| verre | a glass pane (outer / inner / middle) | 4 → verre1, 4 LowE → verre2 | verre1/2/3 |
| intercalaire | the spacer bar between panes (the gap number + material) | 16 → spacer | intercalaire/2 |
| remplissage | the gas fill in the cavity | argon (when present) | remplissage |
| façonnage | edge working / arête finishing | — | façonnage_arete |
So 44.2/16 argon/4 planitherm decomposes to
verre1 44.2 (laminated), intercalaire 16, remplissage
argon, verre2 4 planitherm (coated) — four independent per-field
resolutions, one coherent IGU. This typed split is what makes the structured OCR schema
gradeable field-by-field against ground truth.
/comprendre is the parsing front-end: it turns a paragraph, an email,
or an OCR dump into structured rows and matches each slot against the factory
catalogue. /comprendre/v2 puts a structured-OCR LLM in front of it and the
400-point ensemble behind it. It shares the per-factory Snake models that
/paper describes. See
/math for the matching objects and
/architecture for the module map.