When you run the same enrichment across multiple AI models, Entity Enricher can fuse the results into a single, high-confidence output. Fusion detects conflicts between model outputs and resolves them using deterministic rules or LLM-powered arbitration.
The conflict detector compares every field across all model outputs. Fields where all models agree pass through unchanged. Fields where models disagree are flagged as conflicts that need resolution.
| Type | How Compared | Agreement Means |
|---|---|---|
| Scalar | Normalized exact match (trimmed, lowercased, rounded) | All values equal after normalization |
| Multilingual | The run's primary language decides; translation differences only trigger a per-language merge | Same text in the primary language — phrasing variants of a translation are not disagreements |
| Array | Set comparison (order-independent) on the primary-language view of items | Same items regardless of order or translation phrasing |
| Object | Per-property while the identity fields prove both models describe the same thing — otherwise the whole object is one conflict | All nested properties match |
| Null / empty | A null, empty-string, or empty-array value is an abstention, not a claim | The filled value wins without counting a conflict |
Deterministic rules run on every fusion and settle everything the models' own values can prove. What they can only prefer an answer to — a contradicted value, a nested object the models describe differently, an item only one model produced — is put to a resolver. Selecting an arbitration model in the sidebar decides who that resolver is: the rules themselves, or an LLM.
Deterministic rules are applied based on each field's data type. Almost always this needs no LLM call at all — resolution is instant and free. The one exception is numbers the models disagree about wildly, which no rule can honestly settle; see below.
| Field Type | Rule | Rationale |
|---|---|---|
| String | Majority vote; tie goes to the longest value | More detail is usually better |
| Number | Model value nearest the median | Robust to outliers, never a fabricated average |
| Boolean | Majority; true wins ties | Conservative default |
| Multilingual | Per-language majority vote, union of languages | Each language resolved independently |
| Array | Key-aware union: items group on their key fields, variant spellings fold together, matched items merge per-field | One row per logical entity, nothing lost |
| Object | Per-field when identity agrees; otherwise one model's object is taken whole | Blending two objects that describe different entities would invent a third that neither model returned |
| Null vs Value | Prefer the filled value | Missing data is worse than any value |
Tie-breaker: When votes are tied, the value from the higher-priced model wins (as a proxy for capability), followed by alphabetical model name ordering. For a whole object taken atomically, completeness — the number of filled leaves — comes between the two: with nothing to prove which entity is real, prefer the stronger model, then the answer that carries more information.
Merging a nested object field by field is only safe while both models are describing the same thing. When the identity fields do not prove that — different keys, or no keys at all with a real disagreement underneath — the object becomes a single conflict and one model's version is taken verbatim. Otherwise fusion would assemble a chimera: this model's address on that model's company. One consequence is deliberate but worth knowing: the winner is taken with its blanks included, so a field the winner left empty stays empty — which can hold the entity back at the database admission gate. The reason rides along in the run's validation warnings.
“Nearest the median” is right for models rounding differently and wrong for models contradicting each other — 0 versus 1854 is not a rounding difference. When the values' relative spread reaches 20%, that field is escalated to an LLM arbiter chosen automatically through your organization's usual model selection, and the call is billed like any other. Those fields are flagged as auto-escalated in the fusion audit trail, so a merge that cost tokens always says which fields caused it.
When you select an arbitration model in the sidebar, the questions the rules could not settle are put to that LLM. It sees the entity's identity, the description of each field, and every model's value shown in your primary enrichment language — and it answers by pointing, never by writing a value of its own.
Questions are asked level by level: the entity itself first, then each matched array item in its own call, with its own identity as context (“Act I of this opera”) — and an item the arbiter dropped is never asked about again. The shared part of the prompt is cached by the first call, so the deeper calls run in parallel at a fraction of the cost.
Fallback: If the arbitration model fails (timeout, error), the rule-based decisions stand, so you always get a result — and the record says which method applied.
After conflict resolution, the system builds a single merged result and stores it as an “arbitration” record in the database. Every merged result includes an audit trail so you can trace how each conflict was resolved.
Every merged result includes metadata that documents the fusion process:
The same audit trail is shown for any merged record on the History page, in its Overview tab. Decisions made inside an array — a field of a matched item, an item kept or dropped — are listed too, so what was left out is as visible as what was kept. An LLM-arbitrated record names its arbiter as its model; a rule-based merge lists the models it merged instead, since it made no LLM call at all and carries no prompt, no tokens and no cost.
After fusion completes, the “Merged” tab in the results panel shows:
In batch enrichment, fusion happens automatically when you select two or more models. You do not need to click “Merge Results” manually — as soon as every model has succeeded for an entity, fusion runs and the merged result appears alongside the individual model outputs. A run in which one model failed is deliberately not fused: merging what is left would silently publish a partial answer as if it were the agreed one. Recover the missing model first — retrying its failed expertises fuses the run automatically once it is whole again.
fusion_started, conflicts_detected, and fusion_completed events in real-time.