AI虚拟团队自动化进化:从“人盯人“到“自愈系统“

AI虚拟团队自动化进化:从“人盯人“到“自愈系统“

💡一句话总结:前三篇讲了架构、踩坑、通信。这篇讲实战进化——系统怎么从"人工调度"一步步变成能自动发现问题、自动修复、自动重试的"自愈系统"。核心是一个字:闭环


📌 前情回顾

  • 第一篇:我用4个AI搭了一个"虚拟开发团队"——架构overview
  • 第二篇:AI虚拟团队跑了一个月,我踩了这些坑——Agent撒谎、Gateway崩溃、任务卡死
  • 第三篇:AI虚拟团队的"神经系统"——消息总线、心跳检测、自动派发

这一篇讲从第三篇的"能跑"到真正"好用"之间,我做了哪些进化


🔴 问题一:心跳在跑,但超时任务没人管

现象

心跳每分钟跑一次,检测到任务超时(>5分钟),报告里写着"⏰ 小虾/FIX-xxx 超时11分钟"——然后呢?什么也没发生。

报告发给我看了,但系统不会自动处理。我还是得手动去唤醒小虾、取消旧任务、重新派发。

根因

心跳脚本的超时处理只做了"诊断",没做"修复":

# 旧代码:只ping一下,然后重发消息defdiagnose_and_fix_timeout(agent,task_id,elapsed):result=subprocess.run(['openclaw','agent','--agent',agent_id,'-m','ping','--timeout','15000'])ifresult.returncode==0:# 重新发消息...但没清理旧状态subprocess.run(['openclaw','agent','--agent',agent_id,'-m',content,'--timeout','120000'])returnTrue,"重新派发任务"

问题:

  1. 没取消DB里的旧任务记录(status还是pending)
  2. 没清理inbox里的旧文件(新消息和旧消息混在一起)
  3. 没通过正式流程重新派发(直接发消息,不写DB)
  4. Agent可能根本没收到(消息堆积在inbox里)

修复:4步完整流程

defdiagnose_and_fix_timeout(agent,task_id,elapsed):"""诊断超时原因并自动修复:取消旧任务 → 清理inbox → 重新派发 → 唤醒Agent"""# Step 1: 取消旧DB记录db=sqlite3.connect(TASKS_DB,timeout=5)db.execute("UPDATE tasks SET status='cancelled' WHERE task_id=? AND status='pending'",(task_id,))db.commit()db.close()# Step 2: 清理旧inbox文件(保留.done)inbox_dir=f"{SYNC_DIR}/inbox/{agent_id}"forfinos.listdir(inbox_dir):iftask_idinfandf.endswith('.json')andnotf.endswith('.done'):os.remove(os.path.join(inbox_dir,f))# Step 3: 重新派发(通过send_task.py正式流程)subprocess.run([sys.executable,'send_task.py','小密',agent,task_id,'1',f'超时重派:{task_id}'])# Step 4: 唤醒Agentsubprocess.run(['openclaw','agent','--agent',agent_id,'-m','ping','--timeout','15000'])

关键变化:从"诊断+重发消息"变成"取消→清理→正式派发→唤醒"。每一步都有副作用,但每一步都是必要的。


🔴 问题二:Agent完成了,但测试没自动派发

现象

小虾完成开发任务,.done文件有了,但小牛没收到测试任务。我得手动写测试MD、手动派发。

根因

自动派发逻辑auto_dispatch_tests_for_completed_dev()本身没问题——它会扫描小虾inbox的.done文件,检查小牛inbox有没有对应的TEST-{task_id}文件,没有就自动派发。

问题出在触发时机

  1. 我直接用openclaw agent --agent main -m "执行任务"唤醒小虾
  2. 小虾执行完,创建了.done文件
  3. 但心跳没运行(或者在grace period内)
  4. 自动派发逻辑没机会执行

为什么心跳没运行?

心跳有个"grace period"机制——每次唤醒Agent后180秒内,跳过某些操作避免重复。但这个机制太粗暴,把自动派发也一起跳过了。

而且更根本的问题是:我绕过了心跳流程。直接openclaw agent执行任务,心跳根本不知道发生了什么。

教训

自动化系统的每条路径都必须经过同一个"中枢"。不能有"后门"——即使你是管理员。否则中枢的自动逻辑就形同虚设。


🔴 问题三:报告格式"说一套做一套"

现象

心跳报告显示"✅ 所有任务已完成",但下面还有一堆注意事项。或者报告里有"📋 自动创建测试待办: TEST-xxx"这行字,但不在注意事项区域,而是单独出现在报告上方。

根因

两个独立的bug:

  1. 逻辑矛盾:当有notes时,报告仍然显示"✅ 所有任务已完成"
  2. 输出位置错误ensure_test_todos_exist()直接print()到stdout,显示在报告上方而非注意事项区域内

修复

# 修复1:有notes时不显示"全部完成"iftotal==doneandnotnotesandnottimeout_tasks:lines.append("✅ 所有任务已完成")# 修复2:把print改成返回notes列表defensure_test_todos_exist(replies):msgs=[]forreplyinreplies:# ... 检查逻辑 ...msgs.append(f"📋 自动创建测试待办: TEST-{task_id}")returnmsgs# 返回列表,由heartbeat收集到notes# heartbeat中:notes.extend(auto_pipeline.ensure_test_todos_exist(replies))notes.extend(auto_pipeline.ensure_fix_todos_exist(replies))

关键原则:所有用户可见的信息,必须经过同一个格式化函数。不能有"旁路输出"。


🔄 闭环设计的核心模式

经过这几轮迭代,我总结出一个"自愈闭环"的标准模式:

┌─────────────────────────────────────────────────┐ │ 心跳中枢 │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ 检测状态 │→│ 自动决策 │→│ 执行动作 │ │ │ └──────────┘ └──────────┘ └──────────┘ │ │ ↑ ↓ │ │ ┌──────────┐ ┌──────────┐ │ │ │ 收集结果 │←────────────────│ 通知用户 │ │ │ └──────────┘ └──────────┘ │ └─────────────────────────────────────────────────┘

4个必要环节

环节作用缺失后果
检测状态扫描inbox、DB、.done文件不知道发生了什么
自动决策判断该做什么(重试/派测试/归档)检测到了但不处理
执行动作取消旧任务、派发新任务、唤醒Agent决策了但没执行
通知用户汇报结果和异常执行了但用户不知道

每个环节的常见坑

环节解法
检测检测到但被grace period跳过grace只跳过唤醒,不跳过核心逻辑
决策决策正确但走了旁路(直接print)所有输出必须经过统一的format函数
执行执行了但状态没同步(DB和inbox不一致)每个操作都有对应的状态清理
通知通知了但信息矛盾("已完成"和"有警告"同时出现)互斥信息不能同时显示

📊 进化前后的对比

指标v1 手动调度v2 基础心跳v3 自愈闭环
超时处理手动唤醒报告超时自动取消+重派
测试派发手动写MD+派发手动自动检测+补派
报告准确性N/A偶尔矛盾严格一致
人工干预频率每个任务2-3次偶尔(~30%)极少(~5%)
系统"死"的概率

💡 给想做类似系统的人的建议

  1. 闭环必须完整:检测→决策→执行→通知,缺一不可。缺了"执行"就是空谈,缺了"通知"就是黑盒。

  2. 不要有旁路:所有操作必须经过同一个中枢。你手动操作一次,就可能绕过自动逻辑一次。

  3. 状态必须一致:DB里的状态、inbox里的文件、.done标记,三者必须同步。任何一个不一致都会导致"幽灵任务"。

  4. 报告不能自相矛盾:用户看到的每一行信息都必须是真实状态的反映。"已完成"和"有警告"不能同时出现。

  5. grace period要精细:不能一刀切跳过所有操作。应该只跳过"重复唤醒",不跳过"核心逻辑"。

  6. 自动化的代价是复杂度:每加一个自动逻辑,就多一个可能出bug的地方。但不出bug的自动化不叫自动化,叫脚本。


如果这篇文章对你有帮助,欢迎点赞收藏。有问题可以在评论区交流。