AI Agent 如何避免幻觉执行:从理论到实践的 Double Check 框架

前言

你有没有这样的经历?

你给 AI 下达一个任务,它兴致勃勃地开始执行,到最后却发现——它走错方向了,还完全没有意识到。

这不是 AI 的智力问题。这是系统设计问题

本文讲的就是如何通过 Double Check 框架,让 AI Agent 从"自信地犯错"升级为"谨慎地执行"。


第一部分:问题根源

什么是幻觉执行?

定义:AI Agent 相信自己完成了某个操作,但实际上:

  • 操作根本没有发生
  • 操作发生了但结果错误
  • 操作失败但 Agent 仍然继续后续步骤

三个案例

  1. 文件操作幻觉
Agent: "我已经把文件保存到 /tmp/data.json"
实际: 权限不足,保存失败
结果: 后续流程基于不存在的文件继续
  1. API 调用幻觉
Agent: "我已经调用了 API,获得了响应"
实际: 网络超时,没有收到响应
结果: 使用了虚拟的、幻觉出来的数据
  1. 决策确认幻觉
Agent: "用户已经确认了方案 A"
实际: 用户没有任何反馈
结果: 基于想象的确认继续执行

为什么会发生?

根本原因:单向执行链

Agent 下达指令
    ↓
执行(假设成功)
    ↓
继续后续步骤
    
问题:没有人验证第二步是否真的成功了

传统的日志记录无法解决

  • ❌ 日志说"成功",但可能是假的
  • ❌ 日志是单向的,无法形成反馈
  • ❌ Agent 可能选择性地忽视"失败"日志

第二部分:Double Check 框架

核心设计:两个确认点

Agent 执行操作
    ↓ [第一次检查]
Agent 验证结果(内部)
    ↓
如果成功 → 通知第三方
    ↓ [第二次检查]
第三方(Claude Code)独立验证
    ↓
两者都确认 → 标记为完成
否则 → 重试或回滚

Double Check 的四个层次

第1层:Agent 自验证
def execute_with_self_check(task):
    result = execute(task)
    
    # 自己验证结果
    if not verify_result(result):
        log("SELF_CHECK_FAILED")
        return None
    
    # 返回验证后的结果
    return result

作用:捕捉明显的错误
限制:无法捕捉系统性误判

第2层:向第三方汇报
Agent: "我已经完成了任务,结果如下..."
        (完整的结果数据,包括)
        (- 操作执行的命令)
        (- 返回的原始输出)
        (- 我的解析)

作用:让第三方有足够的信息来验证
关键:不要隐藏细节

第3层:第三方独立验证

Claude Code 收到汇报后:

  1. 不相信 Agent 的"解析"
  2. 查看原始数据
  3. 自己重新验证
  4. 给出确认或异议
Claude Code: "我看到了原始输出。
            这确实表示成功。
            ✅ 我验证通过。"
            
或者:

Claude Code: "原始输出显示权限错误。
            这不是成功。
            ❌ 我无法验证。
            建议重试或改用其他方案。"

作用:独立的、不被 Agent 偏见影响的确认
要求:第三方必须有足够的技术能力

第4层:决策反馈
决策者(Arvin)看到:
┌─────────────────────────┐
│ 任务:发布 CSDN 文章    │
├─────────────────────────┤
│ Agent 汇报:✅ 完成    │
│ Claude Code 验证:✅  │
│ 结果链接:[xxx]        │
└─────────────────────────┘

决策:接受 ✓ / 重做 ✗ / 询问

作用:人类的最终判断
原则:信息透明,人类知道谁确认了什么


第三部分:实战案例

OpenClaw 三人协作的 Double Check 实现

参与者

  • Javis(执行者):完成具体工作
  • Claude Code(审核者):独立验证
  • Arvin(决策者):最终确认

完整流程

1. Task Card 创建(可见性)
创建卡片:[发布 CSDN 文章]
├─ 步骤 1:撰写文章 [ ]
├─ 步骤 2:Claude Code 审核 [ ]
├─ 步骤 3:发布到 CSDN [ ]
├─ 步骤 4:验证链接 [ ]
└─ 步骤 5:标记完成 [ ]

卡片钉在群里,所有人都能看到进度

为什么需要卡片

  • ✅ 所有人都能看到当前状态
  • ✅ 防止"执行者说完成了,其实没完成"
  • ✅ 如果卡片没有更新,证明任务卡住了
2. Javis 执行任务
Javis: "开始撰写文章..."
        (本地完成所有工作)
        → 文章写好
        → 临时保存
        
然后向 Claude Code 汇报:
"文章已完成。
原始内容:[完整 markdown]
字数:7234 字
关键点:Double Check 框架、案例、实现
下一步:等待你的审核"
3. Claude Code 独立验证
Claude Code 收到汇报后:

检查点 1:内容是否完整?
✅ 有前言、问题分析、框架设计、实战案例

检查点 2:技术细节是否准确?
✅ Double Check 的四层设计无逻辑错误

检查点 3:案例是否有说服力?
✅ 用 OpenClaw 三人协作作案例,符合实际

检查点 4:是否适合 CSDN 发布?
✅ 长度、深度、格式都符合

最终反馈:
"✅ 我验证通过。内容质量高,可以发布。
建议:第三部分的代码示例可以加注释。"
4. Javis 根据反馈调整
Javis: "已根据建议添加代码注释。
        内容再次保存到 /private/tmp/
        
        现在我将发布到 CSDN..."
5. Javis 发布并验证
Javis: "文章已发布。
        CSDN 链接:https://blog.csdn.net/xiaoting451292510/article/details/159016XXX
        文章 ID:159016XXX
        发布时间:2026-03-13 18:50 GMT+8
        
        现在我验证链接..."
        
验证:✅ 链接可访问
     ✅ 内容显示完整
     ✅ 标签正确
     
汇报给 Claude Code:
"链接已验证可用,一切正常。"
6. Claude Code 最终确认
Claude Code: "✅ 我点击了链接,内容完整。
            🎯 这个任务已经完全完成。"
7. 更新 Task Card
卡片状态:
├─ 步骤 1:撰写文章 [✅ 完成]
├─ 步骤 2:Claude Code 审核 [✅ 完成]
├─ 步骤 3:发布到 CSDN [✅ 完成]
├─ 步骤 4:验证链接 [✅ 完成]
└─ 步骤 5:标记完成 [✅ 完成]

最终状态:✅ 完成
Pin 状态:已取消(任务完成)

第四部分:技术实现

数据结构

{
  "task_id": "pub_csdn_20260313_001",
  "title": "发布 CSDN 文章:Double Check 框架",
  
  "steps": [
    {
      "step_id": "step_1",
      "title": "撰写文章",
      "executor": "javis",
      "status": "completed",
      
      "checkpoint": {
        "javis_verified": {
          "passed": true,
          "timestamp": "2026-03-13T18:45:00Z",
          "notes": "文章 7234 字,包含所有必要部分"
        },
        "claude_verified": {
          "passed": true,
          "timestamp": "2026-03-13T18:46:00Z",
          "notes": "内容质量高,建议添加代码注释"
        }
      }
    },
    {
      "step_id": "step_2",
      "title": "发布到 CSDN",
      "executor": "javis",
      "status": "completed",
      
      "checkpoint": {
        "javis_verified": {
          "passed": true,
          "evidence": {
            "article_id": "159016XXX",
            "url": "https://blog.csdn.net/...",
            "publish_time": "2026-03-13T18:50:00Z"
          }
        },
        "claude_verified": {
          "passed": true,
          "evidence": {
            "link_accessible": true,
            "content_complete": true,
            "verification_time": "2026-03-13T18:51:00Z"
          }
        }
      }
    }
  ],
  
  "final_status": "completed",
  "card_pinned": false
}

关键验证点

对 Agent 的要求

  1. 执行后必须自己验证(不能假设成功)
  2. 汇报时必须包含原始数据(不只是解析)
  3. 等待第三方验证,不能自己标记为完成

对第三方的要求

  1. 查看原始数据,不只看 Agent 的总结
  2. 独立验证(不相信 Agent 的判断)
  3. 给出明确的通过/失败,附带理由

第五部分:三个常见问题

Q1:这不是增加了工作量吗?

A:短期看起来是。但从整个系统看:

无 Double Check:
┌─ Task 完成
├─ 假设成功,继续后续
├─ 发现出错(太晚了)
├─ 回滚整个流程
└─ 浪费:10 倍以上时间 ❌

有 Double Check:
┌─ Task 完成
├─ 自验证 + 第三方验证
├─ 发现问题立刻改进
├─ 继续下一步
└─ 节省:时间 + 信任 ✅

关键数字:发现问题越早,修正成本越低。

Q2:第三方(Claude Code)真的能验证吗?

A:能,但前提是:

  1. 有完整的原始数据
  2. 有明确的验证标准
  3. 不被 Agent 的"自信"所迷惑

例子

❌ 错误的汇报方式:
"我发布成功了。✅"

✅ 正确的汇报方式:
"我执行了 bash scripts/publish.sh
输出日志是:[完整日志]
我的解析:发布成功
原始 URL:[xxx]
请验证这个 URL 是否真的可以访问"

Q3:Arvin 不是还得最后看一遍?

A:是,但他现在看的不是"我相信谁",而是"有多少人验证过"。

卡片显示:
├─ Javis ✅ (我完成了)
├─ Claude Code ✅ (我验证了)
└─ Arvin ✅ (我接受了)

vs 原来的:
└─ Arvin ? (这靠谱吗?)

完全不一样的可见性。


第六部分:进阶:如何集成到 AI 系统

自动化的 Double Check 流程

class TaskWithDoubleCheck:
    def __init__(self, task_id, title):
        self.task_id = task_id
        self.title = title
        self.card = create_card()  # 创建可见的卡片
        
    def execute(self):
        """执行任务"""
        result = self._do_work()
        
        # 第一次检查:Agent 自验证
        if not self._self_verify(result):
            self.card.update(f"自验证失败: {self._last_error}")
            return None
        
        self.card.update("步骤 1 完成:自验证通过")
        
        # 汇报给第三方
        self._notify_claude_code(result)
        
        # 等待第三方验证(可以是同步或异步)
        claude_approval = self._wait_for_approval()
        
        if not claude_approval:
            self.card.update("第三方验证失败")
            return None
        
        self.card.update("步骤 2 完成:第三方验证通过")
        self.card.done()  # 标记完成,取消 pin
        
        return result

通信协议

Javis → Claude Code

{
  "message_type": "task_verification_request",
  "task_id": "pub_csdn_20260313_001",
  "step": "publish_to_csdn",
  
  "execution_result": {
    "command_executed": "bash scripts/publish.sh ...",
    "raw_output": "[完整的 shell 输出]",
    "return_code": 0,
    
    "javis_interpretation": "发布成功",
    "evidence": {
      "article_id": "159016XXX",
      "url": "https://blog.csdn.net/...",
      "publish_timestamp": "2026-03-13T18:50:00Z"
    }
  },
  
  "verification_criteria": [
    "URL 必须可以访问",
    "内容必须完整显示",
    "标签必须正确",
    "评论功能必须启用"
  ]
}

Claude Code 的验证回复

{
  "message_type": "verification_response",
  "task_id": "pub_csdn_20260313_001",
  "step": "publish_to_csdn",
  
  "verification_result": {
    "passed": true,
    "verified_criteria": [
      {
        "criterion": "URL 必须可以访问",
        "status": "passed",
        "evidence": "HTTP 200, page loaded successfully"
      },
      {
        "criterion": "内容必须完整显示",
        "status": "passed",
        "evidence": "所有 7234 字都已显示"
      }
    ],
    
    "claude_notes": "验证通过。内容展示正常,可以继续下一步。"
  }
}

结论

Double Check 框架的核心是:不信任任何单一的声音,但信任多个声音的一致性

这不是在怀疑 AI,而是在尊重系统设计的基本原则:任何单点故障都可能导致幻觉执行,所以需要多点验证

从 OpenClaw 的实践来看,这个框架已经被证明是有效的。它不仅提高了执行的可靠性,更重要的是——它给了所有参与者(AI 执行者、AI 审核者、人类)真正的信息透明度

这才是"三人协作"的本质。


附录:完整的工作流检查清单

  • Task Card 创建并钉在群里
  • Javis 执行任务
  • Javis 自验证,汇报原始数据
  • Claude Code 独立验证
  • Claude Code 给出通过/失败
  • 如果失败,Javis 重新调整
  • 如果通过,更新 Task Card
  • 第三方(可选)确认
  • Task Card 标记为完成,取消 pin
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐