Skip to content

datallmhub/spring-agent-flow

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

48 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

spring-agent-flow

Build stateful multi-agent workflows in Java β€” with graphs, retries, and persistence.

No orchestration code. No glue logic. Just define your agents and run.

build Java 17+ Spring AI License


πŸš€ Live demo of a real-world use case built with Spring Agent Flow

πŸ”΄ Explore a real-world B2B USE CASE built with Spring Agent Flow:

chrome-capture-2026-05-04

πŸ‘‰ https://huggingface.co/spaces/datallmhub/multi-agent-customer-ops

What it shows

  • Multi-agent orchestration (Triage β†’ Lookup β†’ Policy β†’ Writer)
  • Hybrid AI + deterministic business logic
  • Typed shared state across agents
  • End-to-end decision traceability

Run locally

You can run the demo locally using the full source code:

πŸ‘‰ https://github.com/datallmhub/multi-agent-customer-ops


⚑ In 60 seconds

ExecutorAgent researcher = ExecutorAgent.builder()
        .chatClient(chatClient)
        .systemPrompt("Find key facts.")
        .build();

ExecutorAgent writer = ExecutorAgent.builder()
        .chatClient(chatClient)
        .systemPrompt("Write a clear report.")
        .build();

CoordinatorAgent coordinator = CoordinatorAgent.builder()
        .executors(Map.of("research", researcher, "writing", writer))
        .routingStrategy(RoutingStrategy.llmDriven(chatClient))
        .build();

AgentResult result = coordinator.execute(
        AgentContext.of("Compare Claude 4 and GPT-5"));

System.out.println(result.text());

Output:

=== Multi-Agent Coordination ===

Request: Compare Claude 4 and GPT-5

[router]   Routing to: research
[research] Gathering facts...

[router]   Routing to: writing
[writing]  Generating report...

Result:
Claude 4 excels in reasoning and long-context tasks.
GPT-5 shows stronger tool integration and instruction following.

This is a multi-step, stateful workflow with routing, coordination, and resilience β€” without writing orchestration code.

⭐ If this saves you time, consider starring the repo.


🧠 Why this exists

Real-world AI systems are not one LLM call.

They are:

  • multi-step
  • stateful
  • failure-prone
  • long-running

Spring AI gives you primitives. spring-agent-flow gives you a runtime.


πŸ“Š How it works

How it works

A coordinator routes tasks across agents, executing a graph with shared state, retries, and checkpoints.


🧠 Two levels of control

Level 1 β€” Squad API (recommended)

Dynamic routing, minimal setup. A CoordinatorAgent routes to ExecutorAgents β€” you focus on the agents, not the plumbing.

CoordinatorAgent coordinator = CoordinatorAgent.builder()
        .executors(Map.of(
            "research", researchExecutor,
            "analysis", analysisExecutor,
            "writing",  writingExecutor
        ))
        .routingStrategy(RoutingStrategy.llmDriven(chatClient))
        .build();

AgentResult result = coordinator.execute(AgentContext.of("..."));

Level 2 β€” Graph API

Explicit flows, loops, conditions, full control.

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"))                               // loop back
        .addEdge("analyze", "write")                       // fallback: forward
        .errorPolicy(ErrorPolicy.RETRY_ONCE)
        .build();

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

🧭 When should I use this?

Use it if:

  • your agent needs multiple LLM calls
  • your workflow has branches or loops
  • failures (retry, resume, rate limits) matter
  • multiple agents must coordinate

Avoid it if:

  • you just call ChatClient once

βš”οΈ Why not just Spring AI or simple loops?

Approach Limitation
Spring AI alone Low-level primitives only β€” you write the orchestration
Manual while loops Don't scale, retries are hard, state becomes fragile
LangChain-style flows Limited execution control, Python-first

spring-agent-flow provides:

  • explicit execution graphs
  • built-in resilience (retry + circuit breaker)
  • durable, typed state
Spring AI spring-agent-flow
Primitives (ChatClient, tools) Structured runtime (AgentGraph, CoordinatorAgent)
Manual orchestration Graph-based execution
No durable state Typed shared state + checkpoints
Retry logic in user code Built-in retry + circuit breaker
No resume Interrupt + resume support

πŸš€ Try it in 30 seconds (no API key required)

git clone https://github.com/datallmhub/spring-agent-flow.git
cd spring-agent-flow
mvn install -DskipTests -q
mvn -pl spring-agent-flow-samples exec:java

πŸ‘‰ Runs a real multi-agent workflow with routing, coordination, and state β€” fully simulated.

πŸ“¦ Samples included

The project ships with ready-to-run examples β€” no LLM required.

Example What it shows Run
MultiAgentCoordination Multi-agent routing with CoordinatorAgent default
MinimalPipeline Simple 2-step workflow using AgentGraph -Dexec.mainClass="...MinimalPipeline"
AdvancedGraphDemo Loops, conditions, state, listeners -Dexec.mainClass="...AdvancedGraphDemo"

πŸ‘‰ Start with MultiAgentCoordination β€” it demonstrates the full power of the framework.


🧩 What you get

  • ⚑ No orchestration code required
  • 🧠 Stateful agent workflows
  • πŸ” Built-in retries & circuit breakers
  • πŸ“Š Graph-based execution
  • πŸ’Ύ Durable checkpoints (JDBC / Redis)
  • πŸ”Œ Native Spring AI integration
  • πŸ“‘ Streaming support
  • πŸ“ˆ Micrometer metrics

🧱 Architecture

Modules Architecture

Layered architecture showing coordination, execution, resilience, and persistence on top of Spring AI.


πŸ›  Installation

Requirements: Java 17+, Spring Boot 3.x, Spring AI 1.0+

Distributed via JitPack.

Maven

<repositories>
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>

<dependency>
    <groupId>com.github.datallmhub.spring-agent-flow</groupId>
    <artifactId>spring-agent-flow-starter</artifactId>
    <version>v0.5.0</version>
</dependency>

Gradle

repositories {
    maven { url 'https://jitpack.io' }
}

dependencies {
    implementation 'com.github.datallmhub.spring-agent-flow:spring-agent-flow-starter:v0.5.0'
}

Modules

Module Use case
spring-agent-flow-starter Spring Boot auto-config, properties, Micrometer listener
spring-agent-flow-core Minimal API (Agent, AgentContext, StateKey, AgentResult)
spring-agent-flow-graph AgentGraph, RetryPolicy, CircuitBreakerPolicy SPI, checkpoint contract
spring-agent-flow-squad CoordinatorAgent, ExecutorAgent, ReActAgent, ParallelAgent, RoutingStrategy
spring-agent-flow-checkpoint JdbcCheckpointStore, RedisCheckpointStore, Jackson codec
spring-agent-flow-resilience4j CircuitBreakerPolicy adapter backed by Resilience4j
spring-agent-flow-cli-agents CliAgentNode β€” runs Claude Code / Codex / Gemini CLI agents as graph nodes
spring-agent-flow-test MockAgent, TestGraph for unit-testing graphs

Minimal application.yml:

spring:
  ai:
    agents:
      enabled: true
      default-error-policy: RETRY_ONCE
      observability:
        metrics: true

πŸ“‘ Streaming

graph.invokeStream(AgentContext.of("hello"))
    .subscribe(event -> {
        switch (event) {
            case AgentEvent.Token t         -> System.out.print(t.chunk());
            case AgentEvent.NodeTransition x -> System.out.println("\n--> " + x.to());
            case AgentEvent.Completed c     -> System.out.println("\n[done]");
            default -> {}
        }
    });

πŸ’Ύ Typed state β€” no Map<String, Object>

// Declare keys with types β€” compile-time safety
StateKey<Double> CONFIDENCE = StateKey.of("confidence", Double.class);
StateKey<String> SUMMARY    = StateKey.of("summary",    String.class);

// Use them anywhere
AgentContext ctx = context.with(CONFIDENCE, 0.85);
double score = ctx.get(CONFIDENCE);  // no cast needed

πŸ” Resilience

AgentGraph.builder()
    .errorPolicy(ErrorPolicy.FAIL_FAST)          // or RETRY_ONCE / SKIP_NODE
    .retryPolicy(RetryPolicy.exponential(3, Duration.ofMillis(200)))
    .addNode("llm", flakyAgent,
             RetryPolicy.exponential(5, Duration.ofMillis(500)),   // per-node override
             new Resilience4jCircuitBreakerPolicy(registry))        // per-node breaker
    .build();

See resilient-typed-executor.md and circuit-breaker.md.


πŸ“ˆ Observability (Micrometer)

Metric Tags Description
agents.execution.count agent, graph, status Per-node execution count
agents.execution.duration agent, graph Per-node execution time
agents.graph.transitions graph, from, to Node-to-node transitions
agents.execution.errors agent, graph, cause Error count by type

πŸ§ͺ Testing without an LLM

MockAgent mock = MockAgent.builder()
        .thenReturn("First response")
        .thenReturn("Second response")
        .build();

TestGraph.Trace trace = TestGraph.trace(
        AgentGraph.builder()
            .addNode("a", mock)
            .addNode("b", MockAgent.returning("done"))
            .addEdge("a", "b"));

AgentResult result = trace.invoke(AgentContext.of("test"));

assertThat(trace.visitedInOrder("a", "b")).isTrue();
assertThat(result.text()).isEqualTo("done");

πŸ“š Recipes


πŸ“ˆ Roadmap

Version Focus
0.5 (current) Subgraphs, parallel fan-out, cancellation, typed output, RetryPolicy, CircuitBreakerPolicy, JDBC/Redis checkpoint store
1.0 API stabilization, documentation, community feedback
1.1 Crew roles (CrewAI-inspired), auto-config for checkpoint backends
2.0 OpenTelemetry tracing, MCP integration, Agent-as-Tool

πŸ“ Note on scope

This project is independent and not affiliated with spring-ai-community/agent-client.

That project focuses on CLI agent integrations (Claude Code, Codex, Gemini).

spring-agent-flow focuses on something different: a graph-based runtime for stateful, multi-step agent workflows on top of Spring AI.


🀝 Contributing

Contributions welcome! Please see CONTRIBUTING.md for guidelines.

This project follows the Apache 2.0 License.


Inspiration