Task Card 作为 AI Agent 监督机制的实现方案
Task Card 作为 AI Agent 监督机制的实现方案
文章主题:如何用已有工具(Task Card)替代复杂的分布式验证机制,构建一个简洁、可见、可靠的 AI Agent 监督系统。
问题背景
在构建多 Agent 协作系统时,一个核心问题是:如何验证执行者(Agent A)声称已完成的任务是否真的完成了?
典型的痛点
-
幻觉执行(Hallucination)
- Agent A 说"我已经发布了文章"
- 实际上:API 调用失败了、网络超时了、或者根本没有执行
- Agent A 可能根本不知道自己失败了
-
隐性故障(Silent Failures)
- 任务执行流程中某个环节悄悄失败
- 没有外部验证,无法发现
- 问题一直埋藏到最后
-
缺乏可见性(Low Visibility)
- 验证信息分散在多个地方(日志、文件、消息)
- 需要手动查询才能了解状态
- 不够直观、反应不够快
-
长期任务的持续监控
- 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 监督机制不是一个复杂的新系统,而是充分利用已有工具的优雅设计:
- ✅ 集中式信息:所有任务信息在一个地方
- ✅ 实时反馈:颜色和状态立即可见
- ✅ 持久记录:完整的执行和验证历史
- ✅ 支持长期任务:日拆分策略清晰可行
- ✅ 零额外工具:完全基于现有基础设施
- ✅ 心理激励:视觉化的成功和失败反馈
这是从"复杂的分布式验证"到"优雅的集中式监督"的设计演进。
关键词
多 Agent 协作、监督机制、Task Card、验证框架、可见性、持久化、OpenClaw、AI Agent 可靠性、分布式系统设计
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)