Modality-Conflict Arbitration

aka Cross-Modal Arbitration, Cross-Modal Disagreement Detection, Per-Channel Claim Reconciliation

category: verification-reflection · status: emerging

Have each observation channel emit its own recorded claim, treat disagreement between channels as a detected event, and resolve it against a pre-declared per-claim-type modality authority rather than an implicit fused guess. A support agent processes a recorded call. The transcript reads "that is exactly what I needed, thanks", so the text branch marks the caller satisfied and closes the ticket. The audio branch heard a flat, clipped delivery and marks the caller annoyed. Because the two claims were recorded separately, the disagreement is caught, the declared authority for tone is the acoustic channel, and the call goes to a human instead of being closed.

2. Problem

An agent observes one situation through more than one channel at the same time: a call arrives as both an audio stream and a transcript, a web page arrives as both an accessibility tree and a screenshot, a clip arrives as both a caption and its frames, a clinical intake arrives as text, voice and video together. Each channel carries something the others do not. Standard practice fuses them early — the channels are encoded into one representation, or the cheapest channel is rendered into text and the rest are dropped — and a single generation pass produces one answer. Nothing in that pass records what each channel said on its own.

Channels do not always agree, and a fused pass has no way to report that they disagreed. The measurements are consistent across modalities. On audio-grounded dialogue, text-only reasoning exceeds 90 percent accuracy when transcript and acoustics agree but falls to 33-48 percent when they conflict, and audio-native models still pick the transcript-biased answer in roughly 30 to 40 percent of conflict cases. Attention-level analysis shows the bias is structural rather than incidental: a distributed set of heads drives generation toward the textual premise while only a small localised set resists it, so the erroneous premise wins by routing. Benchmarks over long audio-visual material find that omni-modal models caption and answer questions on temporally aligned content yet cannot reliably perceive that the two tracks contradict each other. The output is not a hedged answer but a confident one, and the contradiction that was present and detectable in the inputs leaves no trace.

Competing forces:

3. When to Use

4. When Not to Use

5. Architecture Diagram

flowchart TD
  A["Observation: one situation, several channels"] --> B["Transcript claim"]
  A --> C["Acoustic claim"]
  A --> D["Visual claim"]
  B --> E{"Claims agree?"}
  C --> E
  D --> E
  E -- "yes" --> F["Answer, agreement recorded"]
  E -- "no" --> G["Conflict recorded as an event"]
  G --> H{"Authority declared for this claim type?"}
  H -- "yes" --> I["Apply authoritative channel, keep losing claim"]
  H -- "no" --> J["Abstain or escalate to a human"]

Each channel commits to its own claim first; a disagreement becomes an event that a pre-declared per-claim-type authority resolves, or that sends the case to abstention.

6. Components

7. Tools

8. Guardrails

An answer may not be emitted from a fused representation while the channels disagree: each channel must record its own claim before fusion, a detected conflict cannot be settled by an implicit or global modality preference, and only the authority declared in advance for that claim type — or abstention and escalation — may resolve it.

Therefore: keep each channel's claim separate and recorded, raise disagreement between channels as a detected event, and settle it with an authority declared in advance for that claim type, abstaining or escalating when no declared authority applies.

9. Failure Modes

10. Evaluation Metrics

11. Code Examples

Turn an invisible text-dominance win into a recorded conflict resolved by a per-claim-type authority.unverified

# BEFORE - implicit fusion, one pass, one answer
obs   = {"audio": wav, "transcript": asr(wav)}
fused = model("How does the caller feel?", obs)
# transcript says "that is exactly what I needed, thanks"
# prosody is flat and clipped
# -> returns "satisfied" with high confidence; the contradiction is gone
return fused          # ticket closed


# AFTER - per-channel claims, detected conflict, declared authority
CLAIM_SLOTS = ["literal_content", "speaker_affect", "visible_objects"]

AUTHORITY = {                       # declared in advance, per claim type
    "literal_content": "transcript",
    "speaker_affect": "acoustics",
    "visible_objects": "frames",
    # "intent_to_churn": no entry -> not resolvable by any single channel
}

claims = {
    "transcript": extract(transcript_only, CLAIM_SLOTS),
    "acoustics":  extract(audio_only, CLAIM_SLOTS),   # NOT conditioned on the transcript
}
# claims["transcript"]["speaker_affect"] = ("satisfied", 0.91, span="0:12-0:15")
# claims["acoustics"]["speaker_affect"]  = ("annoyed",   0.78, span="0:12-0:15")

for slot in CLAIM_SLOTS:
    values = {ch: c[slot].value for ch, c in claims.items() if slot in c}
    if len(set(values.values())) <= 1:
        continue                                   # agreement, nothing to arbitrate

    conflict = record_event("modality_conflict", slot=slot, claims=values)
    winner   = AUTHORITY.get(slot)

    if winner is None or claims[winner][slot].confidence < MIN_CONF:
        return escalate(conflict)                  # no declared authority -> abstain

    decide(slot,
           value      = claims[winner][slot].value,
           because    = winner,
           dissent    = {ch: v for ch, v in values.items() if ch != winner},
           confidence = downgrade(claims[winner][slot].confidence, conflict))

# speaker_affect resolves to "annoyed" on acoustic authority,
# the "satisfied" claim is kept as dissent, and the call is routed to a human.

Expected benefits

Known uses

Related patterns

References