Task Card 作为 AI Agent 监督机制的实现方案

文章主题:如何用已有工具(Task Card)替代复杂的分布式验证机制,构建一个简洁、可见、可靠的 AI Agent 监督系统。


问题背景

在构建多 Agent 协作系统时,一个核心问题是:如何验证执行者(Agent A)声称已完成的任务是否真的完成了?

典型的痛点

  1. 幻觉执行(Hallucination)

    • Agent A 说"我已经发布了文章"
    • 实际上:API 调用失败了、网络超时了、或者根本没有执行
    • Agent A 可能根本不知道自己失败了
  2. 隐性故障(Silent Failures)

    • 任务执行流程中某个环节悄悄失败
    • 没有外部验证,无法发现
    • 问题一直埋藏到最后
  3. 缺乏可见性(Low Visibility)

    • 验证信息分散在多个地方(日志、文件、消息)
    • 需要手动查询才能了解状态
    • 不够直观、反应不够快
  4. 长期任务的持续监控

    • 20 天的任务如何保证每一天都被监督?
    • Session 中断、日志丢失、状态不一致

之前尝试的方案的问题

方案 v1:验证文件 + 轮询 + 飞书通知

任务执行 → 验证文件 → Claude Code 轮询 → 通知 Arvin
(信息分散、延迟高、工具多、复杂度高)

问题

  • ❌ 验证信息分散(多个地方)
  • ❌ 需要轮询(非实时)
  • ❌ 工具复杂(多个 API)
  • ❌ 长期任务支持困难(Session 只能持续 3 天)
  • ❌ Arvin 需要主动查询才能了解状态

解决方案:Task Card 作为监督中枢

核心洞察

在每个 Agent 启动任务时,都会创建一个Task Card(任务卡片),上面包含:

  • 完整的任务清单
  • 所有的子步骤
  • 预期完成时间
  • 当前进度

关键问题:既然这个卡片上已经有了所有信息,为什么不让审查者直接在这个卡片上标记自己的验证结果呢?

答案:这就是本方案的核心——将 Task Card 作为监督的单一、集中的源头

完整的监督流程

阶段 1:任务启动
Jarvis(执行者)创建 Task Card
│
├─ 任务名称:发布 CSDN 文章
├─ 任务清单:
│  ├─ [ ] 读取本地文章文件
│  ├─ [ ] 转换为 CSDN 格式
│  ├─ [ ] 上传到 CSDN
│  └─ [ ] 验证发布成功
├─ 预期完成时间:45 分钟
├─ 当前状态:🟢 进行中
│
└─ 检查状态:
   ├─ ✅ Jarvis 已确认启动
   └─ ⏳ Claude Code 待确认

Arvin 立即看到:任务已启动,涉及的内容是什么。


阶段 2:执行和实时更新
Jarvis 执行任务
│
├─ 09:00 → 读取文件成功
│          卡片更新:[✅ 步骤 1 完成]
│
├─ 09:10 → 格式转换成功
│          卡片更新:[✅ 步骤 2 完成]
│
├─ 09:30 → 上传成功,获得 URL
│          卡片更新:[✅ 步骤 3 完成]
│          新增:article_url: https://blog.csdn.net/...
│
└─ 09:35 → 声称完成
           卡片状态:🟡 等待验证
           检查状态:[✅ Jarvis] [⏳ Claude Code]

Arvin 看到的:任务进度实时更新,每个步骤都有据可查。


阶段 3:Claude Code 的双重验证
Claude Code 接收到卡片更新
│
├─ 读取任务清单
│  (直接从 /tmp/task_cards/*.json 读取)
│
├─ 验证完成声称
│  ├─ web_fetch 检查 URL 是否存在
│  ├─ 验证页面标题是否包含文章名
│  ├─ 检查发布时间是否近期
│  └─ 验证文章内容是否完整
│
└─ 根据验证结果标记卡片
   ├─ 通过 → 卡片变为 🟢 绿色
   │        卡片内容更新:verified_by: Claude Code
   │                     verification_result: passed
   │        检查状态:[✅ Jarvis] [✅ Claude Code]
   │
   └─ 失败 → 卡片变为 🔴 红色
            卡片内容更新:verified_by: Claude Code
                         verification_result: failed
                         failure_reason: "文章内容不完整"
            检查状态:[✅ Jarvis] [❌ Claude Code]
            附注:具体的失败原因和建议

Arvin 看到的

  • ✅ 绿卡 = 任务完成且被验证,可信任
  • 🔴 红卡 = 有问题,需要立即处理

阶段 4:处理验证失败的情况

如果 Claude Code 发现问题

验证失败(红卡)
│
├─ 实时通知:Claude Code 直接发飞书消息给 Arvin
│  "Critical: Task [ID] 验证失败,详见卡片"
│
├─ 卡片记录:所有失败信息保留在卡片上
│  - 失败原因
│  - 失败时间
│  - 建议修复方案
│
└─ Arvin 决策
   ├─ 让 Jarvis 重新执行
   ├─ 手动介入处理
   └─ 或者其他处理方式

关键:Arvin 不需要查阅多个地方,所有信息都在一个卡片上


支持长期任务的分解策略

对于 20 天的任务(比如"每天发一篇文章"),不能期待一个 Claude Code 的 Session 持续 20 天。

解决方案:每天一张卡片

Day 1:Task Card #1
  ├─ 目标:发布第 1 篇文章
  ├─ 状态:[✅ Jarvis] [✅ Claude Code]
  └─ 结果:通过

Day 2:Task Card #2
  ├─ 目标:发布第 2 篇文章
  ├─ 前置信息:第 1 天已完成,链接 [...]
  ├─ 状态:[✅ Jarvis] [✅ Claude Code]
  └─ 结果:通过

...

Day 20:Task Card #20
  ├─ 目标:发布第 20 篇文章
  ├─ 前置信息:前 19 天已完成,总计 [...]
  ├─ 状态:[✅ Jarvis] [✅ Claude Code]
  └─ 结果:通过

最终:自动汇总 20 张卡片 → 20 天任务完成报告

好处

  • ✅ 每天独立的 Claude Code Session,无需持续
  • ✅ 每天独立的验证记录,清晰可追踪
  • ✅ 如果某天失败,只需重做那一天,无需重来 20 天
  • ✅ Arvin 可以看到完整的 20 张卡片,了解全貌

为什么这个方案这么好?

1️⃣ 信息集中,一站式可见

旧方案:验证信息分散

任务执行 → 日志文件 → 验证文件 → 飞书消息 → ...
(信息在 5 个地方,需要逐一查阅)

新方案:所有信息在一个卡片上

Task Card = 任务 + 进度 + 验证结果 + 历史记录
(一个卡片,完整上下文)

2️⃣ 实时反馈,无延迟

旧方案:轮询延迟

轮询间隔 → 检测失败 → 写入文件 → 等待读取 → 才发现问题
(可能延迟 5-10 分钟)

新方案:视觉实时反馈

验证失败 → 卡片变红 + 飞书通知 → 秒级反应
(Arvin 立即看到)

3️⃣ 工具简洁,无多余复杂性

旧方案:多个工具协作

文件系统 + 轮询逻辑 + 飞书 API + 验证脚本 + ...
(5+ 个独立的组件)

新方案:原生工具能力

Task Card(已存在的工具)+ JSON 读写(标准能力)
(2 个组件,零额外复杂性)

4️⃣ 历史完整,可追溯

旧方案:信息易丢失

日志可能被覆盖 → 文件可能被删除 → 验证记录可能被清空

新方案:卡片是永久记录

每张卡片保留完整历史
- 启动时间
- 执行过程
- 验证过程
- 最终结果
- 所有中间状态

5️⃣ 心理反馈,视觉化激励

旧方案:被动提醒

"有问题,请检查日志"(无聊、抽象)

新方案:主动看见

绿卡:任务完成✅ 满足感
黄卡:轻微问题⚠️ 警觉
红卡:严重问题🚨 立即行动

技术实现细节

Task Card 的 JSON 结构

{
  "task_id": "CSDN-ARTICLE-003",
  "task_name": "发布 OpenClaw Task Card 监督方案文章",
  "created_at": "2026-03-13T15:30:00+08:00",
  "expected_completion_time": "2026-03-13T16:15:00+08:00",
  
  "subtasks": [
    {
      "name": "读取 Markdown 文件",
      "expected_duration_seconds": 300,
      "completed": true,
      "completed_at": "2026-03-13T15:35:00+08:00"
    },
    {
      "name": "转换为 CSDN 格式",
      "expected_duration_seconds": 600,
      "completed": true,
      "completed_at": "2026-03-13T15:45:00+08:00"
    },
    {
      "name": "上传到 CSDN",
      "expected_duration_seconds": 1500,
      "completed": true,
      "completed_at": "2026-03-13T16:10:00+08:00"
    },
    {
      "name": "验证发布成功",
      "expected_duration_seconds": 300,
      "completed": true,
      "completed_at": "2026-03-13T16:12:00+08:00"
    }
  ],
  
  "expected_outputs": [
    {
      "type": "url",
      "description": "CSDN 文章 URL",
      "value": null
    }
  ],
  
  "jarvis_status": {
    "claimed_completed": true,
    "claimed_at": "2026-03-13T16:12:00+08:00",
    "confirmation": "✅ 已确认启动和完成"
  },
  
  "claude_verification": {
    "status": "pending",
    "started_at": null,
    "checked_at": null,
    "result": null,
    "failure_reason": null,
    "note": null,
    "confirmation": "⏳ 待验证"
  },
  
  "overall_status": "pending_verification",
  "color_indicator": "🟡"
}

Claude Code 的验证流程

# 1. 读取 Task Card
card = read_json("/tmp/task_cards/CSDN-ARTICLE-003.json")

# 2. 验证完成声称
def verify_csdn_publication(card):
    url = card["expected_outputs"][0]["value"]
    
    # 通过 web_fetch 检查 URL
    page = web_fetch(url)
    
    # 验证条件
    checks = {
        "page_exists": page.status_code == 200,
        "title_matches": card["task_name"] in page.title,
        "content_length": len(page.body) > 5000,
        "published_recently": check_publish_time(page)
    }
    
    return all(checks.values()), checks

# 3. 更新卡片
passed, details = verify_csdn_publication(card)

if passed:
    card["claude_verification"]["result"] = "passed"
    card["claude_verification"]["confirmation"] = "✅ 已验证"
    card["overall_status"] = "completed_verified"
    card["color_indicator"] = "🟢"
else:
    card["claude_verification"]["result"] = "failed"
    card["claude_verification"]["failure_reason"] = json.dumps(details)
    card["claude_verification"]["confirmation"] = "❌ 验证失败"
    card["overall_status"] = "failed"
    card["color_indicator"] = "🔴"

# 4. 保存卡片
save_json(card, "/tmp/task_cards/CSDN-ARTICLE-003.json")

# 5. 如果是 Critical 失败,发飞书通知 Arvin
if card["color_indicator"] == "🔴":
    feishu_notify_arvin(f"Critical: {card['task_name']} 验证失败")

对比:为什么这个方案优于其他方案

vs 方案 1:纯日志/文件验证

维度 纯日志/文件 Task Card 方案
信息集中度 ❌ 分散 ✅ 集中
可见性 ❌ 需要查询 ✅ 直接看
反应时间 ⚠️ 轮询延迟 ✅ 实时
历史记录 ⚠️ 易丢失 ✅ 永久保留
工具复杂度 ❌ 高 ✅ 低

vs 方案 2:纯飞书消息通知

维度 飞书消息通知 Task Card 方案
上下文 ❌ 消息易丢失 ✅ 卡片持久
完整性 ❌ 只有文字 ✅ 结构化数据
可追溯性 ❌ 翻聊天记录困难 ✅ 完整历史
长期任务支持 ❌ 难以追踪 20 天 ✅ 20 张独立卡片

vs 方案 3:数据库中央化

维度 中央数据库 Task Card 方案
部署复杂度 ❌ 高(需要 DB) ✅ 低(文件系统)
可靠性 ⚠️ DB 故障风险 ✅ 文件系统可靠
实现成本 ❌ 高 ✅ 低
易用性 ⚠️ 需要 SQL/ORM ✅ JSON + 文件 I/O

实际应用案例

案例 1:CSDN 文章发布(日常任务)

任务:发布 OpenClaw 监督机制文章

阶段 1:启动
  → Jarvis 创建 Task Card
  → 卡片状态:🟢 进行中

阶段 2:执行
  → 09:00 读取文件 ✅
  → 09:10 格式转换 ✅
  → 09:30 上传成功 ✅
     获得 URL: https://blog.csdn.net/xiaoting451292510/article/details/159008079
  → 09:35 声称完成,卡片变为 🟡 等待验证

阶段 3:验证
  → Claude Code 读取卡片
  → web_fetch 检查 URL,验证内容
  → 验证通过 ✅
  → 卡片变为 🟢,标记 [✅ Jarvis] [✅ Claude Code]
  → 通知 Arvin:任务完成

结果:卡片上有完整的执行和验证记录,供后续追溯。

案例 2:20 天文章发布计划(长期任务)

任务:连续 20 天每天发布一篇文章

Day 1:Task Card #1
  → Jarvis 创建日常卡片
  → 执行并声称完成
  → Claude Code 验证:✅ 通过
  → 卡片 [✅ Jarvis] [✅ Claude Code]

Day 2:Task Card #2
  → 参考前一天结果(在卡片里)
  → 重复相同流程
  → Claude Code 验证:✅ 通过

...

Day 15:Task Card #15
  → 如果这天失败 → 卡片 [✅ Jarvis] [❌ Claude Code]
  → Arvin 看到红卡,立即知道需要重做第 15 天
  → 不需要重做前 14 天

Day 20:Task Card #20
  → 完成,卡片变为 ✅

最终:20 张卡片形成完整的执行历史,可视化汇总。

部署和实施步骤

第 1 步:确认 Task Card 基础设施

# 检查卡片存储位置
ls -la /tmp/task_cards/

# 查看卡片文件格式
cat /tmp/task_cards/sample_task.json

第 2 步:增强 Task Card 格式

在现有的 Task Card JSON 中增加:

{
  "claude_verification": {
    "status": "pending",
    "result": null,
    "note": null
  }
}

第 3 步:Claude Code 实现验证逻辑

  • 读取 /tmp/task_cards/ 中的卡片
  • 根据卡片的期望输出执行验证
  • 更新 claude_verification 字段
  • Critical 失败时发飞书通知

第 4 步:飞书卡片美化(可选)

  • 让卡片的颜色动态变化(绿/黄/红)
  • 或在卡片标题中加 Emoji 标记
  • 增强视觉反馈

结论

Task Card 监督机制不是一个复杂的新系统,而是充分利用已有工具的优雅设计

  1. 集中式信息:所有任务信息在一个地方
  2. 实时反馈:颜色和状态立即可见
  3. 持久记录:完整的执行和验证历史
  4. 支持长期任务:日拆分策略清晰可行
  5. 零额外工具:完全基于现有基础设施
  6. 心理激励:视觉化的成功和失败反馈

这是从"复杂的分布式验证"到"优雅的集中式监督"的设计演进。


关键词

多 Agent 协作、监督机制、Task Card、验证框架、可见性、持久化、OpenClaw、AI Agent 可靠性、分布式系统设计

Logo

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

更多推荐