跳转到内容

事件驱动 Agent 架构

事件驱动 Agent 架构

学习目标

读完本章后,你将能够:

  • 理解基于有向图的 Agent 事件传播模型
  • 设计 Event/Link/Agent 三元组架构
  • 掌握即时传播与定时传播的双模式策略
  • 了解事件生命周期管理与过期淘汰策略

核心概念

事件驱动 Agent 的本质

事件驱动 Agent 架构的核心思想是:Agent 之间不直接通信,而是通过事件作为中介进行异步交互

与直接调用的 Agent 协作模式不同,事件驱动架构有三个关键特征:

  1. 解耦:发送方不知道也不关心谁会接收事件
  2. 异步:事件的创建与处理不需要在同一时间发生
  3. 可回溯:事件持久化存储,支持事后分析和重放

Event/Link/Agent 三元组

事件驱动 Agent 系统由三个核心实体构成:

实体职责核心属性
Agent事件的创建者和消费者check(主动获取)、receive(被动处理)、create_event(创建事件)
EventAgent 之间的通信载体payload(JSON 数据)、expires_at(过期时间)、lat/lng(可选位置信息)
LinkAgent 之间的有向连接source(事件源 Agent)、receiver(事件接收 Agent)、event_id_at_creation(创建时的最新事件 ID)

有向图传播算法

传播流程的关键细节

  1. 水位线追踪:每个 Agent 维护 last_checked_event_id,只处理 ID 大于水位线的新事件,避免重复处理
  2. 创建时快照:Link 创建时记录 event_id_at_creation,忽略 Agent 连接之前的历史事件
  3. 批量传播:传播器按分钟级别批量扫描新事件,一次性推送给所有下游 Agent
  4. 即时传播:支持 propagate_immediately 标志,事件创建后立即触发下游传播,无需等待下一个传播周期

设计模式

模式一:事件过滤器

使用条件判断 Agent(如 TriggerAgent)在事件流中间插入过滤层,只允许匹配条件的事件继续传播:

模式二:事件聚合器

将多个来源的事件汇聚到一个 Agent 进行统一处理:

模式三:事件分支

一个 Agent 的事件同时分发给多个下游 Agent,各自独立处理:

模式四:事件去重

在事件流中插入去重层,避免下游 Agent 重复处理相同事件:


事件生命周期管理

事件过期与清理

事件不是永久存在的——每个事件都有 expires_at 字段,由创建者 Agent 的 keep_events_for 设置决定:

保留策略适用场景
永久保留(expires_at = nil审计日志、历史分析
短期保留(1 小时 ~ 1 天)实时告警、临时状态
中期保留(2 ~ 30 天)日报周报、趋势分析
长期保留(45 ~ 365 天)合规要求、年度对比

清理策略的实现要点

  • 定时任务(默认每 6 小时)扫描 expires_at < NOW() 的事件并删除
  • MySQL InnoDB 需排除最新事件(避免 AUTO_INCREMENT 计数器回退)
  • 清理后更新受影响 Agent 的 events_count 缓存列

反压机制

当事件产生速度超过消费速度时:

  • 丢弃策略:Agent 可通过 set_last_checked_event_id 跳过积压事件,从最新水位线开始消费
  • 批量消费receive! 方法一次性收集所有待消费事件,避免逐条查询

陷阱与对策

陷阱一:事件循环

当 Agent A → Agent B → Agent A 形成环时,事件会无限循环传播。

对策:在 Link 层面不做自动环检测,而是依靠 expires_at 自然终止。设计上应避免环,或在环中插入 TTL 限制的 Agent。

陷阱二:事件风暴

一个 Agent 短时间内产生大量事件,导致下游 Agent 队列积压。

对策

  • 限制 Agent 的 events_count 上限
  • 使用 DeDuplicationAgent 去重
  • 配置合理的 keep_events_for 避免存储膨胀

陷阱三:传播延迟

定时传播模式下(默认每分钟),从事件创建到下游 Agent 接收可能有最多 1 分钟的延迟。

对策:对低延迟场景使用 propagate_immediately 标志,事件创建后立刻触发传播。


设计取舍

数据库存储 vs 消息队列

维度数据库存储(如 Huginn)消息队列(如 RabbitMQ/Kafka)
持久性天然持久化,可回溯需额外配置持久化
延迟较高(轮询,分钟级)极低(推送,毫秒级)
复杂度低(复用已有数据库)高(需额外基础设施)
回溯天然支持 SQL 查询需保留策略支持
吞吐中等(受限于数据库写入)极高(百万级 TPS)

选择数据库驱动的原因:简单部署、天然回溯、中等规模场景足够。如果追求极低延迟或极高吞吐,应引入消息队列。

有向图 vs 工作流引擎

维度有向图(Link 连接)工作流引擎(如 LangGraph)
灵活性高(运行时可修改连接)低(图结构通常是预定义的)
可视化自动生成拓扑图需要显式定义
状态管理分散(每个 Agent 独立内存)集中(统一状态对象)
适用场景用户自定义自动化复杂的条件分支与循环

参考来源