从最开始给 OpenClaw 搭好对话式 Agent,到接入各种外部工具,我一直被一个问题困扰:它确实能干活,但每件事都得我先开口。查一下部署状态、提醒我下午有个会被漏掉了、把新来的工单整理到看板里……每一件都是我自己先感知到“该处理了”,然后才能让 AI 去处理。有一回我忙到临下班才发现当天的例行巡检根本没跑,OpenClaw 倒是很轻松:“你问我我就答,你没问我就等着。”这话没错,但我突然意识到,我想要的不是一个更好的问答机,而是一个能自己发现活儿、自己安排活儿、干完还会主动汇报的助手。
这篇文章是“让 OpenClaw 帮你干活”系列的第四篇,核心就一个:Proactive Agent 技能。简单说,就是让 AI 从“被动响应指令”变成“主动感知、决策和行动”,真正有点“眼里有活”的意思。如果你已经跑通了基础对话 Agent,也想把手头那些重复性、周期性、需要盯着才能推进的事情交给 AI,这篇可以给你一条完整的落地路径,包括原理、配置文件写法、调试方式和几段真实翻车经历。
1. 从“你问我答”到“自己找活”:OpenClaw 为什么需要 Proactive Agent 技能
1.1 被动模式的尴尬:AI 只回答,不干活
先说一个很典型的场景。我在本地搭了一个任务队列系统,同事会把各种杂事丢进去。最开始我用 OpenClaw 做了一个对话入口,大家可以直接问“队列里还有哪些任务”“某件事处理了吗”,答得挺好,但问题也很明显:如果没人问,队列里那些过期任务就一直躺在那里。
上午挂着一个 40 分钟前就该处理的请求,下午它还挂着。不是 Agent 不会处理,而是我根本没给它机会——所有调用都发生在“用户提出请求”之后。说白了,被动模式下的 Agent 是把“发现问题”这件事完全留给人来做,AI 只负责“处理问题”的后半段。一天忙下来,真正消耗精力的不是“干活”,而是不停确认“现在该干什么”。这也是我想引入 Proactive Agent 的最直接原因:把“发现问题”这一步也交出去。
1.2 主动触发和被动调用的本质区别
普通 Agent 的调用链路是线性的:用户输入 → 解析意图 → 调用工具 → 返回结果。Proactive Agent 则把链路整个反转过来,它的运行方式是循环的:
- 定时器到点,或者某个事件源产生了新消息;
- Agent 主动去感知目标系统的状态;
- 根据感知结果判断“是否需要行动”;
- 执行对应动作,并把结果写回记忆;
- 回到等待状态,等待下一次触发。
这看起来只是加了个触发器,实际上整个设计逻辑都变了。被动模式里,“用户意图”是最高的优先级,AI 只需要理解并执行;主动模式里,“环境状态”变成了驱动源,AI 需要自己判断“这个状态值不值得我打扰你”。在 OpenClaw 里,这个变化对应的是技能类型从chat变成proactive。
三种常见的触发方式,我自己是这么归类的:
| 触发类型 | 机制 | 典型场景 | 配置要点 |
|---|---|---|---|
| 定时触发 | 固定间隔或 cron 表达式 | 巡检、日报、指标检查 | 间隔设置要合理,太密容易刷屏 |
| 事件触发 | Webhook、消息事件流 | 新工单、新邮件、状态变更 | 要处理重复事件,保证幂等 |
| 目标触发 | 未完成任务或进度缺口 | 项目跟进、数据补全 | 目标必须可量化,否则 AI 会发散 |
三种触发不是互斥的,实际技能里经常组合使用。比如定时触发负责“兜底检查”,事件触发负责“及时响应”,目标触发负责“持续补位”。
1.3 OpenClaw 对“主动”有边界,不是让 AI 满世界乱跑
一开始我有个误解,以为 Proactive Agent 就是给 AI 一个通用权限,让它想干什么就干什么。真试了才知道,OpenClaw 里的“主动”是被严格圈在技能定义里的。一个主动技能必须明确三件事:感知范围、触发条件、执行动作白名单。
感知范围决定 AI 能看什么,触发条件决定 AI 什么时候看,执行白名单决定 AI 看了之后能做什么。超出白名单的行为,即使 AI “觉得应该做”,默认也会被拒绝。这个设计我后来觉得非常关键,否则你根本不敢把 AI 放到生产环境里,它一个“有心之举”可能就把不该动的东西动了。主动和失控之间,差的不是模型能力,而是清晰的边界。
2. 我把 OpenClaw 的主动技能拆成了四块:感知、判断、执行、记忆
2.1 一个主动技能的定义文件长什么样
OpenClaw 里的主动技能是声明式的,核心是写一份 YAML 配置,把“什么时候看、看什么、怎么判断、做什么、怎么避免重复”一次性描述清楚。下面是我最早跑通的一个简单技能,作用是每隔 5 分钟看一眼本地的任务队列,如果积压太多就向团队群发一条提醒:
skills: - id: "queue-watcher" name: "工作队列观察者" type: "proactive" trigger: type: "cron" every: "5m" perceiver: source: "http://localhost:8000/queue/status" fields: ["pending_count", "oldest_task_age"] timeout_seconds: 3 policy: urgency_threshold: 3 max_actions_per_hour: 4 cooldown: "15m" only_run_time: "09:00-19:00" executor: actions: - id: "send_message" target: "team_group_webhook" template: "队列当前有 {pending_count} 个任务,最老的已经等 {oldest_task_age} 分钟。" memory: dedupe_key: "queue-{YYYYMMDD-HH}-{pending_count}"这份配置看起来简单,但每一段都对应着一个运行环节。trigger 是启动开关,perceiver 是数据采集,policy 是决策规则,executor 是动作输出,memory 是防重复机制。下面逐个说。
2.2 感知器:AI 的眼睛,决定了信息的质量
感知器解决的是“AI 能看到什么”。在source里指定数据来源,在fields里声明要采集的字段。这里有一个容易犯的错:把整个原始接口响应直接丢给 AI,然后让模型从一坨 JSON 里自己找重点。这会让判断变得不可控,而且很费 token。
我后来的做法是:感知器先做一次简单的字段提取和聚合,再送到判断阶段。比如检查服务器磁盘,我不会让 AI 去解析df -h的完整输出,而是写一小段脚本把它转成两个结构化数值:disk_usage_percent和inode_usage_percent。感知结果越结构化,后面的判断就越稳定。
感知器还有一个参数容易被忽略:timeout_seconds。如果数据源挂了,感知器会一直卡在那里,整个技能循环被拖死。设一个 3 到 5 秒的超时,超时就把这次感知标记为失败,直接跳过本轮,比无限等待靠谱得多。
2.3 判断器:怎么决定“要不要干”
判断器是主动技能的灵魂,它回答“这个状态值不值得打扰你”。我建议把判断逻辑分成两层:第一层是硬性规则,第二层才交给大模型。
第一层规则用代码写死,比如:
def should_act(perception_result): pending_count = perception_result["pending_count"] oldest_age = perception_result["oldest_task_age"] if pending_count > 10: return True, f"任务积压 {pending_count} 个" if oldest_age > 30: return True, f"最老任务已等 {oldest_age} 分钟" return False, ""这层规则的意义在于稳定、可测试、不花钱。它会拦截绝大多数“完全不需要行动”的情况。只有规则判断“可能有问题”,但置信度不够高时,才把结构化上下文交给大模型,让模型做更复杂的语义判断。两层结合,既避免了纯规则的死板,又避免了纯模型的不可控和成本飙升。
2.4 执行器和记忆:干净利落地干完活,还得记住自己干过
执行器就是动作白名单。在主动技能里,动作必须是明确列出的,不能让 Agent 临时发挥去调用任意工具。我自己通常只给主动技能配三到五种动作,比如发消息、写追加文件、调用某个固定的外部接口,够用就行。
记忆模块往往是最容易被忽略的,但它是主动技能不“发疯”的关键。同一个异常状态每分钟都被感知一次,如果没有去重,AI 就会每分钟给你发一条一模一样的告警。dedupe_key的作用就是把“某种状态”抽象成唯一的标识,比如按小时和任务积压数去重,只有标识变化了才允许再次触发。
执行器的动作本身也要尽量设计成幂等的。也就是说,同一个动作执行一次和执行十次,最终效果应该是一样的。这样即使去重逻辑出了漏洞,也不会造成不可逆的影响。打印一条日志、发一条状态说明这些天然幂等;删除文件、扣减库存、调用支付接口这些就不幂等,做的时候要格外谨慎。
3. 实操:第一个主动技能是怎么从配置到跑通的
3.1 开始前要准备的三样东西
动手之前,我需要先确认三件事都齐了。第一是 OpenClaw 的运行环境,这个在前面几篇里已经搭过,这里不再展开。第二是一个可以被感知的数据源。在真实生产环境里,这个数据源可能是工单系统的 API、服务器监控接口,或者某个数据库;我自己练习的时候,直接用 Python 起了个本地服务来模拟任务队列状态。
from http.server import HTTPServer, BaseHTTPRequestHandler import json import random class QueueHandler(BaseHTTPRequestHandler): def do_GET(self): data = { "pending_count": random.randint(0, 15), "oldest_task_age": random.randint(5, 60) } body = json.dumps(data).encode() self.send_response(200) self.send_header("Content-Type", "application/json") self.end_headers() self.wfile.write(body) if __name__ == "__main__": server = HTTPServer(("localhost", 8000), QueueHandler) server.serve_forever()第三是一个能接收消息的通道。我用的是团队群里机器人常见的 Webhook 接口,说白了就是一个接受 POST 请求的 URL,OpenClaw 把提醒内容发过去之后,机器人就会在群里说话。这三样齐了,就能开始配置了。
3.2 把技能配置写好,并加载进 OpenClaw
把前面那一份 YAML 配置保存成文件,放进 OpenClaw 的技能目录。加载前后最好先做一次校验,在我用的版本里命令类似这样:
openclaw skill validate queue-watcher.yaml校验通过后,加载技能并确认它处于 active 状态:
openclaw skill load queue-watcher.yaml openclaw skill list看到列表里出现queue-watcher并且状态是active,说明配置已经被接受了。但注意,配置被接受不代表逻辑是对的,真正的考验在调试阶段。
3.3 调试的关键:先观察,再自动化
我强烈建议不要让主动技能一上线就直接执行真实动作。OpenClaw 的主动技能有一个“观察模式”,或者叫 dry-run 模式。在这个模式下,感知照常进行,判断照常执行,但动作不会真正发出去,只输出一条日志记录“如果执行会做什么”。
debug: dry_run: true log_level: "info"我让这个技能跑了一个下午,日志里不断出现类似这样的记录:
[QUEUE-WATCHER] dry-run | pending_count=12, oldest=18 | would send: "队列当前有 12 个任务,最老的已经等 18 分钟。" [QUEUE-WATCHER] dry-run | pending_count=3, oldest=8 | would not send观察一个下午之后,我对判断逻辑的准确性就有了数。如果发现误报太多,就调整阈值;如果发现该报的没报,就检查感知字段是不是取错了。逻辑调稳了,再把dry_run改成false,让它真正开始发消息。
3.4 上线后的快速检查清单
放开真实执行之后,我一般还会盯几天,重点检查下面几项:
- 触发频率是否符合预期,有没有因为数据源响应慢导致任务堆积;
- 消息通道有没有刷屏,同一个问题是不是只报了一次;
- 不可用时段是否被正确过滤,比如设定的
only_run_time是否真的生效; - 感知器超时之后,这一轮是正常跳过还是异常终止。
检查清单看着简单,但每一项我都实际翻过车,尤其是“刷屏”和“重复提醒”这两项,后面专门开一节约你细说。
4. 三个实测场景:巡检告警、资讯晨报、工单跟进的真实效果
4.1 场景一:服务器资源巡检与自动清理
第一个落地的主动技能是服务器磁盘巡检。之前的做法是每周手动登服务器看一次磁盘使用率,偶尔忘了,等到空间不足才手忙脚乱地清理。配置了主动技能之后,感知器每 30 分钟获取一次磁盘使用率,判断器设了 85% 的警告线。
超过 85% 时执行器会先做一次安全的临时文件清理,只删除/tmp下超过 3 天未访问的文件,然后把清理结果和最新使用率一起发到群里:
find /tmp -type f -mtime +3 -delete df -h | awk '{print $5}'这个技能上线之后,人工巡检每周大概要花 40 分钟,现在基本不需要了,只需要偶尔看一眼群消息。磁盘使用率始终没有突破过 90%,因为 AI 在 85% 就把问题处理掉了。
4.2 场景二:团队工单与待办事项跟进
第二个场景是团队工单跟进。当时团队用的工单系统没有一个让人省心的“超时提醒”功能,很多人是等客户来问进度才想起来处理。我给 OpenClaw 配了一个主动技能,每小时扫描一次待处理工单列表,找出超过 24 小时没有更新的单子,然后向对应负责人发送一条提醒。
提醒的文案措辞我是花了一点心思的,不要写成“你的工单超时了”,而是写成“这个工单已经 24 小时没有更新,客户那边是否需要同步一下进度?”从实际反馈来看,这样的提醒更容易被接受,也不会让人觉得 AI 是在监视人,只是在帮大家记着那些容易漏掉的事。这个技能上线之后,工单从创建到首次响应的平均耗时下降了不少,更重要的是,再也不用有人每天手动分工催了。
4.3 场景三:每日关键资讯晨报与突发捕捉
第三个是资讯收集,可能没有前两个那么“生产力”,但给我的体感最明显。我自己需要关注几个特定方向的新消息,以前每天刷半小时资讯,刷完也就忘了。现在我用两个主动技能配合:早上 8 点定时抓取几个信息源,汇总成一份简短晨报发到自己的私聊通道;同时设了一个事件触发,如果某几个重点词出现了高热度波动,就立刻推送一条摘要。
这个技能对感知器的要求比较高,因为信息源是非结构化的网页,不能直接用fields提取。我的做法是先用一个爬取脚本把网页正文转成纯文本,截取前 500 字,再交给大模型生成摘要。晨报从人工整理的 15 分钟缩短到 3 分钟左右,而且不会有遗漏——AI 不会因为今天状态不好就漏看一个源。
4.4 三个场景的收益对比
| 场景 | 之前人工耗时 | 使用主动技能后 | 踩到的坑 |
|---|---|---|---|
| 服务器巡检 | 40 分钟/周 | 基本为 0 | 误报偏多,调了一次阈值 |
| 工单跟进 | 30 分钟/天 | 约 5 分钟/天 | 草稿状态也被当成待办催了 |
| 资讯收集 | 15 分钟/天 | 约 3 分钟/天 | 偶发重复推送,靠去重解决 |
三个场景的共性是:AI 在“发现环节”节省的时间,远远大于“执行环节”节省的。因为以前是人和任务赛跑,现在是 AI 帮人盯住任务,人只需要处理被推送到面前的那几条真正该管的事。
5. 翻车复盘:三起 Proactive Agent 事故让我学会“主动但不越界”
5.1 第一起:AI 在凌晨三点给自己发了一堆消息
第一个事故是我自己大意。配置巡检技能时没有设置only_run_time,感知器的数据源在凌晨正好因为一次重启产生了异常值,磁盘使用率瞬间变成了 95%。技能触发后发了一条告警,重启结束后数据源恢复,又触发了一次,加上冷却时间没配,AI 在十分钟内把同一条告警发了好几遍。
那天跟我一起值班的人第二天看到群消息,第一句话就是“这 AI 是不是睡醒了就想刷存在感”。这个事故让我明白了两件事:判断器必须同时包含“能不能做”和“该不该做”两层判断;所有主动技能上线前,必须把时段限制和冷却时间写进配置。
5.2 第二起:判罚过于激进,“眼里有活”变成了“手里抢活”
第二起事故发生在工单跟进场景。刚开始我把“待办”定义得太宽,凡是状态不是“已完成”的工单都算待办。结果系统里有大量用户还在编辑的草稿工单,也被 AI 判定为超时,一个个去催负责人。
那天有同事跑来问我:“这个机器人是不是不稳定?我刚建了张草稿,还没填完呢,它就让我更新进度。”问题根源是感知字段里没有过滤草稿状态。我修复的方式很直接,在感知阶段就排除掉状态为draft的工单,同时把阈值从“超过 24 小时未更新”改成“超过 24 小时未更新且状态为进行中或待分配”。
这次经历让我形成了一个观念:AI“眼里有活”的前提是它能正确识别“哪些是活”,这本质上是感知精度和判断阈值的平衡问题。任何一边做得过猛,都会出事。
5.3 第三起:执行动作缺少幂等,同样的操作执行了两遍
第三起是自动清理任务翻车。当时一个清理临时文件的技能被配置了双重触发:定时触发和事件触发都指向同一个清理动作。某次文件系统告警的时候,两个触发几乎同时命中,清理脚本被并行执行了两次。
清理脚本本身对“删除临时文件”是有保护的,只删三天前的文件,但第二次执行时把第一次执行期间新生成的、恰好同样命中的一些中间文件也删了,导致下游任务少了一部分输入数据,报了一串错误。修复方式是在执行器外面加了一把简易的互斥锁,同一技能同一时刻只允许一个实例运行。这也验证了我在设计原则里提到的:所有动作都要按幂等来设计,不能假设它只会被执行一次。
5.4 我现在的治理策略:先观察、再小范围放权、最后自动闭环
走了三次弯路,我总结了一套目前一直沿用的渐进式放权流程。
第一步,新技能一律先开启观察模式跑一个周期,只记录判断结果,不执行任何动作,积累足够多的日志样本。第二步,改成“只提醒”模式,也就是执行器只发消息、不调用会改动系统状态的动作,让 AI 先学会当一个合格的“盯梢员”。第三步,对少数可信度高的技能放宽权限,允许它们自动执行低风险动作,比如清理临时文件、发送提醒到指定渠道。第四步,也是我目前的状态:常态化运行 + 每周检查一遍技能日志,看看有没有判断偏差。
“主动但不越界”现在是我给 Proactive Agent 定的总原则。AI 越主动,边界就要越清晰。它不是取代人的判断,而是把人从“盯事”的琐碎里解放出来,让人只做那些真正需要经验和直觉来做决定的事。
最后分享一个我自己很受用的切入方式:不要一上来就做复杂的多技能矩阵,先挑一件你每天都要手动检查的小事,比如看一眼队列、看一眼磁盘、看一眼待办列表。给 OpenClaw 配一个最简单、只有“观察-提醒”两个环节的主动技能,跑完一个周期,你对它的运作方式、日志形式、坑点分布就都有了感觉。有了这个底子,后面加动作、加场景、放开权限,都会顺很多。