Skip to content

路由与并发

Easy-Agents 支持多父节点场景的执行阻塞与放行策略,确保子节点在依赖满足时被正确触发。

概念

  • 多父阻塞(All Parents Done)
    • 子节点只有在所有父节点完成后才允许被调度。
  • 任一父放行(Any Parent Allowed)
    • 当存在多条父链路时,只要符合预设规则的任意一条父链路允许,即可放行子节点。
  • 调度状态
    • parentsLeft:每个子节点仍需等待的父节点数。
    • allowedByAnyParent:是否已有父链路满足放行条件。

RouteOption 核心(路由条件)

  • 定义:RouteOption 封装“是否放行到某个子节点”的条件,基于 Predicate<Map<UUID, NodeResult>>
  • 构建:RouteOption.when(cond).and(cond).or(cond).build() 链式组合条件。
  • 评估:RouteOption.evaluate(resultPool) 在运行期依据“结果池”判断是否放行。
  • 位置:在 EasyTree.TreeNodechildrenWithRouterOptions 中与子节点成对存储。
  • 默认:若某子节点未配置 RouteOption(即为 null),视为“无条件放行”。

核心代码位置:

  • com.ai.agents.orchestrator.util.RouteOption
  • com.ai.agents.orchestrator.util.EasyTree.TreeNode#getNextNodes(...)

使用方式(接线)

在接线时通过重载方法为子节点指定路由:

java
EasyTree.TreeNode root = manager.setStartNode(start);

RouteOption passIfAOk = RouteOption
    .when(pool -> {
        var a = pool.get(nodeAId);
        return a != null && Objects.equals(a.getValue(), "OK");
    })
    .build();

root.addChild(childNode, passIfAOk);

也可以组合条件:

java
RouteOption complex = RouteOption
    .when(pool -> ((Integer) pool.get(nodeXId).getValue()) > 10)
    .and(pool -> "READY".equals(String.valueOf(pool.get(nodeYId).getValue())))
    .or(pool -> Boolean.TRUE.equals(pool.get(nodeZId).getValue()))
    .build();

root.addChild(next, complex);

运行时,getNextNodes(resultPool) 会对每个子节点:

  1. 子节点为 null → 过滤掉
  2. 无 RouteOption → 放行
  3. 有 RouteOption → 调用 evaluate(resultPool),true 放行,false 过滤

典型拓扑

A ──▶ C
B ──▶ C
  • C 同时依赖 A 与 B,只有当 A、B 都完成后,并且满足“任一父放行”的规则,C 才会执行。

开发指引

  • 连接关系使用 EasyTree.TreeNode
    1. root = manager.setStartNode(start)(仅一次)
    2. root.addChild(child)root.addChild(child, routeOption) 正确接线
  • 上下游数据传递:
    • 子节点构建时通过 build(upstreamId) 从结果池获取上游聚合结果

策略模式建议(与 RouteOption 配合)

  • 汇聚节点:多个父节点写入不同 key 值,子节点在 RouteOption 中读取并据此放行/分流。
  • 分支节点:在上游 CodeNode 中计算标签/状态,RouteOption 按标签选择下游分支。
  • 容错旁路:RouteOption.or(cond) 允许在主条件失败时,走兜底分支。

组合策略建议

  • 汇聚节点:多个父节点将各自产生的结果最终聚合到一个子节点上处理
  • 分支节点:一个父节点产出后分发给多个子节点并行处理
  • 过滤/路由:在 CodeNode 中根据结果值决定是否往下游继续传播(可显式编码)

常见问题

  • 子节点早启动:通常因为接线缺失或父节点未正确注册为依赖
  • NPE:重复 setStartNode 导致 UUID 变化,子节点引用旧 UUID 取不到结果
  • 执行顺序与并行:框架保证依赖顺序,但不会强行串行化无依赖的分支,可并行推进

Released under the MIT License.