Skip to main content
Two people file reports about the same project and the numbers do not match — one says the budget is 2 million euros, the other says 5 million. Your memory layer has to hold both, tell you they conflict, and be honest about what it takes to settle the disagreement.

What You’ll Build

Two one-line documents about Project Falcon go into an isolated dataset, and they contradict each other on both the lead and the budget. With contradiction detection on, the second ingestion records a contradicts edge carrying both fact texts, the reason, and a confidence score — nothing is overwritten or deleted — and the session layer tracks which graph elements each answer used, so a rating can be folded into retrieval weights. What comes out is an answer that reports the conflict, keeps reporting it even after a 5/5 rating, and flips to the corrected budget only when an explicit correction is remembered. The complete runnable script is examples/demos/feedback/contradiction_feedback_demo.py — this page walks through its key moments rather than reproducing it.

Features in Play

  • Remember — ingests each document into the demo dataset, and it is the cognify() stage inside it that the contradiction check hangs off
  • Contradiction Detection — the opt-in check that compares the newly touched facts against the ones already stored and writes the contradicts edge
  • Sessions — records each answered question as a QA entry, including which graph nodes and edges the answer used, so feedback has something to attach to
  • Feedback Systemadd_feedback() puts a 5/5 rating and a comment on that QA entry, and a feedback-weights pipeline pushes it into the graph
  • Feedback-Weighted RankingDEFAULT_FEEDBACK_INFLUENCE is what makes those weights count during retrieval scoring

What to Expect

Every box is read back from the graph or the session store rather than echoed from the inputs — you see the actual edges and weights, not a narration of them. The boxes below are from a real run, trimmed. Because ingestion, the contradiction judgement, and every answer are live LLM calls, the exact wording, the confidence scores, and even the number of contradictions flagged vary from run to run. STEP 1 — the first report goes in, and the box lists the facts extracted from it: Anna as the lead, the 2 million euro budget, and their types. With only one document stored there is nothing to disagree with yet.
STEP 2 — the conflicting report lands. Both budget facts now sit in the graph side by side, and the detection pass flags the disagreements — in this run both the budget and the lead — each as a FACT A/FACT B pair with the model’s reason and confidence. The flagged line says it explicitly: nothing was deleted.
STEP 3 — the question is asked for the first time. Retrieval sees both budget facts, so the answer reports the conflict instead of picking a side. The box also shows the session bookkeeping the next step depends on: which graph elements the answer used, all still at the neutral weight 0.5, and the qa_id the exchange was recorded under.
STEP 4 — the 5/5 rating is attached to that qa_id and the weights pipeline pushes it into the graph: every element the rated answer used moves from 0.5 to 0.55, uniformly. That uniformity is the setup for the next box.
STEP 5 — the same question in a fresh session, so only the graph and its new weights are in play. Both budget facts were raised by the same amount, so their relative ranking is unchanged and the answer still reports the conflict: a rating steers attention, it does not decide what is true.
STEP 6 — the correction is remembered as a document, and retrieval finally has a statement that explicitly supersedes the 2 million figure. The answer in a third fresh session flips to 5 million euros, while the old fact stays stored and auditable through its contradicts edge.

Before You Start

  • Complete Quickstart to understand basic operations
  • Ensure you have LLM Providers configured — ingestion, the contradiction judgement, and every answer are live calls, so the wording and the confidence score vary by model
  • Run it from a checkout of the cognee repo with dependencies installed and a configured .env
  • Expect the script to set its own environment before importing cognee: it points cognee’s data and system roots at /tmp/conflict_demo (deleted at startup), turns on CONTRADICTION_DETECTION, keeps CACHING on, and raises DEFAULT_FEEDBACK_INFLUENCE to 0.2 from its default of 0.0 — see Contradiction detection for the contradiction tuning knobs
  • The run starts with prune_data() and prune_system(metadata=True), which is safe here only because those roots are the isolated demo directory rather than your real storage

How It Works

Stage 1: Isolate Storage and Enable Detection

These five settings run before import cognee, which is what makes them take effect. Two of them are the demo’s subject: CONTRADICTION_DETECTION appends the conflict check to the end of the ingestion pipeline (it is off by default), and DEFAULT_FEEDBACK_INFLUENCE lifts feedback weights from ignored to a fifth of the retrieval score, so a rating can actually move ranking. The storage roots keep the whole run inside /tmp/conflict_demo.

Stage 2: Remember the Second, Conflicting Document

The first remember() call stores Anna and the 2 million euro budget; this second one disagrees on both counts. Because entity ids are derived from entity names, “Project Falcon” lands on the same node, which puts the new budget fact one hop from the stored one — the neighbourhood the contradiction check compares. self_improvement=False skips the enrichment pass so nothing but ingestion is in play.

Stage 3: Read the Conflict Back From the Graph

Every step re-reads the graph through this helper rather than trusting what the previous call returned. It splits the edges into two piles: contradicts edges, whose properties carry first_fact, second_fact, reason, and confidence for the printout, and ordinary semantic facts. Structural edges such as contains and is_part_of are filtered out so the printed list is only human-meaningful statements — and both budget facts stay in that list, because flagging a conflict never removes either side.

Stage 4: Ask, and Capture What the Answer Used

Asking for the budget with a session_id writes a QA entry into the session store, and that entry’s used_graph_element_ids is the link between an answer and the graph elements behind it. The demo reads the current feedback weight of each of those elements now, before any rating exists, so the next step has a baseline to compare against. Retrieval sees both budget facts, so the answer reports the conflict rather than choosing.

Stage 5: Rate the Answer and Push the Rating Into the Graph

add_feedback() attaches the score and comment to that one QA entry — at this point the feedback lives in the session and nothing in the graph has moved. The weights pipeline is the second half of the loop: it walks the elements the rated answer used and updates their feedback_weight, with alpha controlling how hard one rating pulls. Printing the before and after side by side shows the shift. In an ordinary application this is what improve() does for you.

Stage 6: Ask Again — a Rating Cannot Break a Tie

The same question runs in a fresh session, so nothing but the graph and its new weights can influence the answer — no conversation history carries the rating’s text forward. The rating raised both budget facts equally, because the answer it praised had used both, and equal raises leave their relative order unchanged. The answer still reports the conflict, which is the point of the step: feedback steers which memories get attention, not which ones are true.

Stage 7: Remember the Correction and Watch the Answer Flip

The same claim the feedback comment made in prose is now remembered as a document — this is what textual feedback becomes when you persist it. Retrieval finally has a statement that explicitly supersedes the 2 million figure, and the answer in a third fresh session flips to 5 million. The 2 million fact is still stored and still auditable through its contradicts edge; what changed the answer was new knowledge, not the rating.

Run It

Cognify

What the contradiction check compares, what it skips, and how to tune it.

Feedback System

Rating a session answer and pushing that rating into graph weights.

Truth Subspace Reranking

How feedback weights and truth weighting reach retrieval scoring.

Improve

The operation that applies feedback weights for you outside a demo.