读见

我们教会了 AI 回答问题,又是谁教会它改变主意?

原题We Taught AI to Answer Questions. Who Taught It to Change Its Mind?

约 25 分钟约 6,183 字原文英文已翻译

推荐理由这项状态修订实验把重算与局部更新放在同一最终目标下比较。适合智能体开发者理解依赖追踪为何会影响记忆和答案更新的可靠性。

读前速览

3 个要点

我构建了一个基准测试,用来检验 AI 系统能否在新证据出现时可靠地更新其结论。所有方法在从头计算时都拿到了 100% 的准确率,但它们修订既有状态的能力却差异巨大,一些策略无法更新关键事实,或者破坏了无关的逻辑。

  1. 六种方法在从头作答时都达到了 100% 的准确率,证明底层逻辑是可靠的。

    「从头作答」路径把最终证据和规则喂给系统,让它无论采用何种更新策略都能构建出正确的状态。这证实了问题出在更新过程,而非核心推理。

  2. 修订既有状态的能力差异显著,得分从 100% 一路跌到 0.7%。

    从旧状态进行更新时,「完全重算」和「增量修订」策略保持了完美的准确率。然而其他策略(如「浅层更新」和「激进清空」)未能正确传播变更,导致结论陈旧或产生附带损伤。

  3. 「增量修订」策略是最高效、最准确的解决方案。

    该策略追踪依赖关系,在某个事实发生变化时只更新必要的节点,在达到 100% 准确率的同时,工作量比完全重算减少了 75%。它成功规避了数据陈旧和附带损伤两个问题。

完整摘要

这项实验比较了通往同一最终状态的两种路径:从头作答与修订旧状态。我在 300 个案例上测试了六种策略,发现完全重算和增量修订保持了 100% 的准确率,而其他方法则受困于数据陈旧、附带损伤和隐蔽失败。结果凸显了追踪依赖关系对于确保一致的信念修订的重要性。

目录 · 17 节

查看原文

人工智能Artificial Intelligence

当新证据推翻一个结论时,基于该结论做出的决策也会随之改变吗?我测试了六种更新策略,然后测试了一个本地模型。When new evidence kills one conclusion, do the decisions built on it change too? I tested six update strategies, then a local model.

Emmimal P Alexander
October 31, 202626 min read
Cancelled flight icon with ripples reaching hotel and taxi icons, a calm tooth icon, a robot, and a card showing 100% falling to 0.7%.
Image by author
A cancelled flight sends a ripple through a trip. The hotel and taxi update, while the dentist appointment stays untouched. A friendly robot looks on. The 100% to 0.7% card shows the article’s result: strategies that answer correctly from scratch can fail when they must revise an old state.

我不断看到 AI 系统在状态更新上出错。它们缓存了一个答案,收到会推翻这个答案的数据后,却仍然没有更新。我想弄清楚其中的原因。I keep seeing AI systems fail at state updates. They cache an answer, receive data that breaks it, and still fail to update. I wanted to find out why.

假设一个旅行机器人预订了航班、酒店和出租车,并将行程标记为已确认。后来,航班被取消了。机器人记录了这次取消。但它会取消出租车吗?会更新酒店预订吗?它知道你的牙医预约与此无关,应该保持不变吗?Say a travel bot books a flight, hotel, and cab. It marks the trip confirmed. Later, the flight gets canceled. The bot logs the cancellation. But does it cancel the cab? Does it update the hotel? Does it know your dentist appointment is unrelated and should stay put?

更新信念很难。系统需要修改某些事实,保留其他事实,并摒弃旧有假设。在标准基准测试中答对一道题,并不能证明系统真正具备这种能力。Updating beliefs is hard. A system needs to change some facts, keep others, and drop old assumptions. Getting one answer right on a standard benchmark does not prove a system can actually do this.

我构建了 RevisionTrace 来测试它。它是一个用于信念修正的 Python 基准测试。I built RevisionTrace to test it. It is a Python benchmark for belief revision.

它通过两条不同的路径运行测试。第一条路径会预先向系统提供所有最终数据,让系统从头开始计算。第二条路径则从基线状态开始,并持续输入实时更新,迫使系统即时适应。两条路径使用相同的规则和相同的真实数据。It runs a test using two different routes. Route one gives the system all the final data upfront to calculate everything from scratch. Route two starts with a baseline state and feeds in live updates, forcing the system to adapt on the fly. Both use the same rules and the same ground truth.

我在 300 个案例中测试了六种策略,性能差距非常大。I tested six strategies across 300 cases. The performance gap was huge.

Strategy

Answering from scratch

Revising an existing state

Full recomputation

100%

100%

Incremental revision

100%

100%

History-dependent, shallow updates

100%

59%

History-dependent, sticky state

100%

57%

History-dependent, branch-first updates

100%

29%

History-dependent, aggressive flushing

100%

0.7%

等一下。在看数据之前,我们先补充一些背景。这些测试策略是我自己设计的。我这里并不是在对真实的大语言模型进行基准测试,也不是说生产环境中的 AI 恰好会失败这么多。Hold on. Let's add context before we look at the data. I built these test strategies myself. I'm not benchmarking real LLMs here. And I'm not saying production AI fails exactly this much.

真正的教训非常具体:智能体可以在记忆中保存所有正确的数据,但当某个变量发生变化时,它仍可能无法更新原有结论。记住事实很容易,管理状态变化却很难。The real lesson is highly specific. An agent can have all the right data in memory. But it can still fail to update an old conclusion when a variable changes. Remembering facts is easy. Managing state changes is hard.

RevisionTrace 只测试一件事:如果某个核心事实发生变化,系统是否会更新依赖它的逻辑?同时,是否会保持无关数据不变?RevisionTrace tests one thing. If a core fact changes, does the system update the dependent logic? And does it leave the unrelated data alone?

这篇文章介绍了这次实验、我发现的 bug,以及修复方法。所有内容都基于标准 Python 运行。不需要任何 API 密钥,也不调用任何模型。This post covers the experiment, the bugs I caught, and the fix. Everything runs on standard Python. Zero API keys. Zero model calls.

你可以在 GitHub 上找到代码:https://github.com/Emmimal/revisiontrace/

You can find the code on GitHub: https://github.com/Emmimal/revisiontrace/

主要发现概述Key findings in brief

以下是这 300 个案例的结果。你可以运行本文末尾的代码,亲自核实这些数字。Here is what the 300 cases showed. You can run the code at the end of this post to verify the numbers yourself.

  • 计算与更新:从头开始时,六种方法都获得了满分。但在更新旧状态时,准确率最低降至 0.7%。

    Calculating vs updating: All six methods got a perfect score when starting from scratch. But when updating an old state, accuracy fell as low as 0.7%.

  • 过时数据与附带损害:留下旧数据和破坏正确数据是两种不同的错误。三种方法未能更新多达 65% 的需要更改的事实。另一种方法破坏了 58% 本应保持不变的事实。

    Stale data vs collateral damage: Leaving old data and breaking good data are two different bugs. Three methods failed to update up to 65% of the facts they needed to change. A different method broke 58% of the facts it should have left alone.

  • 静默失败:错误隐藏在中间步骤中。三种方法在约五分之一的失败运行中得出了正确的最终输出。最终答案看起来没问题,但内部状态却一团糟。

    Silent failures: Bugs hide in the intermediate steps. Three methods got the final output right in about a fifth of their failed runs. The final answer looked fine, but the internal state was garbage.

  • 一致但错误:无论我如何打乱更新顺序,一种策略给出的结果都完全相同。它看起来非常稳定,但实际上只有 75% 的时候是正确的。

    Consistent but wrong: One strategy gave the exact same result no matter how I shuffled the updates. It looked perfectly stable. But it was actually right only 75% of the time.

  • 修复方法:该解决方案非常轻量。你只需跟踪依赖关系。变量发生变化时,就沿着依赖链向下传递更新,直到各个值稳定下来。这种方法得分为 100%,而且比完整重建少做了 75% 的工作。

    The fix: The solution is lightweight. You just track dependencies. When a variable changes, you push the update down the chain until the values settle. This method scored 100%. It also did 75% less work than a full rebuild.

整个架构可以用一张图完整呈现。The entire architecture fits in a single diagram.

Diagram of two routes to the same final state: Route A answers from scratch using final evidence, Route B revises from an old state, and an oracle checks both.
The same evidence, two routes to the same final state. Only route B depends on history.
A belief revision benchmark compares answering from scratch with revising stored conclusions. Route A derives every conclusion from the final evidence to reach state A. Route B starts from old conclusions, applies evidence updates and revises to state B. An oracle then checks whether each state is correct.

现有研究对语言模型中信念修正的发现What research already says about belief revision in language models

在编写任何代码之前,我先查阅了现有研究。此前已有研究人员从不同角度探讨过这个问题。Before writing any code, I checked for existing research. People have already looked at this in pieces.

Belief-R(Wilie 等人,2024)用于测试模型在获得新证据后是否会更新结论。作者测试了约 30 个模型。他们发现,模型通常无法修正自己的信念。他们还注意到一种权衡:能够成功更新的模型,在无需更新时往往会失败。这正是我在后文中衡量的附带损害。Belief-R (Wilie et al., 2024) tests if models update conclusions when new evidence arrives. The authors tested around 30 models. They found that models generally fail to revise their beliefs. They also noticed a trade-off. Models that successfully updated tended to fail when no update was needed. This is the exact collateral damage I measure later.

知识编辑研究探讨了类似的问题。MQuAKE(Zhong 等,2023)会编辑模型中的单条事实,然后提出依赖于这项改动的多步问题。模型很容易记住新事实,但在回答这些关联问题时表现很差。Knowledge editing research tackles a similar problem. MQuAKE (Zhong et al., 2023) edits a single fact inside a model. It then asks multi-step questions that rely on that change. Models easily remember the new fact. However, they fail badly on the dependent questions.

RippleEdits(Cohen 等,2024)探讨了这种相同的连锁效应。它是一个包含约 5,000 条事实编辑的诊断数据集。更改一条事实后,相关事实也应该自动随之更改。但标准编辑方法无法做到这些一致的更新。一个简单的上下文学习基线反而效果最好。RippleEdits (Cohen et al., 2024) explores this same ripple effect. It is a diagnostic set of about 5,000 factual edits. Changing one fact should automatically change related facts. But standard editing methods fail to make these consistent updates. A simple in-context baseline actually worked best.

AGM-Bench(Jenkins,2026)是与本文最接近的先前研究。它曾作为海报发表于 ICLR 2026 的一场研讨会。该研究建立在 1985 年的 AGM 信念修正理论之上。作者在七个模型上测试了 2,400 个场景。论文发现了两类主要错误:模型会保留过时的事实,作者称之为“信念惯性”;模型也会破坏无关事实,作者称之为“附带损害”。我使用了这些相同的术语,但并非由我首创。由于这是一篇研讨会论文,它仍属于早期研究。AGM-Bench (Jenkins, 2026) is the closest prior work. It was a poster at an ICLR 2026 workshop. It builds on the 1985 AGM theory of belief revision. The author tested 2,400 scenarios across seven models. The paper found two main errors. Models keep outdated facts, which they call "belief inertia." Models also break unrelated facts, which they call "collateral damage." I use these same terms, but I did not invent them. Since it is a workshop paper, it is still early research.

计算机科学几十年前就解决过类似问题。真值维护系统(Doyle,1979)会追踪每个信念的确切依据。如果某个前提发生变化,系统就会撤销依赖于该前提的信念。数据库使用增量视图维护(Gupta 等,1993)来仅更新受影响的数据。我的基准测试正是采用这一概念来修复问题。我并没有发明它。Computer science solved similar problems decades ago. Truth maintenance systems (Doyle, 1979) track the exact reason for every belief. If a premise changes, the system drops the dependent beliefs. Databases use incremental view maintenance (Gupta et al., 1993) to update only the affected data. My benchmark uses this exact concept as the fix. I did not invent it.

以下是这项研究的具体构成:Here is how the research breaks down:

Work

Core Question

Subject Tested

Belief-R (2024)

Do models update conclusions when facts change?

~30 language models

MQuAKE (2023)

Does one edited fact update multi-hop answers?

Model-editing methods

RippleEdits (2024)

Do related facts update consistently after an edit?

Model-editing methods

AGM-Bench (2026)

Do models follow rational revision rules?

Seven language models

RevisionTrace (Here)

Does a fix reach every dependent fact and nothing else?

Six revision strategies

我的贡献非常具体。我在完全相同的数据上并行运行从头构建流程和更新流程,并在一次运行中追踪过时错误和附带损害。我只是想看看一次成功更新的具体机制。My contribution is highly specific. I run the scratch-build path and the update path side by side on the exact same data. I track stale errors and collateral damage in a single run. I just want to see the mechanics of a successful update.

如果你想了解真实语言模型的基准测试,请阅读上面的论文。我的实验只测试底层的更新逻辑。If you want benchmarks on real language models, read the papers above. My experiment strictly tests the underlying update logic.

我如何构建这个实验:依赖图、三值逻辑和一个预言机How I built the experiment: a dependency graph, three-valued logic and an oracle

我用依赖图、三态逻辑和预言机搭建了这套方案。各个部分都很小,但组合起来,就能让故障一目了然。I built the setup using a dependency graph, three-state logic, and an oracle. The pieces are small. Together, they make failures obvious.

图的运作方式如下:事实推动结论,结论推动其他结论,最终端点是决策。Here is how the graph works. Facts drive conclusions. Conclusions drive other conclusions. The final endpoints are decisions.

每个节点都会对其输入应用一条简单的逻辑规则,使用 AND、OR 或 k-of-n 逻辑。我还在每张图中都添加了一个独立分支,以便检查局部更新是否意外破坏了无关逻辑。Every node applies a simple logic rule to its inputs. It uses AND, OR, or k-of-n logic. I also added an isolated branch to every single graph. This lets me check if a local update accidentally breaks unrelated logic.

一个典型的图谱大约使用 10 条事实来推导 12 个结论。逻辑链的深度为两到五层。A typical graph uses about 10 facts to calculate 12 conclusions. The logic chains run two to five layers deep.

Dependency graph where facts F1 to F4 feed conclusions C1 and C2, which feed the decision C3 through AND and OR rules.
A made-up example of the structure. Real cases are larger.
A small dependency graph with three columns: facts, conclusions and a decision. C1 is AND of F1 and F2. C2 is OR of F3 and F4. The decision C3 is AND of C1 and C2. Real benchmark cases use the same structure with about 12 conclusions.

每个节点的状态都是 TRUE、FALSE 或 UNKNOWN。我采用了克莱尼三值逻辑。只要任一输入为 FALSE,AND 门就是 FALSE。只有所有输入都为 TRUE 时,AND 门才是 TRUE。其他情况下,它都是 UNKNOWN。OR 门的规则正好相反。对于 k-of-n 规则,如果至少有 k 个输入为 TRUE,则结果为 TRUE。如果把每个 UNKNOWN 都算作 TRUE 后仍达不到目标,则结果为 FALSE。其他情况下,结果保持 UNKNOWN。这一点很重要。“我不知道”是一种有效状态。拒绝承认这一点的系统终将失败。Every node is TRUE, FALSE, or UNKNOWN. I used Kleene's three-valued logic. An AND gate is FALSE if any input is FALSE. It is TRUE only if all inputs are TRUE. Otherwise, it is UNKNOWN. An OR gate works the opposite way. A k-of-n rule is TRUE if at least k inputs are TRUE. It is FALSE if counting every UNKNOWN as TRUE still misses the target. Otherwise, it stays UNKNOWN. This is important. "I do not know" is a valid state. Systems that refuse to say it will fail.

证据以主张的形式出现。一次更新要么添加一项主张,要么撤回一项主张。每项主张都有一个值和一个优先级。事实的值取自优先级最高的主张。如果优先级最高的主张并列但彼此矛盾,该事实就变为 UNKNOWN。如果某个事实没有任何有效主张,它也会变为 UNKNOWN。撤回是永久性的。最终状态只取决于最终的主张列表。更新的顺序无关紧要。这就是随机打乱测试能够奏效的原因。Evidence comes in as claims. An update either adds or removes a claim. Each claim has a value and a rank. A fact takes the value of its highest-ranked claim. If the top claims tie but disagree, the fact becomes UNKNOWN. If a fact has no active claims, it is also UNKNOWN. Retractions are permanent. The final state only depends on the final list of claims. The order of updates does not matter. This is why the shuffle test works.

预言机根据最终证据计算真实值。我将它与测试策略分开构建。它采用严格的克莱尼逻辑。每次测试运行前,都会通过 5,000 次随机逻辑检查,验证预言机与这些策略是否一致。The oracle calculates the ground truth from the final evidence. I built it separately from the test strategies. It uses strict Kleene logic. Before every test run, a self-test verifies the oracle against the strategies using 5,000 random logic checks.

我将每个结论分别与其旧值、oracle 的预期值以及系统的新值进行比较。这样可以揭示五种错误。I compare each conclusion against its old value, the oracle's expected value, and the system's new value. This exposes five types of errors.

Error

Meaning

Stale

Should have changed, but kept the old value.

Collateral

Should have stayed the same, but changed.

Wrong direction

Changed, but to the wrong value.

False resolution

Should be UNKNOWN, but picked TRUE or FALSE.

Hidden damage

Internal nodes failed, but final decisions were right.

只有每个节点都与测试预言机匹配时,案例才算通过。由于 300 个案例的样本量较小,我使用 95% Wilson 置信区间计算最终得分。A case only passes if every single node matches the oracle. I use 95% Wilson confidence intervals for the final scores because 300 cases is a small sample size.

更新已存储结论的六种方式Six ways to update a stored conclusion

我测试了六种更新缓存结论的方法。每种方法都从完美的初始状态开始。然后,我逐条向它们提供更新。其中两种是标准技术,另外四种是我故意设计来失败的。每种失败模型都只违反一条规则。I tested six ways to update a cached conclusion. Every method starts with a perfect initial state. Then I feed them updates one by one. Two methods are standard techniques. I built the other four to fail on purpose. Each failure model breaks just one rule.

Strategy

How it works

Type

Full recomputation

Calculates everything from scratch after every update.

Correct by design

Incremental revision

Updates only the downstream nodes. Stops when values settle.

Correct by design

Shallow updates

Only touches the changed fact and its immediate neighbors.

Failure model

Branch-first updates

Cascades properly but only follows the first branch it sees.

Failure model

Sticky state

Cascades properly but refuses to change a firm answer back to UNKNOWN.

Failure model

Aggressive flushing

Wipes everything to UNKNOWN. Only recalculates nodes downstream of the change.

Failure model

前两种方法是可靠的基准方案。它们在设计上就能通过所有测试。测试套件验证了这两种方法在全部 300 个用例中都与预言机的结果一致。它还证明,所有六种方法在从头计算时都能完美运行。The first two methods are solid baselines. They pass every single test by design. The test suite verifies that both match the oracle on all 300 cases. It also proves that all six methods work perfectly when calculating from scratch.

我构建了四种故障模型,用来模拟现实世界中的 bug。浅层更新就像只检查即时笔记的智能体。状态粘滞就像拒绝丢弃旧假设的缓存。激进刷新模拟了硬重置后再懒散地重建。分支优先更新则像忽略并行路径的流水线。这些都只是对代码的类比。我并不是在指名批评任何特定产品。I built the four failure models to mimic real-world bugs. Shallow updates act like an agent that only checks immediate notes. Sticky state acts like a cache that refuses to drop an old assumption. Aggressive flushing mimics a hard reset followed by a lazy rebuild. Branch-first updates act like a pipeline that ignores parallel paths. These are just analogies for the code. I am not calling out specific products.

这 300 个测试用例涵盖六种不同的场景。我使用固定种子为每个类别生成了 50 个用例。代码会在每个用例创建时严格验证,确保它确实测试了预期的逻辑。The 300 test cases cover six different scenarios. I generated 50 cases for each category using a fixed seed. The code strictly verifies every case upon creation to ensure it actually tests the intended logic.

Category

What must happen

Single fact change

Everything that depends on the fact is reconsidered

Multi support

A conclusion with several supports changes only when its remaining support is not enough

Shared dependency

Two branches that share one fact are both revised

Conflicting evidence

An equal-rank contradiction leaves the fact unresolved, or higher-ranked evidence settles it

Unrelated change

A change in the side branch leaves the main graph alone

Multi update

Four to eight updates in a row, some added and later retracted, with no obsolete conclusion surviving

结果:从头作答时为 100%,修改时为 0.7%Result: 100% when answering from scratch, 0.7% when revising

以下是结果:从头开始时达到 100%,但更新时低至 0.7%。Here are the results: 100% from scratch, but as low as 0.7% on updates.

第一部分很简单。每种策略从头开始都能完美运行。能否得到正确答案只取决于数据。将最终事实和规则输入任何一种方法,它都会构建出正确的状态。即使是在更新任务中得分只有 0.7% 的方法,在这里也能拿到满分。The first part is easy. Every strategy works perfectly from scratch. Getting the right answer just depends on the data. Feed any of these methods the final facts and the rules, and it builds the correct state. Even the method that scores 0.7% on updates gets a perfect score here.

真正让它们表现不同的是更新操作。证据相同,规则相同,逻辑也完全一致。唯一的区别在于起点不同:一个从零开始构建,另一个则修改已有状态。这个基准测试隔离出了更新逻辑的确切影响。请记住,现实中的语言模型未必能如此清晰地区分推理和记忆。The updates are what break them. The evidence is the same. The rules are the same. The logic is identical. The only difference is the starting point. One builds from nothing. The other modifies an existing state. This benchmark isolates the exact effect of the update logic. Keep in mind, real language models might not separate reasoning and memory this cleanly.

Bar chart: all six strategies score 100% answering from scratch, but revising from an old state ranges from 100% down to 0.7%.
The same six strategies, scored two ways on the same final evidence.
Exact final-state agreement over 300 seeded cases. Every strategy answers correctly from scratch. When revising from a stored state, full recomputation and incremental revision score 100%, shallow updates 59%, sticky state 57%, branch-first updates 29% and aggressive flushing 0.7%.

我们来看看这 300 个案例的总体得分。两种正确策略都达到了 100%。浅层方法的得分在 53% 到 64% 之间。粘滞方法的得分在 51% 到 63% 之间。分支优先方法则降至 24% 到 34%。刷新方法基本上彻底失败,得分不到 3%。请记住,这些区间只衡量了我的特定测试样本,并不能预测现实世界中的 AI 失败率。Let's look at the overall scores across the 300 cases. The two correct strategies hit 100%. The shallow method scored between 53% and 64%. The sticky method scored 51% to 63%. Branch-first dropped to 24% to 34%. The flush method basically failed completely, scoring under 3%. Remember, these intervals just measure my specific test sample. They do not predict real-world AI failure rates.

正确的方法在每项测试中都表现出色,因此我没有将它们列入下表。以下是四种失败模型在六个类别中的得分。每个类别均运行了 50 次。The correct methods aced every test, so I left them out of the table below. Here is how the four failure models scored across the six categories. Each category ran 50 times.

Category

Shallow

Sticky

Branch-first

Flush

Single fact change

40%

54%

10%

0%

Multi support

72%

84%

58%

2%

Shared dependency

54%

46%

6%

2%

Conflicting evidence

52%

28%

36%

0%

Unrelated change

84%

66%

34%

0%

Multi update

52%

64%

30%

0%

有三种模式显而易见。Three patterns are obvious.

首先,分支优先策略在共享依赖场景下表现不佳,得分仅为 6%。当一个事实会影响多条路径时,就会出现这种情况。代码只会更新它遇到的第一条路径,而忽略其余路径。First, branch-first fails on shared dependencies. It scored just 6%. This happens when one fact feeds multiple paths. The code only updates the first path it sees and ignores the rest.

其次,sticky 在证据相互矛盾时表现不佳,得分为 28%。证据冲突时,正确答案是 UNKNOWN。这种方法却不愿退回到该状态。Second, sticky fails on conflicting evidence. It scored 28%. When evidence conflicts, the correct answer is UNKNOWN. This method refuses to drop back to that state.

第三,对于互不相关的更改,shallow 表现最好,得分为 84%。侧分支规模小、长度短。一次惰性的一跳更新实际上就能到达末端。Third, shallow does best on unrelated changes. It scored 84%. The side branch is small and short. A lazy one-hop update can actually reach the end.

图深度会明显损害浅层策略。其准确率从深度为 2 时的 70.5% 降至深度为 5 时的 44.4%。每增加一层,一跳更新就多了一次提前停止的机会。粘性策略则不受深度影响,其得分只是上下波动。每种深度的样本量实在太小,无法体现出真正的趋势。Graph depth actively hurts the shallow strategy. Its accuracy drops from 70.5% at a depth of two down to 44.4% at a depth of five. Every extra layer is another chance for a one-hop update to stop early. The sticky strategy does not care about depth. Its scores just bounce around. The sample size for each depth is simply too small to show a real trend.

最小的失败:一个过时的结论The smallest failure: one stale conclusion

原始数字掩盖了真正的错误。我们来看看我发现的最小且干净的失败案例。Raw numbers hide the actual bugs. Let's look at the smallest clean failure I found.

它来自一个总共有 18 个结论的测试用例。我们只需要关注其中一个包含三个事实的小角落。It comes from a test case with 18 total conclusions. We only need to look at a small three-fact corner.

事实 F6、F7 和 F8 初始为 TRUE。系统根据它们推导出两个结论。Facts F6, F7, and F8 start out TRUE. The system calculates two conclusions from them.

首先,C14 要求这三个事实全部为 TRUE。既然它们都为 TRUE,C14 的结果就是 TRUE。其次,C17 要求 C14 和 F8 均为 TRUE。它的结果也为 TRUE。First, C14 needs all three facts to be TRUE. Since they are, C14 resolves to TRUE. Second, C17 needs both C14 and F8 to be TRUE. It also resolves to TRUE.

随后,一条新的更新覆盖了 F6,将 F6 设置为 FALSE。Then a new update overrides F6. It sets F6 to FALSE.

正确的系统会更新这两个节点。C14 依赖 F6,因此会变为 FALSE。C17 依赖 C14,因此也会变为 FALSE。A correct system updates both nodes. C14 relies on F6, so it drops to FALSE. C17 relies on C14, so it drops to FALSE too.

浅层策略修复了 C14,但过早停止。C17 错误地仍为 TRUE。缓存数据现在已过时。The shallow strategy fixes C14 but stops early. C17 wrongly stays TRUE. The cached data is now stale.

Table of facts F6, F7, F8 and conclusions C14 and C17 before and after F6 becomes FALSE, with C17 left stale as TRUE.
Case unrelated_change-003 from the seed 2026 run.
A stale conclusion in a belief revision test. When F6 becomes FALSE, the shallow update strategy correctly changes C14 but leaves C17, which depends on C14, at TRUE. The oracle says C17 should be FALSE.

基本逻辑没有问题。如果把最终数据交给浅层方法,让它从头计算 C17,它会正确地回答 FALSE。这个 bug 完全出在更新过程中。系统修正了紧挨着新事实的节点,却始终没有检查下游节点。The basic logic is fine. If you give the shallow method the final data and ask it to calculate C17 from scratch, it correctly answers FALSE. The bug lives entirely in the update process. The system fixed the node right next to the new fact. It just never checked the downstream nodes.

这完美地说明了核心问题。一个结论发生了变化。依赖于它的结论却保持不变。想想一个真实的智能体。C14 是航班取消,C17 是“行程已确认”状态。This perfectly illustrates the core problem. One conclusion changed. The conclusion relying on it stayed the same. Think of a real agent. C14 is the canceled flight. C17 is the "trip confirmed" status.

本次测试中其余16个结论都是正确的。只检查距离更新最近节点的基准测试会判定这次运行通过。正因如此,我才会对图中的每一个节点逐一评分。The other 16 conclusions in this test were correct. A benchmark that only checks the node closest to the update would pass this run. That is exactly why I score every single node in the graph.

过时的结论与附带损害:两种犯错方式Stale conclusions vs collateral damage: two ways to be wrong

数据过时只是故障的一种。附带损害则是另一种。只关注数据过时的基准测试会完全忽略这一点。Stale data is just one type of failure. Collateral damage is the other. A benchmark looking only for stale data will completely miss it.

以 shared_dependency-048 为例。五个事实初始均为 TRUE。F4 初始为 FALSE。随后,一次新的更新将 F4 切换为 TRUE。Take case shared_dependency-048. Five facts start TRUE. F4 starts FALSE. Then a new update flips F4 to TRUE.

刷新策略将其视为一次蛮力缓存清除操作。它会将每个节点都重置为 UNKNOWN,然后只重建 F4 下游的节点。这条特定路径运行得非常理想。C1 和 C3 变为 TRUE。C0 和 C4 保持 TRUE。The flush strategy treats this like a brute-force cache wipe. It resets every single node to UNKNOWN. Then it rebuilds only the nodes downstream of F4. This specific path works perfectly. C1 and C3 flip to TRUE. C0 and C4 stay TRUE.

但另外两个节点与 F4 没有任何连接。C2 查看 F1、F2 和 F0。这三个都为 TRUE,因此 C2 应保持为 TRUE。C5 查看 C2、F1 和 F0。它也应保持为 TRUE。But two other nodes have zero connection to F4. C2 looks at F1, F2, and F0. All three are TRUE, so C2 should stay TRUE. C5 looks at C2, F1, and F0. It should also stay TRUE.

由于这两个节点都不依赖 F4,重建脚本便忽略了它们。两个节点都一直卡在 UNKNOWN 状态。系统虽然成功更新了正确的信息,却在此过程中破坏了原本完好的数据。Since neither node depends on F4, the rebuild script ignores them. Both nodes stay stuck at UNKNOWN. The system successfully updated the right facts, but it destroyed perfectly good data in the process.

Table showing the flush strategy correctly updating C1 and C3 but wrongly setting C2 and C5 to UNKNOWN.
Case shared_dependency-048. The first two rows were revised correctly. The last two were damaged.
Collateral damage after a correction. The flush strategy wipes every stored conclusion to UNKNOWN, then refills only the conclusions that depend on F4. C2 and C5 never depended on F4, so they stay UNKNOWN when they should still be TRUE.

我把第一种错误称为状态陈旧:某个值本应改变,却没有改变。我把第二种错误称为附带损害:某个值本应保持不变,却被破坏了。以下是这两种错误在全部 300 个案例中的表现。I call the first error a stale state. A value needs to change, but it does not. I call the second error collateral damage. A value should stay the same, but it breaks. Here is how both bugs played out across all 300 cases.

Bar chart of stale and collateral rates: branch-first is 65.4% stale, while flush is 2.0% stale but 58.0% collateral.
Stale and collateral rates for the four failure models. The correct strategies scored 0% on both.
Two ways to be wrong when revising. Stale means a conclusion that should change did not. Collateral means a conclusion that should stay changed. Shallow is 33.1% stale, sticky 42.1%, branch-first 65.4%. Flush is 2.0% stale but damages 58.0% of conclusions that should stay.

看看刷新策略。如果只检查过期数据,它似乎比浅层方法好得多。其过期数据仅占 2.0%,而浅层方法为 33.1%。Look at the flush strategy. If you only check for stale data, it seems much better than the shallow method. It leaves just 2.0% stale compared to 33.1%.

但实际上,它的总体得分是最低的。为什么?因为它彻底破坏了无关数据。其他三种方法几乎从不触及无关事实。它们之所以失败,是因为留下了旧数据。But it actually has the worst overall score. Why? It completely destroys the unrelated data. The other three methods almost never touch unrelated facts. They fail because they leave old data behind.

这证明,询问“答案有没有变化?”不是一个好的测试。你必须问两个问题:受影响的数据是否发生了变化?无关数据是否完全保持不变?This proves that asking "did the answer change?" is a bad test. You have to ask two questions. Did the affected data change? Did the unrelated data stay exactly the same?

只有依赖项跟踪器通过了这两项测试。Only the dependency tracker passes both tests.

隐而不显的失败:正确的决策,错误的理由Failures that hide: right decisions, wrong reasons

还有两个统计数据说明了漏洞是如何隐藏起来的。Two more stats show how bugs stay hidden.

首先是隐性损害。在每次测试失败时,我都会检查最终决策是否仍然正确。决策是一个最终的终端节点。对于会留下陈旧数据的三种方法,大约五分之一的失败案例中,最终输出是正确的。最终答案没问题,但内部状态已经出错。First, hidden damage. In every failed test, I checked if the final decisions were still correct. A decision is a final endpoint node. For the three methods that leave stale data, the final output was right in about one out of five failures. The final answer was fine, but the internal state was broken.

这是个大问题。如果你只测试最终输出,这些错误就会蒙混过关。想象一下,“行程已确认”标记是正确的,但内部的“酒店已预订”备注却是错的。下次系统检查酒店时,就会失败,而你完全不会收到任何警告。This is a massive problem. If you only test the final output, you pass these bugs. Imagine the "trip confirmed" flag is correct, but the internal "hotel booked" note is wrong. The next time the system checks the hotel, it fails. You get absolutely no warning.

第二,错误判定。在整个测试套件中,526 个节点应判定为 UNKNOWN。错误的策略却强行判定为 TRUE 或 FALSE。Second, false resolution. Across the whole test suite, 526 nodes should resolve to UNKNOWN. A bad strategy forces a TRUE or FALSE anyway.

Strategy

Failed runs

Failed but decisions correct

Forced an answer when UNKNOWN

Shallow updates

123

23 (18.7%)

103 (19.6%)

Branch-first updates

213

34 (16.0%)

209 (39.7%)

Sticky state

129

29 (22.5%)

302 (57.4%)

Aggressive flushing

298

5 (1.7%)

0 (0%)

仔细看看这种固守策略。它拒绝放弃已确认的判断。证据相互矛盾时,真实状态是 UNKNOWN。固守策略却只是继续沿用旧答案。它没有造成任何方向性错误。造成的连带损害几乎为零(0.1%)。如果你只检查答案是否错误,它看起来简直完美。Look closely at the sticky strategy. It refuses to drop a confirmed belief. When evidence conflicts, the true state is UNKNOWN. The sticky method just keeps its old answer instead. It made zero wrong-direction errors. It caused almost zero collateral damage (0.1%). If you only check for wrong answers, it looks perfect.

这种情况在生产环境中很常见。一个可信来源被撤回后,正确的状态就变成了“我们不知道”。如果系统拒绝承认这一点,就会基于已经失效的数据表现出自信。You see this in production all the time. A trusted source gets retracted. The correct state becomes "we do not know." A system that refuses to say that will project confidence based on dead data.

flush 方法恰好相反。它会激进地默认采用 UNKNOWN。它绝不会错误地作出判定,但会抹掉太多数据,导致最终决策几乎总是失效。The flush method does the exact opposite. It defaults to UNKNOWN aggressively. It never commits falsely, but it wipes out so much data that the final decisions almost always break.

更新顺序重要吗?稳定并不等于正确。Does update order matter? Stable is not the same as correct

更新的顺序不应改变结果。最终证据是相同的。The order of updates should not change the result. The final evidence is the same.

我选取了有多次更新的 133 个测试用例。每个用例的更新顺序最多打乱五次。我关注两件事:系统每次是否都达到了完全相同的状态?而这个状态是否确实正确?I took the 133 test cases that had multiple updates. I shuffled the update sequence up to five times per case. I looked for two things. Did the system reach the exact same state every time? And was that state actually correct?

Strategy

Same state every time

Correct state every time

Full recomputation

100%

100%

Incremental revision

100%

100%

Shallow updates

88.0%

48.9%

Sticky state

97.7%

75.2%

Branch-first updates

87.2%

28.6%

Aggressive flushing

66.2%

0.8%

以下是发生顺序故障的过程。案例 multi_update-004 收到四次更新。F2 获得一项断言,随后又失去它。F3 失去一项旧断言。F0 降为 FALSE。最终证据表明 F2 和 F3 均为空。真实结果预期节点 C3 从 TRUE 降为 UNKNOWN。Here is how an order failure happens. Case multi_update-004 gets four updates. F2 gets a claim, then loses it. F3 loses an old claim. F0 drops to FALSE. The final evidence leaves F2 and F3 empty. The ground truth expects node C3 to drop from TRUE to UNKNOWN.

我用两种不同的更新顺序运行了浅层方法。第一种顺序下,C3 一直卡在 TRUE。第二种顺序下,C3 正确地变成了 UNKNOWN。最终数据完全相同。仅仅是到达历史导致了这个错误。I ran the shallow method using two different update orders. In the first order, C3 stayed stuck at TRUE. In the second order, C3 correctly dropped to UNKNOWN. The final data was identical. The arrival history alone caused the bug.

再看一下粘滞策略。它在 98% 的运行中都到达了完全相同的状态。但它只有 75% 的时候是正确的。如果你只衡量一致性,这种方法看起来非常出色。它非常稳定。但大约每五次中就有一次,它每次都会以同一个错误状态结束。Look at the sticky strategy again. It reached the exact same state in 98% of the runs. But it was only correct 75% of the time. If you only measure consistency, this method looks amazing. It is highly stable.But in about one case in five, it ends in the same wrong state every time.

测试更新顺序的成本极低。你只需打乱输入,重新运行测试,然后比较输出。如果最终状态不同,就说明存在 bug。甚至不需要预言机也能发现它。Testing update order is incredibly cheap. You just shuffle the inputs, replay the test, and compare the outputs. If the final states differ, you have a bug. You do not even need an oracle to find it.

是谁教会它改变主意的?是什么让修订奏效?Who taught it to change its mind? What makes revision work

这篇文章的标题提出了一个问题:究竟是什么让修改奏效?数据给出了答案。The title of this piece asks a question. What actually makes revision work? Here is the answer from the data.

我想准确找出致胜策略成功的关键所在。因此,我对正确的增量方法加以限制,严格规定一次更新最多能从发生变化的事实传播多远。I wanted to isolate exactly what makes the winning strategy succeed. So I took the correct incremental method and restricted it. I put a hard limit on how far an update could travel from a changed fact.

在跳数为零时,系统只记录新证据,完全忽略已存储的结论。它会变成一个只追加的日志。它可以回答新问题,但无法修正旧问题的答案。At zero hops, the system just records the new evidence. It ignores stored conclusions entirely. It becomes an append-only log. It can answer new questions, but it cannot revise old ones.

跳数限制为 1 时,它只会更新直接下游邻居。我逐步提高跳数上限,直到完全取消限制。At one hop, it only updates the immediate downstream neighbors. I kept increasing this hop limit step by step until there was no cap at all.

Bar chart: exact agreement rises from 8.0% at zero hops to 100% at four hops, while work per update stays near 5 node evaluations.
Same 300 cases, same machinery. Only the reach of a correction changes. Work is node evaluations per update.
An ablation on incremental revision that limits how many hops a correction can travel through the dependency graph. Exact agreement is 8.0% at zero hops, 59.0% at one, 90.3% at two, 99.3% at three and 100% at four. Work per update rises from 1.0 to 5.2 node evaluations.

有三点尤为突出。Three things stand out.

首先,零跳数仍然得分为 8.0%。在这些运行中,这次更新实际上并未改变最终结果。如果新数据最终证明无关,那么一个拒绝更新的系统也可能通过测试。基准测试设计者需要对此保持警惕。First, zero hops still scored 8.0%. In these runs, the update did not actually alter the final outcome. A system that refuses to update can pass a test if the new data turns out to be irrelevant. Benchmark designers need to watch out for this.

其次,一跳正是浅层策略。它的得分为 59.0%,每次更新进行了 3.7 次评估。我写的浅层失败模型,就是正确修复方案的一跳版本。Second, one hop is exactly the shallow strategy. It scored 59.0% and used 3.7 evaluations per update. The shallow failure model I wrote is just the one-hop version of the correct fix.

第三,准确率会随着覆盖范围扩大而提高。两跳时得分跃升至 90.3%。三跳时达到 99.3%。四跳时达到完美的 100%。在这些运行中,四跳始终足够。Third, accuracy scales with reach. The score jumps to 90.3% at two hops. It reaches 99.3% at three. It hits a perfect 100% at four hops. In these runs, four hops were always enough.

计算成本呈现出这种模式。完整重建每次更新需要 21.9 次评估。增量修订需要 5.2 次。它只用四分之一的工作量就取得了满分。Compute costs match this pattern. A full rebuild takes 21.9 evaluations per update. Incremental revision takes 5.2. It gets a perfect score with a quarter of the work.

有缺陷的模型耗用了 2.5 到 7.1 次评估。刷新所消耗的算力比正确的增量修复更多,却仍然彻底失败。有缺陷的策略并不一定更省成本。浅层方法之所以快,只是因为它们跳过了必要的工作。The broken models took between 2.5 and 7.1 evaluations. Flushing used more compute than the correct incremental fix and still failed completely. A broken strategy is not automatically cheaper. The shallow methods are only fast because they skip the required work.

那么,究竟是什么让一个系统成功改变主意?你只需要做两件事。第一,梳理依赖关系。第二,应用严格的传播规则。更新下游节点,并在数值不再变化时立即停止。So what actually makes a system successfully change its mind? You just need two things. First, map the dependencies. Second, apply a strict propagation rule. Update the downstream nodes and stop the moment the values stop changing.

没有依赖关系图,就无法找到下游节点。没有停止规则,你要么过早停止,留下过时数据;要么清空所有内容,造成附带损害。Without the dependency map, you cannot find the downstream nodes. Without the stopping rule, you either quit early and leave stale data, or you wipe everything and cause collateral damage.

同一批案例上的小型本地模型:Gemma 3 4B 的表现A small local model on the same cases: what Gemma 3 4B did

到目前为止,所有测试都只使用了纯代码。但标题里提到了 AI,所以我用完全相同的测试跑了一个小型本地模型。先明确一下范围:这只是一个模型、一次运行,以及部分数据。请把它看作边界测试,而不是语言模型的通用基准测试。Everything so far used pure code. But the title mentions AI. So I ran a small local model through the exact same test. Let me set clear bounds here. This is one model, one run, and a subset of the data. Think of this as a boundary test, not a universal benchmark for language models.

我通过 Ollama 在本地运行了 Gemma 3 4B。没有进行任何 API 调用。我将温度硬编码为 0,并固定了随机种子。我只测试了 66 个案例。我筛掉了结论超过八条的图。完整的图对于 4B 模型来说实在太大,难以消化。I ran Gemma 3 4B locally via Ollama. Zero API calls. I hardcoded the temperature to 0 and fixed the seed. I only tested 66 cases. I filtered out any graph with more than eight conclusions. The full graphs were simply too large for a 4B model to digest.

我针对每个案例用三种不同的方式提示了模型:I prompted the model three different ways per case:

  • 答案:仅提供最终证据。从头开始构建。

    Answer: Final evidence only. Build it from scratch.

  • 修订:旧证据、旧结论和新更新。

    Revise: Old evidence, old conclusions, and the new updates.

  • 根据提示进行修订:旧证据、旧结论、新更新,以及需要更新的节点清单。

    Revise with hint: Old evidence, old conclusions, new updates, plus a direct list of which nodes needed updating.

我还测试了一个完全不做任何事的基线。它只是保留旧状态。如果模型连什么都不做都比不过,那它的修订逻辑就毫无价值。I also ran a baseline that does absolutely nothing. It just keeps the old state. If the model cannot beat doing nothing, its revision logic has no value.

该模型在基本逻辑方面表现不佳。从头开始计算时,它在单个节点上的准确率仅为 58.6%。471 个节点中,有 66 个应标记为 UNKNOWN。模型却在其中 62 个节点上错误地强行判定为 TRUE 或 FALSE。The model struggled with the basic logic. Calculating from scratch, it only hit 58.6% accuracy on individual nodes. Out of the 471 total nodes, 66 should have been UNKNOWN. The model incorrectly forced a TRUE or FALSE on 62 of them.

只有每个节点都正确,测试用例才算通过。节点准确率具有误导性:系统的节点得分可能很高,但几乎每个完整用例都无法通过。我仅将下面的静态基线视为对照组。A test case only passes if every single node is right. Node accuracy is misleading. A system can get a high node score but fail almost every full case. I treat the static baseline below purely as a control group.

Bar chart of conclusion accuracy for Gemma 3 4B: copy-stored 79.4%, revise 77.3%, from scratch 58.6% and strict hint 52.0%.
Share of individual conclusions right, Gemma 3 4B on 66 small cases.
A local language model run through Ollama on 66 cases with eight or fewer conclusions. A baseline that only copies stored conclusions scores 79.4%. The model scores 77.3% revising, 77.1% with a dependency hint and carry scoring, 58.6% answering from scratch and 52.0% with strict hint scoring.

Row (66 cases)

Exact

Conclusions right

Stale

Collateral

Wrong direction

Copy stored, never revise

12.1%

79.4%

100%

0%

0

Revise

16.7%

77.3%

81.4%

7.0%

2

Revise with hint (carry)

13.6%

77.1%

72.2%

7.0%

12

Revise with hint (strict)

7.6%

52.0%

72.2%

38.5%

12

有三件事尤为突出。Three things stood out.

首先,说到结论,什么都不做反而胜过模型。模型的每一项得分都不高于79.4%的复制基线。First, on conclusions right, doing nothing beat the model. Every model row scored at or below the 79.4% copy baseline.

其次,这条提示只是改变了错误类型。过时错误从 81.4% 降至 72.2%。但方向错误从 2 个跃升至 12 个。模型处理了更多节点,但算出了错误的值。Second, the hint just changed the type of error. Stale errors dropped from 81.4% to 72.2%. But wrong-direction errors jumped from 2 to 12. The model touched more nodes, but it calculated the wrong values.

第三,模型连基本的格式要求都没做到。它直接漏掉了 118 条被要求复制过来的结论。为了给这次运行评分,我不得不应用一条严格规则,把这些值保留下来。我同时报告两个数字,因为丢失数据确实是个严重问题。Third, the model failed basic formatting. It simply dropped 118 conclusions it was told to copy over. I had to apply a strict rule to carry those values forward just to score the run. I report both numbers because dropping data is a real failure.

精确匹配分数只是噪声。我们看到的是 66 个案例中有 9 个或 11 个正确。The exact match scores are just noise. We are looking at 9 or 11 correct cases out of 66.

结论是:提示能告诉模型该看哪里,却不能教会它如何计算。这个模型连基本的推导都做不好。如果一个系统连状态都算不出来,就无法测试它更新状态的能力。Here is the takeaway. A hint shows the model where to look. It does not teach it how to compute. This model failed at basic derivation. You cannot test a system's ability to update a state if it cannot calculate the state in the first place.

这就是纯 Python 测试很重要的原因。它们将更新逻辑隔离出来。每种代码策略都从完美状态开始。要在 LLM 上正确测试这一点,我们需要一个从零开始就能达到 100% 的模型。我还没跑过这样的模型。This is why the pure Python tests matter. They isolate the update logic. Every code strategy starts with a perfect state. To test this properly on an LLM, we need a model that hits 100% from scratch. I have not run one yet.

这项实验未能说明什么What this experiment does not show

我需要明确说明这项测试的局限性。标题很醒目,但数据针对性很强。I need to be clear about the limits of this test. The title is bold, but the data is highly specific.

首先,这不是大型语言模型(LLM)基准测试。这六种策略只是 Python 代码,并不是 AI 模型。在从零构建的版本中获得满分,只是代码设计的一个特点。First, this is not an LLM benchmark. The six strategies are just Python code. They are not AI models. Getting a perfect score on the scratch build is just a feature of the code design.

其次,故障模型是我自己构建的。它们的错误率只是反映了我对它们的编程方式。flush 方法会破坏 58% 的数据,因为我把它硬编码成了清空所有数据。我不知道生产环境中的智能体是否真的会这样运行。Second, I built the failure models myself. Their error rates just reflect how I programmed them. The flush method destroys 58% of the data because I hardcoded it to wipe everything. I do not know if production agents actually behave this way.

第三,逻辑完全是符号化的。图规模很小。变量严格限定为 TRUE、FALSE 或 UNKNOWN。真实数据往往杂乱无章。要从原始文本中提取出清晰的依赖关系图,是一个极其困难的问题。这个基准测试完全忽略了这一问题。Third, the logic is purely symbolic. The graphs are small. Variables are strictly TRUE, FALSE, or UNKNOWN. Real data is messy. Extracting a clean dependency map from raw text is an incredibly hard problem. This benchmark ignores that problem completely.

第四,样本量较小,共使用了 300 个案例。我报告了 95% 的 Wilson 置信区间,并未对置信区间重叠的组别之间的模式作过度解读。Fourth, the sample size is small. It uses 300 cases total. I report 95% Wilson confidence intervals, and I did not read patterns into groups where the intervals overlap.

第五,一个随机种子只能代表一个快照。我又测试了三个随机种子,以验证这些数字。正确方法仍保持在 100%。失败率在一定范围内波动(浅层:55.3% 至 60.7%;分支优先:25.7% 至 33.3%;冲刷:0.7% 至 1.3%),整体模式没有变化。Fifth, one random seed is just a snapshot. I tested three more seeds to verify the numbers. The correct methods stayed at 100%. The failure rates moved within a range (shallow 55.3% to 60.7%, branch-first 25.7% to 33.3%, flush 0.7% to 1.3%), and the pattern did not change.

仓库中包含一个名为 llm_eval.py 的脚本。它使用完全相同的 oracle 测试本地模型。我之前分享过一次运行结果:它用 66 个小型案例测试了一个小模型。请将其视为边界测试,而不是对语言模型的广泛论断。The repo includes a script called llm_eval.py. It tests a local model against the exact same oracle. I shared one run earlier. It tested one small model on 66 small cases. Treat that as a boundary test, not a broad claim about language models.

我们必须在这里划清界限。在这个受控基准测试中,计算答案和更新状态是两种彼此独立的能力。它精准地揭示了更新过程是如何出错的。但这并不能证明真实的大语言模型也会以完全相同的方式失败。若想了解这方面的证据,请阅读 Belief-R 和 AGM-Bench 的论文。它们确实对模型进行了测试。We must draw a hard line here. In this controlled benchmark, calculating an answer and updating a state behave as separate capabilities. It isolates exactly how updates break. But it does not prove that real LLMs fail the exact same way. If you want that evidence, read the Belief-R and AGM-Bench papers. They actually test the models.

在智能体或 RAG 系统中构建什么内容What to build into an agent or RAG system

以下是将其应用于 AI 智能体或 RAG 系统的方法。这些是设计规则,而非原始测试数据。如果你的系统会缓存摘要、答案或状态标志,下面这六个习惯可以修复我发现的漏洞。但只有在系统正确跟踪依赖关系时,它们才有效。Here is how to apply this to an AI agent or a RAG system. These are design rules, not raw test data. If your system caches summaries, answers, or status flags, these six habits fix the bugs I found. They only work if your system tracks dependencies properly.

  1. 跟踪依赖关系。为每个缓存项标记其所依赖事实的 ID。否则,更新就会丢失。

    Track dependencies. Tag every cached item with the IDs of the facts it relies on. Otherwise, updates just get lost.

  2. 持续推送更新,直到结果稳定。不要在第一个下游节点处停止,也不要清空整个缓存。更新受影响的节点,并在值稳定后立即停止。

    Push updates until they settle. Do not stop at the first downstream node. Do not wipe the whole cache either. Update the affected nodes and stop as soon as the values stabilize.

  3. 允许存在“未知”状态。数据相互矛盾通常意味着“我不知道”。如果你的系统无法这样回答,它就会基于过时的信息继续给出自信的答案。

    Allow an UNKNOWN state. Conflicting data usually means "I do not know." If your system cannot say that, it will keep a confident answer based on dead facts.

  4. 两个方向都要测试。检查正确的数据是否发生了变化。检查无关数据是否保持不变。只测试一侧会掩盖大量严重错误。

    Test both directions. Check if the right data changed. Check if the unrelated data stayed the same. Testing only one side hides massive bugs.

  5. 检查内部状态。最终输出看起来可能没问题,但内部节点可能完全过时。测试整个图。

    Check internal states. The final output can look fine while the internal nodes are completely stale. Test the whole graph.

  6. 打乱你的更新顺序。以随机顺序输入更新。如果最终状态发生变化,那就说明存在 bug。你甚至不需要为此准备一个真实结果作为参照。

    Shuffle your updates. Feed updates in a random order. If the final state changes, you have a bug. You do not even need a ground-truth oracle for this.

最后还有一点。定期运行一次完整重建作为审计。从头重新计算所有内容,并与缓存进行差异比较。完整重建的计算成本是平时的四倍,因此不要在线执行。只把它用作健康检查即可。One last thing. Run a full rebuild periodically as an audit. Recompute everything from scratch and diff it against your cache. A full rebuild costs four times as much compute, so do not do it live. Just use it as a health check.

回想一下旅行机器人。航班被取消了。如果机器人有依赖关系图,就能准确知道该检查哪些内容。它会更新依赖逻辑,必要时将相关事项标记为“未知”,而不会动你的牙医预约。从原始文本中提取这样的依赖关系图是一项巨大的挑战,而这个实验并没有解决这个问题。Think back to the travel bot. The flight gets canceled. If the bot has a dependency map, it knows exactly what to check. It updates the dependent logic. It flags things as "unknown" if needed. It leaves your dentist appointment alone. Extracting this dependency map from raw text is a massive challenge. This experiment does not solve that.

我们花了数年时间教 AI 回答问题。现在,我们需要教它改变主意。为此,你只需要一张依赖关系图,以及一条严格的使用规则。We spent years teaching AI to answer questions. Now we need to teach it to change its mind. To do that, you just need a dependency map and a strict rule for how to use it.

亲自运行它Run it yourself

整个基准测试只有一个 Python 文件,并且严格只使用标准库。The entire benchmark is a single Python file. It strictly uses the standard library.

按如下方式运行:python revisiontrace.pyRun it like this:python revisiontrace.py

大约需要一秒钟。它会打印报告,并将七个文件保存到 revisiontrace_out 文件夹中。输出包括 CSV 表格、完整的案例日志、JSON 数据、最小失败用例的文本记录,以及两张 SVG 图表。It takes about one second. It prints the report and saves seven files to a revisiontrace_out folder. The outputs include CSV tables, full case logs, JSON data, text records of the smallest failures, and two SVG diagrams.

查看终端顶部,确认你的运行结果与我的一致。你应该能看到以下几行内容:Look at the top of your terminal to verify your run matches mine. You should see these exact lines:

text
verified: full_recompute and incremental match the oracle on all 300 casesverified: all 6 strategies answer correctly from scratch on all 300 casesRevisionTrace  |  300 cases  |  case-set hash 506be3856003

默认种子始终会生成完全相同的测试用例和逐字节一致的输出文件。想测试不同的样本?只需运行 python revisiontrace.py --seed 7 --cases 100。The default seed always builds the exact same test cases and byte-for-byte output files. Want to test a different sample? Just run python revisiontrace.py --seed 7 --cases 100.

你可以在 GitHub 上找到代码:https://github.com/Emmimal/revisiontrace/

You can find the code on GitHub: https://github.com/Emmimal/revisiontrace/

披露Disclosure

本文中的所有代码均由我编写,且为原创作品。没有任何人赞助这项工作,我也与本文所引论文的作者没有任何关联。基准测试结果未使用任何语言模型。唯一一次模型运行(Gemma 3 4B)使用本地安装的 Ollama,温度设为 0,随机种子为 42。期间没有调用任何 API,也没有访问网络。All code in this article was written by me and is original work. No one sponsored this work, and I have no affiliation with the authors of the papers cited here. The benchmark results use no language model. The one model run (Gemma 3 4B) used a local Ollama install with temperature 0 and seed 42. There were no API calls and no network access.

每个基准测试数据都来自使用种子 2026 运行 revisiontrace.py(案例集哈希值为 506be3856003)的结果,此外还包括「限制」一节中列出的三个额外种子,以及一次验证运行(种子 42,1,200 个案例,每个案例额外采用 10 种更新顺序);在这次验证中,两种正确策略再次在每个案例上都与预言机结果一致。模型数据则来自我自己使用种子 2026 运行 llm_eval.py 的结果。Every benchmark number comes from a run of revisiontrace.py with seed 2026 (case-set hash 506be3856003), plus the three extra seeds named in the limits section and one validation run (seed 42, 1,200 cases, 10 extra update orders per case) in which both correct strategies again matched the oracle on every case. The model numbers come from my own run of llm_eval.py on seed 2026.

相关工作部分是我根据各篇论文的摘要页面用自己的话撰写的,并已对照出版社或会议页面进行核查。我没有复制这些论文中的任何文字、数据或图表。图表均由我自行制作,基于该基准测试的输出绘制。The related work is described in my own words, based on each paper's abstract page, which I checked against the publisher or conference page. I reproduced no text, data or figures from those papers. The figures are my own and are drawn from the benchmark's output.

参考文献References

  1. Alchourrón, C. E., Gärdenfors, P., & Makinson, D.(1985)。论理论变化的逻辑:部分相交收缩与修正函数。《符号逻辑杂志》,50,510–530。https://doi.org/10.2307/2274239

    Alchourrón, C. E., Gärdenfors, P., & Makinson, D. (1985). On the logic of theory change: Partial meet contraction and revision functions. The Journal of Symbolic Logic, 50, 510–530. https://doi.org/10.2307/2274239

  2. Cohen, R., Biran, E., Yoran, O., Globerson, A., & Geva, M.(2024)。评估语言模型中知识编辑的涟漪效应。《计算语言学协会学报》,12,283–298。https://aclanthology.org/2024.tacl-1.16/

    Cohen, R., Biran, E., Yoran, O., Globerson, A., & Geva, M. (2024). Evaluating the ripple effects of knowledge editing in language models. Transactions of the Association for Computational Linguistics, 12, 283–298. https://aclanthology.org/2024.tacl-1.16/

  3. Doyle, J.(1979)。一种真值维护系统。《人工智能》,12,231–272。概述:理由维护(维基百科)

    Doyle, J. (1979). A truth maintenance system. Artificial Intelligence, 12, 231–272. Overview: Reason maintenance (Wikipedia)

  4. Gemma 团队,Google DeepMind。(2025)。Gemma 3 技术报告。arXiv:2503.19786。https://arxiv.org/abs/2503.19786

    Gemma Team, Google DeepMind. (2025). Gemma 3 technical report. arXiv:2503.19786. https://arxiv.org/abs/2503.19786

  5. Gupta, A., Mumick, I. S., & Subrahmanian, V. S. (1993). 增量维护视图. 《1993 年 ACM SIGMOD 数据管理国际会议论文集》,157–166。https://dl.acm.org/doi/10.1145/170035.170066

    Gupta, A., Mumick, I. S., & Subrahmanian, V. S. (1993). Maintaining views incrementally. Proceedings of the 1993 ACM SIGMOD International Conference on Management of Data, 157–166. https://dl.acm.org/doi/10.1145/170035.170066

  6. Jenkins, B. (2026). AGM-Bench:大型语言模型会理性地修正信念吗?ICLR 2026 大型语言模型逻辑推理研讨会。https://www.iclr.cc/virtual/2026/10017503

    Jenkins, B. (2026). AGM-Bench: Do large language models revise beliefs rationally? Workshop on Logical Reasoning of Large Language Models, ICLR 2026. https://www.iclr.cc/virtual/2026/10017503

  7. Marcos, J., Přenosil, A., & Égré, P. 多值逻辑。《斯坦福哲学百科全书》(2026 年春季版)。https://plato.stanford.edu/archives/spr2026/entries/logic-manyvalued/

    Marcos, J., Přenosil, A., & Égré, P. Many-valued logic. Stanford Encyclopedia of Philosophy (Spring 2026 edition). https://plato.stanford.edu/archives/spr2026/entries/logic-manyvalued/

  8. Ollama.(无日期)。Ollama[软件]。GitHub。https://github.com/ollama/ollama

    Ollama. (n.d.). Ollama [Software]. GitHub. https://github.com/ollama/ollama

  9. Python 软件基金会。(无日期)。Python 标准库。《Python 3 文档》。https://docs.python.org/3/library/index.html

    Python Software Foundation. (n.d.). The Python standard library. Python 3 documentation. https://docs.python.org/3/library/index.html

  10. Wilie, B., Cahyawijaya, S., Ishii, E., He, J., & Fung, P. (2024). 信念修正:大型语言模型推理的适应性. 2024年自然语言处理实证方法会议论文集,10480–10496. https://aclanthology.org/2024.emnlp-main.586

    Wilie, B., Cahyawijaya, S., Ishii, E., He, J., & Fung, P. (2024). Belief revision: The adaptability of large language models reasoning. Proceedings of the 2024 Conference on Empirical Methods in Natural Language Processing, 10480–10496. https://aclanthology.org/2024.emnlp-main.586

  11. Wilson, E. B.(1927)。《或然推断、继承定律与统计推断》。《美国统计学会期刊》,22,209–212。

    Wilson, E. B. (1927). Probable inference, the law of succession, and statistical inference. Journal of the American Statistical Association, 22, 209–212.

  12. Zhong, Z., Wu, Z., Manning, C., Potts, C., & Chen, D. (2023). MQuAKE:通过多跳问题评估语言模型中的知识编辑。《2023年自然语言处理实证方法会议论文集》,15686–15702。https://aclanthology.org/2023.emnlp-main.971

    Zhong, Z., Wu, Z., Manning, C., Potts, C., & Chen, D. (2023). MQuAKE: Assessing knowledge editing in language models via multi-hop questions. Proceedings of the 2023 Conference on Empirical Methods in Natural Language Processing, 15686–15702. https://aclanthology.org/2023.emnlp-main.971


作者Written By

埃米米尔·P·亚历山大Emmimal P Alexander

我叫 Emmimal P Alexander,是一名独立的 AI 工程师和技术作家,专注于实用深度学习、神经符号系统和模型可靠性。我著有《Python 神经网络与深度学习:实用方法》(2024)。除了在 TDS 的工作,我还会在 emitechlogic.com 上记录最新的可复现实验、原生 PyTorch 实现,以及对 AI 可信性的深入探讨。欢迎在那里联系我获取完整代码库,也可以通过 LinkedIn 和 GitHub 联系我。I’m Emmimal P Alexander, an independent AI engineer and technical writer specializing in practical deep learning, neuro-symbolic systems, and model reliability. I am the author of Neural Networks and Deep Learning with Python: A Practical Approach (2024). Beyond my work here on TDS, I document my latest reproducible experiments, raw PyTorch implementations, and deep-dives into AI trustworthiness at emitechlogic.com. Connect with me there for full codebases or on LinkedIn and GitHub.

See all from Emmimal P Alexander

分享这篇文章Share This Article

Towards Data Science 是一个社区出版平台。提交你的见解,与全球读者分享,并通过 TDS 作者付费计划获得报酬。Towards Data Science is a community publication. Submit your insights to reach our global audience and earn through the TDS Author Payment Program.

Write for TDS

值得记下

  1. 真正的教训非常具体。一个智能体可以在记忆里拥有全部正确的数据,但当某个变量发生变化时,它仍然可能无法更新一个旧结论。记住事实很容易,管理状态变化却很难。

← 回到本期 · 第 17 条