{"slug": "i-removed-one-edge-from-an-llm-context-graph-and-its-answer-changed", "title": "I removed one edge from an LLM context graph, and its answer changed", "summary": "A developer's experiment with ThoughtDAG, a context graph tool for LLMs, found that removing a single edge from the graph changed the model's answer, and that a scoring artifact—where outputs hit the max_new_tokens cap of 64—caused three apparent failures that were not actual context failures. The developer recommends logging finish_reason and raw responses to distinguish evaluator artifacts from genuine context-repair failures, and suggests separating the detection of a bad branch from the repair of the context after it is known to be bad.", "body_md": "Um, from what I found when I tried it:\n\nI think the experiment is getting more interesting once the question is split into a few separate layers.\n\nThe short version of my answers to your three questions would be:\n\n| Question | My current take |\n|---|---|\nWhat should be logged? |\nThe graph operation is only part of it. I would log the exact request payload your harness sent, model/runtime identity, generation termination, raw output, and evaluator state. In particular, `finish_reason` / output-cap hits turned out to matter in a small check I ran. |\nWhen is manual pruning useful vs automatic memory/RAG? |\nI would not make this a binary contest. Manual control seems especially useful for debugging, auditing, research interventions, and exceptional cases; automatic selection is better suited to routine scale; a hybrid where the system proposes and the human can inspect/override seems like a very natural third condition for ThoughtDAG. |\nWorth testing across models/context sizes? |\nYes, but I would separate semantic content, position, actual input length, and model/backend rather than just increasing the nominal context window or adding more models at once. |\n\nThe framing that now makes the most sense to me is:\n\ndetecting that a branch is badandrepairing the context after that branch is already known to be badare different experiments.\n\nYour current graph intervention is particularly clean as the second kind.\n\nThat distinction lets the current experiment stay narrow without asking it to solve the harder adjudication problem at the same time.\n\nSomething roughly like this:\n\n```\nintervention identity\n        ↓\nmodel/runtime identity\n        ↓\nexecution outcome\n        ↓\nevaluation identity\n```\n\n`source_prune`\n\n, descendant removal, replay, etc.)I would say **client-observed request payload** rather than assume that an OpenAI-compatible provider internally serializes it exactly the same way; the latter is often outside the experimenter’s visibility.\n\n`max_new_tokens`\n\nThat last layer ended up being more important than I expected.\n\nI tried a small matched-control run against the repair fixtures, and my first automated summary contained three apparent failures that were not actually context failures. All three outputs hit `max_new_tokens=64`\n\n; the model had already computed the correct answer in prose, but the required final-number line was cut in the middle of the number.\n\nI reran the **exact same pinned payloads** at 64 and 128 tokens. The old 64-token strings reproduced exactly and were prefixes of the 128-token generations; all three longer generations completed the correct answer.\n\nSo a small practical addition I would make to the trace format is:\n\n```\nhit_generation_cap\nfinish_reason\nraw_response\nparsed_answer\nscore\n```\n\nThat makes it much harder for an evaluator artifact to masquerade as a context-repair failure.\n\nThe matched control I tried, including the scoring gotchaThe question that originally motivated the post — *is a later correction enough, or should the earlier source leave the request?* — actually seems to contain several possible interventions:\n\n```\nappend a correction\nremove the bad source\nremove affected descendants\nrecompute affected descendants\n```\n\nThey are not interchangeable.\n\nA later correction asks the model to perform something like **belief revision** while contradictory or superseded material remains available. There is already evidence that this is non-trivial: the [Belief-R work on belief revision](https://aclanthology.org/2024.emnlp-main.586/) found that models often struggle to revise prior inferences appropriately when new evidence arrives.\n\nBut ThoughtDAG gives you another experimental lever: instead of asking the model to resolve the conflict internally, you can alter the effective context before the request.\n\nThat makes a useful separation possible:\n\n```\nA. Which state is actually stale / wrong?\n        ↓\nB. Once it is known to be wrong, what must be invalidated?\n        ↓\nC. What, if anything, must be recomputed?\n```\n\nI would treat **A** as a detection/adjudication benchmark and **B/C** as a repair benchmark.\n\nThat seems especially helpful for the temporal cases. If the latest turn says “the correction was wrong; go back to the old value”, the model may have no independent evidence telling it that the latest turn itself is false. Calling that a failure to *detect misinformation* would require a different source of truth.\n\nCalling the branch **known-bad by the experiment** and then asking what repair is necessary avoids that ambiguity.\n\nThis is also starting to show up as a distinct neighboring problem in recent agent-memory work. [STALE](https://arxiv.org/abs/2605.06527) separates state resolution from downstream policy adaptation, and the very recent [Dependency-Guided Rollback Repair](https://arxiv.org/abs/2608.10502) explicitly assumes diagnosed faulty memories and asks how to retract affected downstream state while preserving unaffected work.\n\nI would not treat those papers as proving the ThoughtDAG result — the systems and memory semantics are different — but the decomposition is strikingly similar.\n\nIt gives a reasonably standard vocabulary for what your source/subgraph/replay comparison is probing:\n\n```\nfault diagnosis\n        !=\nfault removal\n        !=\ndependency invalidation\n        !=\nselective recomputation\n```\n\nThat is probably a stronger framing than trying to make the one-edge result carry all four claims.\n\nThis was also the part of my small run I found most interesting after the matched-length question was controlled.\n\nAmong the 18 cases where pollution changed a clean-correct answer:\n\n```\nsource-only pruning      14/18\ncontaminated subgraph    18/18\n```\n\nAgain, one model and a small controlled fixture set, so I would not generalize the rate.\n\nBut it is consistent with a simple structural failure mode:\n\n```\nbad source\n    ↓\nderived claim\n    ↓\nderived calculation\n    ↓\nsummary / recommendation\n```\n\nOnce the derived state has been materialized into later messages, deleting only the original source does not necessarily remove the stale downstream text from the next request.\n\nThat makes the existing distinction between **source pruning**, **subgraph pruning**, and **replay/recomputation** useful in its own right.\n\nThere is also a nice design trade-off here:\n\nSo rather than asking only:\n\n“Does pruning work?”\n\nI would probably preserve the more informative question:\n\nWhat is the smallest repair that restores a valid downstream state without unnecessarily discarding unaffected work?\n\nThat seems compatible with the direction ThoughtDAG is already taking with [staleness and dependency-order replay](https://github.com/chenxiachan/thoughtdag).\n\nI would be hesitant to turn this into:\n\n```\nmanual pruning vs RAG\nwhich one is better?\n```\n\nbecause they optimize different things.\n\nA rough split might be:\n\n| Mode | Natural strength | Natural cost |\n|---|---|---|\nManual |\ninspectability, deliberate exceptions, debugging, research interventions, auditability | human attention |\nAutomatic |\nroutine operation, scale, low interaction cost | false keeps / false removals can be less visible |\nHybrid |\nsystem does routine selection; human can inspect/override important cases | more UI/control-plane complexity |\n\nThe distinction between stored history and effective model input is already a practical implementation primitive. For example, the [OpenAI Agents SDK exposes model-input filtering](https://openai.github.io/openai-agents-python/running_agents/), and [Claude context editing](https://platform.claude.com/docs/en/build-with-claude/context-editing) separates selective clearing from broader compaction.\n\nSo I do not think the interesting claim for ThoughtDAG needs to be:\n\n“other systems cannot filter context.”\n\nThe more distinctive question seems to be:\n\nWhat changes when context selection is visible, reversible, and expressed in the same graph the human is using to reason?\n\nThat gives manual control a possible value even when automatic selection is perfectly available.\n\nIt also suggests a fairly natural third condition if you ever want to study this:\n\n```\nautomatic suggestion\n        +\nhuman-visible accept / reject / override\n```\n\nRecent work on controllable memory use points in a similar direction. For example, [SteeM](https://aclanthology.org/2026.acl-long.670/) studies user control over *how strongly* an agent should rely on memory, rather than assuming maximum memory use is always desirable.\n\nAnother separation I like here is:\n\n```\nkeep this history?\n        !=\nshow it to the human?\n        !=\ninclude it in this model call?\n```\n\nYour current “remove the edge without deleting the earlier work” behavior is useful precisely because those do not have to be the same decision.\n\nA possible evaluation matrix for manual / automatic / hybridI think this is worth testing across models and larger contexts.\n\nI would just distinguish **nominal context capacity** from **actual input length**.\n\nAn 800-token experiment on a model advertised as 128K context is still an ~800-token experiment; changing the model’s maximum window does not by itself test long-context behavior.\n\nThere are at least four variables that can otherwise get mixed together:\n\n```\nsemantic treatment\nposition\nactual input length\nmodel / backend\n```\n\nThe first cheap sequence I would use is probably:\n\n**semantic control**\n\n`clean / polluted / matched-neutral / repaired`\n\n**position control**\n\nmove the same contaminated material earlier / middle / later while holding content as fixed as possible\n\n**actual length control**\n\nincrease real input length while preserving the intervention\n\n**model/backend replication**\n\nthen repeat a small selected panel across deliberately different model families/runtimes\n\nThere is good reason to isolate 2 and 3. [Lost in the Middle](https://aclanthology.org/2024.tacl-1.9/) showed that the position of relevant information can strongly affect long-context performance, while [Context Length Alone Hurts LLM Performance Despite Perfect Retrieval](https://aclanthology.org/2025.findings-emnlp.1264/) found degradation from increasing input length even when retrieval of the relevant evidence was effectively controlled.\n\nSo if an edge deletion changes both content and where everything else lands in the request, those are alternative explanations worth keeping visible.\n\nThe matched-neutral condition is one cheap way of removing a large part of that ambiguity before paying for a large model sweep.\n\nA compact decision tree I would use when reading the resultsOne thing I think the original post gets right is explicitly saying that this is **not** attention visualization or an explanation of why a particular token was generated.\n\nAn edge here establishes something concrete:\n\nan upstream node was or was not serialized into the downstream request.\n\nThat is a useful provenance/exposure relation.\n\nIt does not automatically establish:\n\nevery statement in the child is semantically dependent on that parent,\n\nor:\n\nthe model internally represented that graph edge as the cause.\n\nThere is a nearby research vocabulary for this. [ContextCite](https://arxiv.org/abs/2409.00729), for example, treats context attribution as a perturbation problem: alter subsets of the context and measure what happens to generation.\n\nSo I would be comfortable calling the ThoughtDAG operation an **observable context intervention** or a **counterfactual context ablation**.\n\nThat is already useful without promoting it into a hidden-mechanism explanation.\n\nThe current controlled arithmetic cases are useful because they make the intervention easy to audit.\n\nThe trade-off is that many of them share a similar computational shape.\n\nSo, if the next goal is **generalization**, I am not sure the highest-information next step is simply “more models × more nearly identical arithmetic cases.”\n\nA small number of different dependency motifs might tell you more:\n\n```\nratio / division\nconditional choice\nlookup → transformation\nmulti-source aggregation\nmulti-step plan with a reusable intermediate result\n```\n\nThe especially interesting cases for replay would be ones where a descendant contains **useful work that should not simply be thrown away**.\n\nThat would separate:\n\n“delete everything downstream and solve the easy final arithmetic again”\n\nfrom:\n\n“invalidate exactly the work that depended on the bad premise, then reconstruct the useful intermediate state.”\n\nFor a later natural-language track, something like [LongMemEval](https://arxiv.org/abs/2410.10813) gives useful categories such as multi-session reasoning, temporal reasoning, and knowledge updates. I would keep that as a separate generalization lane rather than weakening the controlled synthetic lane by trying to make one benchmark do both jobs.\n\nIn my Qwen run, the explicitly irrelevant-distractor cases produced:\n\n```\n0/9 derailments\n```\n\nwhile the misinformation and temporal-supersession families each derailed all nine of their tested k=1/2/3 cases.\n\nGiven how explicitly the fixtures identify those asides as unrelated, I would personally read that lane as a useful **negative control / sanity check**:\n\nthese clearly marked irrelevant asides did not land in this short controlled setup.\n\nI would not generalize it to:\n\nirrelevant context is harmless.\n\nThat distinction also keeps it compatible with the broader long-context literature, where irrelevant material and length can certainly hurt under other conditions.\n\nThis is not a problem with the current text-only intervention, but it may matter as ThoughtDAG grows more agentic.\n\nSome model APIs impose structural constraints on conversation history. A tool invocation and its result, for example, may have to remain paired in a particular order. Arbitrarily removing one message can make the remaining request invalid rather than merely changing its semantics.\n\nSo a future graph may need the notion of an **atomic pruning unit** or **protocol-aware context transformation**:\n\n```\nsemantic node\n        vs\nprovider-valid message unit\n```\n\nThat is probably only worth worrying about when tool traces themselves become editable context, but it seems like a useful boundary to keep in mind.\n\nPutting all of that together, I think the result is already more interesting than:\n\n“I removed an edge and the answer changed.”\n\nThe more specific experiment I see is:\n\nGiven a context state that is known to contain a contaminated branch, what is the smallest observable context intervention that restores a correct downstream state, and what useful work can be preserved?\n\nThat gives you several cleanly separable research questions without requiring the UI, the memory policy, the misinformation detector, and the model’s hidden reasoning to all be evaluated at once.\n\nAnd for the broader human-vs-system question, I would keep the thing that seems genuinely distinctive here: the branch can remain part of the visible history while being excluded from the active model request.\n\nThat means the design does not force **remembering**, **showing**, and **using right now** to be the same operation.\n\nTo me, that is probably the most interesting place to compare human-directed, automatic, and hybrid context control.", "url": "https://wpnews.pro/news/i-removed-one-edge-from-an-llm-context-graph-and-its-answer-changed", "canonical_source": "https://discuss.huggingface.co/t/i-removed-one-edge-from-an-llm-context-graph-and-its-answer-changed/179013#post_5", "published_at": "2026-08-23 03:46:03+00:00", "updated_at": "2026-08-23 04:13:05.648196+00:00", "lang": "en", "topics": ["artificial-intelligence", "large-language-models", "ai-tools", "ai-research"], "entities": ["ThoughtDAG", "OpenAI", "Belief-R"], "alternates": {"html": "https://wpnews.pro/news/i-removed-one-edge-from-an-llm-context-graph-and-its-answer-changed", "markdown": "https://wpnews.pro/news/i-removed-one-edge-from-an-llm-context-graph-and-its-answer-changed.md", "text": "https://wpnews.pro/news/i-removed-one-edge-from-an-llm-context-graph-and-its-answer-changed.txt", "jsonld": "https://wpnews.pro/news/i-removed-one-edge-from-an-llm-context-graph-and-its-answer-changed.jsonld"}}