最近在做 AdamI 的过程中,有一种失败状态我一直反复遇到。

它不是那种很明显的失败。

不是进程崩溃,不是 API 被拒绝,也不是测试直接变红。

而是一种更麻烦的情况:

系统已经做了一件事,也看到了一些结果,但它仍然没有足够的依据确认,这件事到底是不是真的完成了。

乍看之下,这好像只是一个边缘情况。

但我越来越觉得,它其实是持久化 Agent 里非常重要的问题。

因为系统运行得越久,错误的确定性就越危险。

一个聊天机器人判断错一次,对话结束以后,这个错误往往也就停在那里了。

但一个持久化系统可以判断错一次,把这个判断保存下来,第二天继续基于它行动,再让系统里的其他模块把这个原本只是“猜测”的东西当成事实。

这时候问题就已经变了。

我们不能只问:

这个动作成功了吗?

更应该问:

我有没有足够的证据相信它成功了?

这两件事并不一样。

动作发生了,不代表结果已经成立

在 Digital Life Log #009 里,我写过这个问题。

工具调用成功,并不等于现实世界里的目标状态真的发生了。

一条命令可以返回 0,但输出内容仍然是错的。

API 可以先接受请求,但后续处理失败。

浏览器自动化可以点击正确的按钮,但网页后台没有真正保存修改。

文件可能看起来已经上传,但远端内容并不完整。

Agent 也可能只是因为自己的执行流程走到了最后一步,就把任务判断为完成。

这些都不一定意味着结果已经被验证。

所以我后来开始刻意区分几种状态:

attempted

observed

verified

uncertain

一开始我以为这只是状态管理上的细节。

后来发现,它实际上会决定系统下一步可以相信什么。

成功和失败之间,还有一个很麻烦的状态

软件系统通常喜欢明确答案。

成功。

失败。

真。

假。

完成。

未完成。

但现实世界并不总是这么干净。

有时候证据不完整。

有时候两个观察结果互相冲突。

有时候系统知道某件事发生了变化,但无法确认最后到底变成了什么状态。

有时候唯一的确认信息,恰好来自刚刚执行这个动作的同一个组件。

还有些时候,连验证过程本身都会失败。

这时如果强行要求系统只能在 success 和 failure 之间选一个,就等于制造了一个现实中原本不存在的确定结论。

这才是我真正担心的地方。

如果 AdamI 只是因为“看起来大概率成功”就写入 success,这个错误不会只停留在当前这次推理里。

在持久化架构中,它可能继续存在。

它可能被写进记忆。

可能让一个 task 从 open 变成 complete。

可能解除另一个任务的依赖。

可能影响下一次模型推理。

也可能变成另一个 Agent 之后看到的“证据”。

一个很弱的假设,慢慢就会变成系统历史的一部分。

不确定性也需要有地方存在

这也是持久化系统和聊天机器人的一个重要区别。

聊天机器人可以简单说一句:

“我不确定。”

但一个持久化 Agent 不能只停在这句话上。

它需要一个真正能够保存下来的 uncertainty state。

系统应该能够表达类似这样的状态:

我已经执行了这个动作。

我观察到了一部分证据。

但现有证据还不足以证明结果已经成立。

所以暂时不能把它当成完成。

这个状态可能只持续几分钟,也可能持续几个小时,甚至更久。

也许正确的下一步是稍后重新检查。

也许需要另一个独立来源提供证据。

也许需要向人确认。

也许依赖这个结果的后续任务应该继续保持阻塞。

也有可能最后始终无法获得足够的证据,那么这个任务就应该保留为 unresolved,而不是被硬塞进 completed。

到了这里,persistence 就已经不只是“记得更多东西”了。

不确定性本身,也必须能够被保存。

多 Agent 系统会把这个问题放大

当系统里出现多个 Agent 时,这个问题会更明显。

假设 Agent A 执行了一个动作。

Agent B 之后读取项目状态。

Agent C 再基于这个状态做规划。

如果 Agent A 在证据不足的时候直接写下了“done”,那么 B 和 C 已经看不到最初那层不确定性了。

它们看到的只剩一个结论。

这其实是一种信息损失。

信息在多个 Agent 之间传播的时候,系统反而越来越确定了,但过程中并没有增加新的证据。

这显然不是我们想要的结果。

共享状态当然很重要。

因为不同 Agent 不需要每次都重新观察整个世界。

但共享状态真正有价值的前提是,它保存的不只是“最终标签”,还要尽量保存这个判断背后的证据质量。

一个持久化的多 Agent 系统,除了需要知道自己相信什么,也应该知道自己凭什么相信。

我并不打算给 AdamI 做一套复杂的形式化认知系统。

但至少在架构上,它不能因为时间过去了,就自动把 uncertainty 变成 certainty。

错误记忆,有时候比没有记忆更糟

我们通常会把 memory 当成优势。

记得更多,就有更多上下文。

可以维持连续性。

也可以减少重复工作。

但持久化 memory 同样给错误提供了生存空间。

如果系统把一个错误判断以 verified fact 的形式保存下来,那么未来行为可能会变得越来越一致,同时也越来越错误。

所以 memory 和 verification 实际上是绑在一起的。

在某个状态被写成长期状态之前,系统应该关心它到底从哪里来。

是直接观察到的吗?

是推理出来的吗?

是另一个 Agent 报告的吗?

有没有独立验证?

证据是不是已经过期?

不同来源之间有没有冲突?

这不意味着系统必须追求绝对确定。

很多现实任务本来就不存在绝对确定。

真正重要的是一件更简单的事:

不要把弱证据伪装成强证据。

有时候,最正确的状态就是暂时没有结论

这件事其实很反直觉。

因为 Agent 通常都是被设计成“把事情做完”的。

用户想要结果。

Benchmark 奖励完成。

任务系统也喜欢清晰的状态变化。

整个环境都在推动系统尽快把 uncertainty 变成一个明确答案。

但一个真正长期运行的系统,可能需要另一种能力。

有时候,最正确的动作就是暂时不做决定。

有时候最正确的状态就是:

still uncertain。

这并不代表系统什么都不做。

它仍然可以继续收集证据。

可以安排下一次检查。

可以要求确认。

可以暂时限制某些后续动作。

在一些高风险场景里,不确定性甚至应该直接降低系统的 authority。

如果系统连一个敏感动作是否成功都无法确认,它就不应该立刻假设这个结果成立,然后继续执行后面三四个依赖任务。

这和我最近一直在思考的另一件事其实是同一个方向:

capability 可以增长,但 authority 应该被逐步获得。

证据也是一样。

confidence 也应该被逐步获得。

AdamI 现在做到哪里

AdamI 目前已经有一些机制,让这个问题变得无法回避。

系统有持久化 task state。

有 background processes。

有 memory mechanisms。

有 verification 和 observability 的一些路径。

也有一个 Guardian layer,用来限制系统可以做什么。

同时还有多个模型角色,以及 hybrid routing 结构。

但我不会说 AdamI 已经解决了 uncertainty。

还没有。

目前系统可以保存未完成任务,也可以让状态跨越多次模型调用继续存在。

但更深的问题仍然没有完全解决:

到底需要多少证据,一个持久化系统才有资格把某个判断正式写入长期状态?

如果现实世界在两次检查之间发生变化,这个问题会更难。

如果两个工具给出不同结果,也会更难。

如果一个 Agent 在验证另一个 Agent,这件事又会更复杂。

以后如果系统开始自己生成更多任务,这个问题只会继续放大。

接下来我想测试的东西

我接下来想在 AdamI 的 task 和 memory flow 里,把 uncertainty 做得更明确一些。

不是让模型在文字里加一句“我不确定”。

而是让 uncertainty 本身成为一个会影响行为的状态。

如果某件事还是 uncertain,那么后续行为也应该跟着变化。

系统可能需要先 recheck。

依赖任务可能继续保持 blocked。

证据可能需要设置过期时间。

有些情况可能必须经过 human confirmation。

也可能在后续新的 observation 出现以后,系统自动把 uncertain 解析成 verified 或 failed。

最重要的一点是:

不确定性不能因为当前这次模型调用结束了,就自动消失。

如果证据还不完整,那么 uncertainty 就应该比这一次 model call 活得更久。

这看起来只是一个很小的规则。

但我越来越觉得,它可能正是“看起来很持久的系统”和“真正能够承担自己过去所造成后果的系统”之间的区别之一。

一个 persistent agent 应该有能力保持不确定。

不是永远保持。

只是一直保留到现实世界真的给出足够的理由,让它不再需要不确定为止。