AgentFlow 入门与实战:Task-Based 并发、EWMA 动态调度与四道门禁的 Java 生产级编排

AgentFlow 入门与实战:Task-Based 并发、EWMA 动态调度与四道门禁的 Java 生产级编排


一、AgentFlow 是什么

1.1 一句话定义

AgentFlow 是一个用 Java 构建的、面向持久化异步 AI Agent 任务的 pub-sub 有向图编排框架,专为"永不终止的开放式工作流"设计,让多个独立 Agent 通过消息传递持续协作。

1.2 解决什么问题

传统 AI Agent 编排通常采用"请求-响应"的一次性模式------用户提问,Agent 处理,返回结果,结束。但现实中很多场景是持续运行、不断演进的:客服工单流转、监控告警处理、多阶段审批流水线。这些场景需要 Agent 长时间存活,持续接收和处理消息。

类比:AgentFlow 就像一条永不停歇的工厂流水线。 传统 Agent 是"接单-完工-关门"的作坊模式;AgentFlow 是"传送带不停运转、工位持续处理"的流水线模式。每个工位(Task)是一个独立线程,通过传送带(pub-sub 消息)传递工件(消息)。

1.3 核心设计哲学

AgentFlow 的核心设计选择是 Task-Based Concurrency ------每个操作封装为一个独立的 Task,运行在自己的 daemon 线程中,Task 之间通过发布-订阅模式通信,发布者不需要知道订阅者的存在。


注:

博客:

https://blog.csdn.net/badao_liumang_qizhi

二、核心架构

2.1 Task-Based Concurrency

java 复制代码
public abstract class Task implements Runnable {
    // 线程生命周期管理
    public void start() { ... }
    public void stop() { ... }

    // 子类实现的抽象方法
    protected abstract boolean shouldProcess();
    protected abstract void process();
    protected abstract long calculateSleepTime();
}

每个 Task 是一个自包含的工作单元,能够处理传入消息、调整自身处理频率、与其他 Task 通信、维护自己的状态。

2.2 Adaptive Timing(EWMA 动态调整)

AgentFlow 最具特色的设计是用指数加权移动平均(EWMA)算法动态调整每个 Task 的处理频率,而非固定轮询间隔。

java 复制代码
public abstract class AdaptiveTimingTask extends Task {
    double alpha = 0.1;              // 学习率
    double estimatedSleepTime = 100; // 初始休眠时间(ms)

    @Override
    protected long calculateSleepTime() {
        if (lastWaitingTime() == 0) {
            return (long) estimatedSleepTime;
        }
        estimatedSleepTime = alpha * lastWaitingTime()
                           + (1 - alpha) * estimatedSleepTime;
        return (long) estimatedSleepTime;
    }
}

效果:繁忙的 Task 自动获得更短的休眠时间(更频繁运行),空闲的 Task 自动退避以节省资源。系统在响应性和效率之间自然平衡。

类比:EWMA 就像交通信号灯的自适应配时。 固定轮询是"不管车流量多少,绿灯都是 30 秒";EWMA 是"车多时绿灯延长,车少时绿灯缩短"------系统根据实际负载动态调整。

2.3 AdaptiveRelayTask:编排的核心组件

java 复制代码
public class AdaptiveRelayTask<X, Y> extends AdaptiveTimingTask {
    List<X> inbox = new ArrayList<>();
    List<AdaptiveRelayTask<Y, ?>> relays = new ArrayList<>();
    Function<X, Y> expression;

    @Override
    protected void process() {
        for (X x : inbox) {
            Y result = expression.apply(x);
            for (AdaptiveRelayTask<Y, ?> relay : relays) {
                relay.accept(result);
            }
        }
        inbox.clear();
    }
}

这个类提供了:泛型输入输出、函数式转换、消息队列管理、自动路由到下游 Task。


三、AgentFlow4J:Spring AI 之上的生产级治理层

cynthiasystems/AgentFlow 侧重于运行时架构 (pub-sub + EWMA),而 AgentFlow4J 则在其基础上增加了生产级治理能力------人机审批、检查点恢复、预算控制、工具策略。

3.1 两级 API

AgentFlow4J 暴露两层 API,按需要的控制粒度选择:

Level 1 --- Squad API(推荐大多数应用) :动态路由,最小化配置。CoordinatorAgent 将请求路由到一组 ExecutorAgent,你只需关注 Agent 本身,而非底层管道。

Level 2 --- Graph API(需要完全控制) :显式定义节点、边、条件边、循环。支持每个节点的重试策略、断路器、预算门禁、基于检查点的恢复。

java 复制代码
AgentGraph graph = AgentGraph.builder()
    .addNode("research", researcher)
    .addNode("analyze", analyzer)
    .addNode("write", writer)
    .addEdge("research", "analyze")
    .addEdge(Edge.conditional("analyze",
        ctx -> ctx.get(CONFIDENCE).doubleValue() < 0.7,
        "research"))  // 循环回退
    .addEdge("analyze", "write")
    .errorPolicy(ErrorPolicy.RETRY_ONCE)
    .build();

AgentResult result = graph.invoke(AgentContext.of("..."));

关键特性 :两级 API 可以组合------CoordinatorAgent 本身就是一个 Agent,可以作为节点放入 Graph 中。

3.2 治理模型:四道门禁

AgentFlow4J 的生产级治理围绕四道门禁展开:

门禁 作用 实现
BudgetPolicy 限制每次运行/每个节点/每次调用的花费 货币无关,成本可以是美元、Token 数或调用次数
ToolPolicy 阻止危险工具的执行 工具白名单/黑名单
StatePolicy 保护敏感状态字段 状态读写权限控制
ApprovalGate 在高风险操作前暂停,等待人工审批 基于检查点的暂停/恢复

Budget-aware Routing:AgentFlow4J v0.7.0 引入了预算感知路由------在预算充足时路由到高级 Agent,预算低于阈值时优雅降级到便宜的回退方案。

类比:四道门禁就像核电站的多层安全机制。 预算控制是"燃料限额",工具策略是"操作许可",状态保护是"辐射屏蔽",人工审批是"发射按钮的双人确认"。

3.3 持久化执行

AgentFlow4J 在每个节点后自动创建检查点。如果工作流中途崩溃,从最后一个成功的检查点恢复,而不是从头开始。

java 复制代码
// 人机审批的暂停/恢复
ApprovalGate gate = ApprovalGate.builder()
    .threshold(1000.0)  // 金额超过 1000 时触发审批
    .build();

// 暂停后通过 Slack/Webhook 通知人工
// 审批通过后从检查点恢复,不丢失已完成的工作

四、快速上手示例

4.1 Maven 依赖

xml 复制代码
<repositories>
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>

<dependency>
    <groupId>com.github.datallmhub.agentflow4j</groupId>
    <artifactId>agentflow4j-starter</artifactId>
    <version>v0.7.0</version>
</dependency>

<!-- Spring AI Provider --- 可替换为 OpenAI/Anthropic/Gemini/Ollama -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-mistral-ai</artifactId>
</dependency>

4.2 定义类型化状态

用 StateKey<T> 替代 Map<String, Object>,编译器可以捕获键不匹配的错误:

java 复制代码
public final class ReviewKeys {
    public static final StateKey<String> DOCUMENT =
        StateKey.of("document", String.class);
    public static final StateKey<String> DOC_TYPE =
        StateKey.of("doc.type", String.class);
    public static final StateKey<String> RISK_LEVEL =
        StateKey.of("risk.level", String.class);
    public static final StateKey<String> ISSUES =
        StateKey.of("issues", String.class);
    public static final StateKey<String> FINAL_REPORT =
        StateKey.of("final.report", String.class);
}

4.3 编写三个 Agent

每个 Agent 是一个 Spring Bean,由 ExecutorAgent 支撑:

java 复制代码
@Configuration
public class ReviewAgents {

    @Bean
    Agent classifier(ChatClient.Builder builder) {
        return ExecutorAgent.builder()
            .chatClient(builder.build())
            .systemPrompt("""
                你是一个法律文档分类器。阅读文档并返回 JSON:
                "type": [CONTRACT, NDA, INVOICE, OTHER]
                "risk": [LOW, MEDIUM, HIGH]
                """)
            .inputMapper(ctx -> ctx.get(ReviewKeys.DOCUMENT))
            .outputMapper((ctx, result) -> ctx
                .with(ReviewKeys.DOC_TYPE, extractField(result.text(), "type"))
                .with(ReviewKeys.RISK_LEVEL, extractField(result.text(), "risk")))
            .build();
    }

    @Bean
    Agent analyst(ChatClient.Builder builder) {
        return ExecutorAgent.builder()
            .chatClient(builder.build())
            .systemPrompt("你是法律分析师。提取最重要的三个条款并标记问题。")
            .inputMapper(ctx -> ctx.get(ReviewKeys.DOCUMENT))
            .outputMapper((ctx, result) -> ctx
                .with(ReviewKeys.ISSUES, result.text()))
            .build();
    }

    @Bean
    Agent summariser(ChatClient.Builder builder) {
        return ExecutorAgent.builder()
            .chatClient(builder.build())
            .systemPrompt("你是高级法律审核员。根据文档类型、风险等级和分析发现,生成一页审核报告。")
            .inputMapper(ctx -> String.format(
                "类型: %s\n风险: %s\n发现:\n%s",
                ctx.get(ReviewKeys.DOC_TYPE),
                ctx.get(ReviewKeys.RISK_LEVEL),
                ctx.get(ReviewKeys.ISSUES)))
            .outputMapper((ctx, result) -> ctx
                .with(ReviewKeys.FINAL_REPORT, result.text()))
            .build();
    }
}

4.4 构建编排图

java 复制代码
AgentGraph graph = AgentGraph.builder()
    .addNode("classify", classifier)
    .addNode("analyze", analyst)
    .addNode("summarise", summariser)
    .addEdge("classify", "analyze")
    .addEdge("analyze", "summarise")
    .build();

AgentResult result = graph.invoke(
    AgentContext.of(Map.of(ReviewKeys.DOCUMENT, documentText)));

五、与其他框架的定位对比

维度 AgentFlow (cynthiasystems) AgentFlow4J Spring AI Alibaba Graph
核心定位 持久化异步 Agent 运行时 Spring AI 治理层 企业级 Graph 编排
并发模型 Task 线程 + EWMA 动态调整 基于 Spring AI Flux 响应式
消息传递 Pub-Sub 有向图 AgentContext 类型化状态 OverAllState
治理能力 基础 四道门禁 + 检查点 interruptBefore/After
人机审批 无内置 ApprovalGate Graph Studio
适用场景 长运行开放式工作流 生产级 Spring AI 应用 复杂 DAG 工作流

选型建议:

  • 需要持续运行的开放工作流(监控、工单流转)→ cynthiasystems/AgentFlow
  • 需要生产级治理(预算、审批、检查点)且使用 Spring AI → AgentFlow4J
  • 需要复杂 DAG + 可视化编排 → Spring AI Alibaba Graph

六、总结

AgentFlow 的核心设计哲学是 "让 Agent 像流水线一样持续运转":

层面 核心技术 设计要点
并发模型 Task-Based Concurrency 每个 Task 独立线程
消息传递 Pub-Sub 有向图 发布者不感知订阅者
动态调度 EWMA 指数加权移动平均 繁忙 Task 获更多 CPU,空闲 Task 自动退避
类型安全 StateKey 编译器捕获键错误
治理 四道门禁 + 检查点 预算/工具/状态/审批
持久化 节点级检查点 崩溃后从断点恢复

参考资源:

博客: https://blog.csdn.net/badao_liumang_qizhi

相关推荐
愿得一猪蹄1 小时前
# Java线程池实战,别再new Thread了
java
ee又momo1 小时前
# 深入理解Java注解,从使用到自定义
java
释厄6231 小时前
错误无误公理——错误正确本同源都迭代定律——逆转有价值
android·开发语言·kotlin
霸道流氓气质2 小时前
AI智能博客平台实战:RAG增强写作、多Agent协作与语义检索的Vue3 + Spring AI全栈实现
java·人工智能·spring
2601_962885722 小时前
如何用 Python计算 CR能量指标(中间意愿指标)?
开发语言·python
打工仔折腾 AI2 小时前
LangChain 工具调用实战:从 Tool 定义到 Agent 执行链路拆解
java·前端·人工智能·后端·python·langchain·ai agent 实战
哦虎!2 小时前
【JavaEE】网络原理 - TCP/IP
java
东风微鸣2 小时前
把 Tailscale 接进 Prometheus 监控
java·数据库·prometheus
看浪的路人2 小时前
第9讲:大模型应用监控与可观测性——OpenTelemetry + Prometheus + Grafana 全链路追踪
java·前端·spring