Building Multi-Agent Systems with Spring AI and Langgraph4j: A Hands‑On Guide

This article introduces multi‑agent architectures and the Agents Handoff pattern, then demonstrates a complete implementation using Spring Boot 3.4.2, Langgraph4j, and Spring AI, including code for a marketplace agent, a payment agent, configuration, testing, and suggestions for further improvement.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Building Multi-Agent Systems with Spring AI and Langgraph4j: A Hands‑On Guide

1. Introduction

Multi‑agent architecture is a new trend in artificial intelligence for building complex and innovative solutions. The "Agents Handoff" pattern refers to transferring control and context from one agent to another to achieve continuous and efficient task execution.

1.1 What is Multi‑Agent Architecture

A multi‑agent system consists of multiple interacting agents, each designed to perform specific tasks. Agents can operate independently or cooperate to achieve a common goal, with coordination and communication being essential for seamless execution of complex processes.

1.2 What is Agents Handoff

Agents Handoff is the mechanism of handing over control and data (context) from one agent to another, which is crucial in scenarios requiring different expertise or task distribution among several agents to optimize performance.

1.3 How to Implement Agents Handoff

Function calls (also called tools) are used as the technical means to implement Agents Handoff. In AI models, function calls act as pillars for agents, allowing them to invoke specific functions, share data, and cooperate on tasks, enabling dynamic interaction and real‑time adaptation.

Below is an illustration of the ReAct agent architecture highlighting the role of function calls:

Action as an agent:

Multiple actions can be treated as agents, allowing iterative addition of new behaviors to build complex multi‑agent scenarios:

2. Practical Example

2.1 Define Marketplace Agent

public class AgentMarketplace extends AbstractAgentExecutor<AgentMarketplace.Builder> {
    static class Tools {
        record Product(@JsonPropertyDescription("商品名称") String name,
                      @JsonPropertyDescription("商品价格") double price) {}
        @Tool(description = "从商品市场中查询商品")
        Product searchByProduct(@ToolParam(description = "要查询的商品名称") String product) {
            // demo logic
            return new Product("Spring Boot3实战案例200讲", 70D);
        }
    }
    public static class Builder extends AbstractAgentExecutor.Builder<AgentMarketplace.Builder> {
        public AgentMarketplace build() throws GraphStateException {
            this.name("marketplace")
                .description("商品市场智能体, 获取商品相关的信息")
                .parameterDescription("")
                .defaultSystem("""你是负责在商品市场上提供商品信息""")
                .toolsFromObject(new Tools());
            return new AgentMarketplace(this);
        }
    }
    public static Builder builder() { return new Builder(); }
    protected AgentMarketplace(Builder builder) throws GraphStateException { super(builder); }
}

2.2 Define Payment Agent

public class AgentPayment extends AbstractAgentExecutor<AgentPayment.Builder> {
    static class Tools {
        record Transaction(@JsonPropertyDescription("购买的商品名称") String product) {}
        @Tool(description = "购买商品并进行付款")
        Transaction submitPayment(@ToolParam(description = "购买的商品名称") String product,
                                 @ToolParam(description = "商品的价格") double price,
                                 @ToolParam(description = "支付账号") String account) {
            System.err.printf("准备使用: %s账号, 购买图书: 《%s》| %s%n", account, product, price);
            return new Transaction("Spring Boot3实战案例200讲");
        }
    }
    public static class Builder extends AbstractAgentExecutor.Builder<AgentPayment.Builder> {
        public AgentPayment build() throws GraphStateException {
            this.name("payment")
                .description("支付智能体, 购买并进行支付")
                .parameterDescription("与付款相关的所有购买信息")
                .defaultSystem("""你是提供支付服务的智能体""")
                .toolsFromObject(new Tools());
            return new AgentPayment(this);
        }
    }
    public static Builder builder() { return new Builder(); }
    protected AgentPayment(Builder builder) throws GraphStateException { super(builder); }
}

2.3 Configure Agents Handoff

@Configuration
public class AgentHandoffConfig {
    @Bean
    CompiledGraph<State> graph(ChatModel chatModel) throws Exception {
        AgentMarketplace agentMarketplace = AgentMarketplace.builder()
            .chatModel(chatModel)
            .build();
        AgentPayment agentPayment = AgentPayment.builder()
            .chatModel(chatModel)
            .build();
        return AgentHandoff.builder()
            .chatModel(chatModel)
            .agent(agentMarketplace)
            .agent(agentPayment)
            .build()
            .compile();
    }
}

2.4 Test Controller

@RestController
@RequestMapping("/agents")
public class AgentController {
    private final CompiledGraph<State> graph;
    public AgentController(CompiledGraph<State> graph) { this.graph = graph; }

    @GetMapping
    public ResponseEntity<?> chat(String prompt) {
        Optional<State> result = graph.invoke(Map.of("messages", new UserMessage(prompt)));
        String ret = result.flatMap(state -> {
            state.messages().forEach(message -> {
                System.out.println(message);
                System.err.println("----------------------------");
            });
            return state.lastMessage();
        }).map(Content::getText).orElseThrow();
        return ResponseEntity.ok(ret);
    }
}

2.5 Test Result

The agents execute in order as expected.

2.6 Improvements

By using an MCP server as an agent and combining sampling capabilities, the handoff architecture can be further enhanced to provide better support for complex multi‑agent workflows.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Javaartificial intelligenceBackend DevelopmentSpring BootMulti-AgentLanggraph4j
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.