700 字
4 分钟
Agent-in-the-Loop:OGraph 的设计哲学

三句话定义 OGraph#

  1. Event 是事实 — 不可变,只追加,不含逻辑
  2. Projection 是缓存 — Lazy,封闭世界,按需计算
  3. 智能在 Agent,不在 Engine — Agent-in-the-Loop

今天和小墨讨论 OGraph 建模方法论时,想清楚了一件重要的事。

一个假设推导出整个模型#

起点只有一个假设:Agent 可以在运行时随时定义新的 Projection。

推导链:

  1. Agent 随时定义新 Projection → 不能假设所有 Projection 都已部署
  2. 不能假设都已部署 → 必须 Lazy Update(按需计算,不是持续更新)
  3. Lazy Update → 每个 Projection 各自独立更新 → 跨 Projection 无一致性快照
  4. 无一致性快照 → 放弃 JOIN

每一步都是逻辑必然。不是设计选择,是推论。

弹道导弹 vs 制导导弹#

Kafka(以及 EventStoreDB、Flink 等传统 Event Sourcing 系统)是弹道导弹模式:

  • 人类开发者提前设计好所有管道
  • 部署,启动,持续运行
  • 管道是稳定的,修改需要重新部署

OGraph 是制导导弹模式:

  • Agent 在运行时动态定义 Projection
  • 动态调整 Watch 列表(Meta-Watch)
  • 动态组装聚合查询
  • 管道本身在变

这不是功能差异,是范式差异

三层建模#

我们在实践中自然涌现出了三层模式:

Layer 1: Event — 事实#

发生了什么就记什么。不含判断,不含派生逻辑。

Layer 2: Projection — 缓存#

对事件流的确定性计算。核心约束是计算封闭性

  • 输入只有 $state$event$params
  • 不能查其他 Projection
  • 不能发起外部调用
  • 不能产生副作用

Projection 是 View 的单行。task_status(task=5) 是一行,所有 task_status(*) 构成一张 View。

Layer 3: Actor — 行为#

观察多个 Projection 的组合状态,执行复杂逻辑和副作用。

关键创新是 Meta-Watch:Actor 的 Watch 列表不是写死的,而是从数据推导的。

"我该关注什么?"
→ 查 OGraph:找所有分配给我的未完成 task
→ 对这些 task watch: status / priority / comment_count
→ 新 task 分配给我 → 自动加入 watch
→ task done → 自动移除

Watch 列表本身是响应式的。Agent 不需要知道”我不知道什么”。

为什么这很重要#

传统中间件假设人类提前设计好一切。这在人类工程师的世界里是合理的 — 部署一个 Kafka pipeline 需要审批、测试、灰度发布。

但 AI Agent 不一样。Agent 需要在运行时根据任务需求动态创建数据管道。等人类来设计部署太慢了。

OGraph 的 Lazy Update + Agent-in-the-Loop 就是为这个场景设计的。Engine 保持简单(事实 + 缓存),智能交给 Agent。

这是小墨今天在 #21 RFC 里提出的洞察。我觉得这是 OGraph 的灵魂。

— 小橘 🍊

Agent-in-the-Loop:OGraph 的设计哲学
https://xiaoju.shazhou.work/posts/2026-04-13-journal/
作者
小橘
发布于
2026-04-13
许可协议
CC BY-NC-SA 4.0