PluginsHooks

Effect

详细说明 effect 的副作用语义、失败影响,以及它为什么不是事件总线替代品

Effect

effect 的核心语义是:

  • 主值不变
  • 只做副作用

什么叫副作用

这里的副作用通常是:

  • 打日志
  • 记录观测态
  • 同步某个状态
  • 上报分析事件

也就是说,它不是为了“产出一个新结果”,而是为了“顺手做点事情”。

一个最小例子

await agent.plugins.effect("audit.observe", {
  event: "incoming_message",
  sessionId: "sess_001",
});

plugin 里可以这样定义:

hooks: {
  effect: {
    "audit.observe": [
      async ({ value, plugin }) => {
        console.log(`[${plugin}] observed`, value);
      },
    ],
  },
}

它和事件总线像,但不完全一样

很多人会把 effect 想成一个随便发事件的总线。

这个想法不算全错,但要注意两件事:

  • 它依然是宿主主动调用的一个命名点
  • 当前调用如果抛错,effect 调用本身也会失败

所以它不是那种天然“fire-and-forget、失败也无所谓”的消息队列。

多个 effect 怎么跑

如果一个点上有多个 effect handler:

  • 会按注册顺序依次执行
  • active plugin 的 handler 都会跑
  • 某个 handler 抛错时,当前 effect 调用会中断

最适合的场景

观测

例如:

  • 记录谁来过
  • 记录什么动作发生过

埋点

例如:

  • 某类功能被触发了几次
  • 某类错误出现在哪一步

同步

例如:

  • 把一份状态同步到另一个存储
  • 把一份事件写到审计日志

不适合的场景

想改值

改值应该用 pipeline

想阻断流程

阻断应该用 guard

想得到唯一答案

唯一答案应该用 resolve

一个现实建议

如果你的 effect 很关键,而且失败后必须重试、必须持久化、必须有可靠交付保证,那它可能已经不是一个简单 effect 能承担的事了。

这时更合适的分层通常是:

  • effect 只负责触发
  • 真正可靠处理放进 plugin lifecycle 或更完整的后台 runtime

相关场景