P2 methodology AI工程Synapse自动化

当 AI 团队的人数出现三个版本:我们如何用元规则修复数字漂移

从同一系统出现44/46/50三个agent人数的真实事故出发,剖析多文件维护场景下数字漂移的根因并提出Fact-SSOT元规则

  • 同一事实在三个文档里出现三个版本,AI 会悄悄选一个继续跑
  • 根因是 AI 知识库缺乏"单一事实来源"机制,不同于人类文档
  • 解法:Fact-SSOT 三条元规则——隔离、收窄写权限、冲突强制报错
  • 半天落地,两周内冲突检测触发三次,全部真实命中,零误报
  • 适用场景:变化频率以天/周计、多任务共引用的配置型事实

上周我们的系统里同时存在三个"正确答案"

44、46、50。这三个数字都是我们 AI agent 团队的成员人数,分别来自三个不同的文档文件,在同一套系统里安静地共存了将近两周,直到某个需要跨文件决策的任务把它们同时拉进了上下文窗口。没有人故意制造这个混乱——每次更新都有理由:有人把兼职 agent 算进去写成了 50,有人只统计全职写成了 46,原始的 44 则留在日志摘要的历史快照里没被清理。三种"真相",互不干扰,直到系统被迫同时看见它们。

这不是一个哲学问题,是一个工程问题。而且它比你想象的更常见——只要你的 AI 系统依赖超过两个文档文件,这个风险就已经存在了。

为什么这个问题难排查:AI 不会像人一样停下来质疑

我们一开始以为这只是个文档管理的疏漏,找到三个文件对齐一下就完事了。但复现实验让我们意识到问题更深:当我们把三个版本的文档同时喂给 AI 执行同一个任务时,它没有报错,而是悄悄地选了其中一个数字继续跑。更麻烦的是,结果不稳定——有时用 46,有时用 50,取决于文档在上下文里的排列顺序。

实际上,人类读者在遇到数字不一致时会本能地停下来质疑,会去找原始依据;但 AI 在大多数情况下会默默消化矛盾,用某种内部权重决定相信哪个版本,然后继续执行。这意味着人类文档管理里的小毛病,在 AI 系统里会被放大成持续的、不可预测的系统性偏差——你不知道它选了哪个,也不知道选择依据是什么。这就是数字漂移真正危险的地方:不是一次性的崩溃,而是静默的、难以溯源的错误。

根因:AI 知识库缺少"事实注册表"机制

问题的根因不在于某次手误,而在于文档体系没有对"事实性数据"做专门管理。代码工程里有 Single Source of Truth 的概念——一个常量只在一个地方定义,其他地方引用它。但在 AI 知识库里,我们习惯于在每个文件里把相关信息写完整,导致同一个事实被反复陈述,每次陈述都可能产生微小偏差。

我们引入了一个叫 Fact-SSOT(Fact Single Source of Truth) 的元规则体系,核心逻辑是三条:

第一条:事实隔离——把数字从叙述文档里抽出来

把所有会变化的定量事实(人数、版本号、日期、阈值等)集中存放在一个专用的事实注册表(Fact Registry)里,其他文档使用明确的引用标记而不是直接写死数值。我们用一个有版本控制的 YAML 文件实现这个注册表:

# fact_registry.yaml
# 唯一权威来源,其他文档禁止直接写死以下数值

team:
  agent_count_fulltime: 46
  agent_count_including_parttime: 50
  last_updated: "2025-01-15"
  updated_by: "lysander"

system:
  prompt_version: "v2.3.1"
  context_window_limit: 128000
  max_parallel_tasks: 8

其他文档引用时用占位标记,在渲染/注入阶段替换为注册表数值,而不是把数字硬编码进文本里。

第二条:写入权限收窄——让修改事实变得有仪式感

事实注册表设定明确的 Git commit 规范,让"修改事实"这个行为显式化:

# 修改注册表时必须遵循的 commit 格式
git commit -m "fact(team): agent_count_fulltime 44 -> 46

原因: Q1 新增 2 名全职 agent 完成入职
影响文档: system_prompt_v2.md, team_config.md, weekly_report_template.md
验证人: @team-lead"

不需要复杂工具,只需要让团队知道:改注册表不是顺手的事,是需要留记录、通知下游的事。

第三条:AI 读取时的冲突检测——把"悄悄选择"变成"显式报错"

在系统提示里加入一条元指令,强制要求 AI 在检测到数字冲突时停止并上报,而不是自行决断:

# 系统提示中的冲突检测元规则片段
conflict_detection:
  enabled: true
  instruction: |
    当你在上下文中发现同一实体存在不一致的定量描述时(如同一团队
    在不同文档中出现不同的人数),立即停止执行当前任务,输出以下
    格式的冲突报告,等待人工确认后再继续:

    [FACT_CONFLICT]
    实体: {entity_name}
    冲突值: {value_a}(来源: {source_a}) vs {value_b}(来源: {source_b})
    建议参考: fact_registry.yaml
    [/FACT_CONFLICT]

可移植的原则:如果你也在维护多文件 AI 知识库

如果你在构建任何依赖多文档的 AI 系统,把"文档一致性"当作一等公民来设计,而不是事后校对的工作——注意力是不可靠的资源,结构才是。

  1. 如果你在维护超过两个需要引用相同数字的文档,把事实数据从叙述文档里物理隔离出来,建一个哪怕只有十行的 YAML 注册表,总比分散在各处好。
  2. 如果你在团队协作更新 AI 配置文件,让修改关键数值这个行为变得有仪式感——一条规范的 commit message 比口头约定"下次注意"可靠得多。
  3. 如果你发现 AI 在处理矛盾信息时"静默通过",在系统提示里加冲突检测元规则,让隐性风险变成可见异常,宁可多几次中断也不要不可预测的偏差。
  4. 如果你的数据变化频率是实时级别的,Fact-SSOT 帮不了你——那种场景需要真正的数据库和 API,文档规范只适合变化以天或周计的配置型事实。

落地情况与边界

这套规则落地大概花了半天:迁移现有文档两小时,写事实注册表一小时,更新系统提示半小时。运行两周后,冲突检测触发了三次,每次都是真实的数据不一致被及时发现,没有一次误报。更值得记录的是一个副作用:团队成员在更新数字时开始有意识地先去改注册表,这个习惯本身就是收益,不需要额外监督。

需要说清楚的是,Fact-SSOT 不是银弹。它解决的是结构性不一致,不解决数据本身的准确性——如果注册表里的数字一开始就是错的,这套规则帮不了你。数字漂移是个小问题,但它暴露的是系统对自身事实掌控力的脆弱性。在 AI 大量介入决策的系统里,这个脆弱性值得认真对待。

如果你也遇到过类似的多文档一致性问题,或者在考虑如何给 AI 系统设计更健壮的知识库结构,欢迎在评论区聊——我们在 Synapse 框架里把 Fact-SSOT 和其他几条元规则都整合进去了,下一篇我会具体写冲突检测的提示词设计和我们踩过的坑。