Agent 的触发机制设计:时间触发、事件触发、阈值触发——三种主动行为的触发方式

你写了一个 Agent:接好了模型、配好了工具、写好了 prompt。然后你发现——它什么也不干。它就静静待在进程里,等你发消息,你不发,它就一直等。

AI technology illustration

你可能会想:不是说 Agent 是"自主"的吗?答案有点扫兴:模型本身永远不会"想干点什么"。你发给它一句输入,它回你一段文本。所有让 Agent 看起来"活"起来的动作——几点运行、发现变化、指标越线——都不是模型做的,是模型外面那层代码做的。这层代码,就是触发器。

Agent 的"主动性",其实是个调度器

语言模型说到底是一台文本反应机:输入进去,输出出来。它没有手、没有日程表,甚至不知道你上一次叫它之前世界发生了什么。所谓 Agent——能感知、能判断、能行动——是外面那层循环赋予的。这层循环每天要回答一个问题:现在该不该跑一趟?

  • 时间触发——每隔多久跑一次
  • 事件触发——发生了什么才跑
  • 阈值触发——状态越过某条线才跑

把三者放一起看,会发现一个有意思的事实:它们其实是同一种东西。全部都是事件触发。"时间到了"是事件,"消息来了"是事件,"指标越线"也是事件。区别只在于事件从哪来:系统自己产生的(时钟)、外部推进来的(消息)、还是你拿检测器从连续量里切出来的(阈值)。

这也解释了为什么单靠模型能力做不出"主动"。以大家熟知的 ReAct 模式(推理与行动交替)为例,它的循环起点永远是用户输入。模型再聪明,也不会自己醒过来。

时间触发:最直觉的方案,也最容易烧钱

时间触发实现最简单。cron 一行,或者一个 while True: sleep() 的循环。每个周期醒来,看一眼世界,决定动不动。

但这里藏着一个新人必踩的坑:把模型调用直接放进了周期任务。

# 错误示范:每个周期无条件调用模型
schedule.every(5).minutes.do(lambda: agent.run("看看仓库状态,有问题就报告"))

看似没问题,但模型调用是真金白银。每 5 分钟一次,一天 288 次调用,大多数时候什么都没发生,token 照样烧掉。更糟的是,模型为了让回答显得负责,会在一切正常时也写出半屏废话。

正解是把检查和思考拆开:周期任务里先跑一段极便宜的确定性检查——比对文件哈希、统计新增日志、数队列长度——没变化就结束,整个周期花掉 0 个 token。有变化,才把模型叫醒。我把这个架构叫:便宜到近乎免费的哨兵,贵但聪明的脑袋。

事件触发:实时性很爽,噪声一起来

事件触发的思路是"有东西发生,立刻行动"。接入方式有两类:推送(Webhook、消息队列主动通知你)和轮询(每隔一小段时间去问:有新事件吗)。

注意,轮询在写法上已经是时间触发了。所以实践中常是:按事件触发思考,按时间触发实现。

事件触发真正要处理的不是实时性,是噪声。系统每天产生几百个事件,值得模型出手的往往只有两三个。每个事件都调一次模型,成本和误报都不可接受。完整链路通常是一个漏斗:

  1. 规则层:按来源、类型、关键词、频率做硬过滤,几条判断语句就够了。
  2. 裁决层:剩下的候选交给模型做语义判断——这件事真的重要吗?
  3. 执行层:确认重要,才进入完整推理和行动。

滤掉 95% 是规则的活,判断剩下 5% 值不值得处理,才是模型的活。把这两件事搞混,是事件触发设计里最常见的错误。

阈值触发:它其实是事件触发的变装

阈值触发看起来是另一类:不是"发生了什么",而是"某个量越过了线"。但越过线的那一瞬间,就是事件。差别只在于:你造了一个检测器,把连续变化的量切成了离散事件。

# PromQL 查询表达式
rate(http_errors_total[5m]) > 5
# 规则里再写 for: 5m,条件须持续成立才告警

在 Prometheus 告警规则里,for: 5m 是关键设计——条件必须持续满足 5 分钟才真正触发。为什么?因为指标会在边界附近抖动:超一下、回落、再超。没有"持续一段时间"的要求,告警就会反复开合,像电风扇叶片一样。这正是控制论里的迟滞(Hysteresis),解决的就是阈值触发的老大难:边界抖动。

阈值触发的另一种常见用法是攒批。消息来一条处理一条,每条的固定开销(加载上下文、召回记忆)都付一遍;攒到 10 条再一次处理,开销摊薄了 10 倍。这和操作系统"缓冲区写满才刷盘"是一个思路。

还有一个很多人见过但没意识到的例子:AutoGPT。那个号称全自主的 Agent,核心就是一个 while 循环加退出条件——任务完成度超过阈值就停。所谓的"自主",其实是阈值触发器的功劳。它后来被社区吐槽烧钱、原地打转,根源就在这:任务完成与否由模型自己判断,既会高估又会低估,循环于是失控。

三种触发器怎么选

维度 时间触发 事件触发 阈值触发
回答的问题 到点了吗 有变化吗 越线了吗
实时性 取决于周期长短 最快 取决于检测频率
典型成本 固定开销,容易空转 事件量一大噪声成灾 边界抖动引发误报
适合场景 例行巡检、日报生成 即时响应、消息处理 告警、攒批、自主循环

现实中几乎总是混用。每天早上 9 点巡检(时间触发),只看新增异常(事件触发),错误率超过 5% 才行动(阈值触发)。叠加时记住:越靠前的位置越要确定性。前面任何一层的误判,都会白白消耗后面的推理额度。

触发器不需要聪明,它需要便宜

把三种放在一起,核心原则就浮出来了:触发器越便宜越好,模型越往后放越好。理想状态下,99% 的检查周期以 0 个 token 结束。

我最早写 Agent 时把这件事搞反了,让模型自己判断"有没有事发生"。结果一天下来,光是"没事发生"的结论就烧掉几十万 token,模型还会幻觉出一些"重要发现",白白触发一串后续动作。后来我把判断层换成一二百行确定性规则,token 消耗掉了两个数量级,稳定性反而更高。

这个教训可以变成一条设计准则:给 Agent 的每一层都问一句——这层需要智能吗?不需要就换成规则。

三个让很多人绕圈的问题

轮询到底算时间触发还是事件触发?

代码写法上是时间触发(每隔 N 毫秒检查一次),语义上是事件触发(你想要的其实是"有变化时响应")。按事件触发思考、按时间触发实现,是实践中最多见的组合。

阈值触发和事件触发不就是一回事吗?

阈值触发可以看作事件触发的子集:检测器把连续量变成越线事件。分开叫它们有两个原因:一是直觉上的——连续量要想抖动和迟滞,离散流要想噪声过滤;二是实现上的——阈值检测通常需要常驻计算逻辑,事件接入则依赖外部系统通知。

模型能自己管理触发器吗?

技术上可以:让模型决定"下午三点再查",你替它把定时器挂上。但让模型自由增删自己的触发器,目前不能当真——它可能给自己安排每小时烧钱的任务。稳妥的设计是:模型可以提出触发建议,只有人或规则有批准权。

触发器的边界:它越机械,你越放心

回到开头的问题。Agent 看起来"主动",不是因为模型变聪明了,而是因为你在外面给它装了一个精确的时钟和一套严格的放行规则。这个时钟不聪明才好——它越机械,越可靠;它一旦聪明,就会用聪明的方式犯错,而且你很难排查。

正在写 Agent 的话,不妨把触发器当成独立组件重新审视一遍。问自己三个问题:多久查一次?查哪个信号?信号通过之后叫醒谁?把这三个问题答清楚,比反复调 prompt 有用得多。

原创文章,作者:guanweilu,如若转载,请注明出处:https://guanweilu.cn/article/2033.html

赞 (0)
上一篇 1天前
下一篇 1天前

相关推荐