Skip to main content

Why contradictions matter

A customer service agent has a memory: “Customer is on the Basic plan.” Stored 8 months ago, confidence 1.0. The customer upgraded to Premium 3 months ago. The agent still applies Basic plan logic — not because the model is bad, but because contradicting information was never processed. Engram solves this by detecting contradictions when new memories are stored.

How detection works

When a new memory is stored, Engram:
  1. Finds semantically similar existing memories using HNSW embedding search (similarity ≥ 0.60)
  2. Runs tension analysis on each similar pair
  3. Handles the result based on tension type

Tension types

Two beliefs that cannot both be true simultaneously.Example: “User lives in New York”“User moved to Tokyo”Handling: The original memory’s confidence is demoted by 0.20. If it falls below 0.40, it is archived. The new memory is stored at 0.70 confidence.
Before: "User lives in New York" (confidence: 0.88)
After:  "User lives in New York" (confidence: 0.68)  ← demoted
        "User moved to Tokyo"    (confidence: 0.70)  ← new belief
New information supersedes old — the old fact was true at some point but is now outdated.Example: “User’s phone is iPhone 12”“User recently upgraded to iPhone 15”Handling: The original memory is archived. The new memory is stored at full confidence.Detected via temporal markers: now, recently, as of, switched to, moved to, upgraded, no longer, formerly…
Both beliefs are valid — they apply in different contexts.Example: “User prefers concise responses for quick questions” + “User prefers detailed responses for research tasks”Handling: Both memories coexist at their original confidence. No demotion.
Related but not directly contradicting — possibly complementary.Handling: New memory is stored without penalising the existing one. Both coexist.

Detection modes

Engram supports two contradiction detection modes:

LLM-based (default when LLM_PROVIDER is set)

Uses an LLM to analyse tension between two belief statements. Higher accuracy on subtle contradictions. Adds ~2–5s latency to store operations.
# Enable in docker-compose.yml or .env
LLM_PROVIDER=anthropic
ANTHROPIC_API_KEY=sk-ant-...

Embedding-only (zero API calls)

Uses cosine similarity bands + temporal/negation text heuristics. Zero external API calls. Sub-millisecond analysis. ~45–55% accuracy on the benchmark contradiction suite (vs. ~65% for LLM-based).
# Enable embedding-only mode
LLM_PROVIDER=none
Embedding-only mode still outperforms Mem0 (~15%) and Zep (~20%) on the same benchmark — because they have no contradiction detection at all. You don’t need LLM-based detection to be best-in-class.

Querying contradictions

# Find memories currently in tension
uncertainty = client.cognitive.detect_uncertainty(agent_id=agent.id)

for contradiction in uncertainty.contradictions:
    print(f"Tension between:")
    print(f"  A: {contradiction.belief_a}")
    print(f"  B: {contradiction.belief_b}")
    print(f"  Type: {contradiction.type}")

Audit trail

Every confidence change is logged with the source and reason:
# Why does the agent believe X?
stats = client.cognitive.get_confidence_stats(memory_id="uuid")

for event in stats.history:
    print(f"{event.timestamp}: {event.source}{event.old_confidence:.2f}{event.new_confidence:.2f}")
    print(f"  Reason: {event.reason}")
This mutation audit trail is the foundation for AI governance and explainability in regulated environments.