Spring AI vs LangChain4j vs Embabel vs AgentScope Java

Compare Spring AI, LangChain4j, Embabel, and AgentScope Java with the same ticket-lookup example. Choose a starting framework for Spring Boot, plain Java, or agents that need planning.

Layer diagram with Spring AI and LangChain4j in the integration layer, Embabel above Spring AI in the agent layer, LangChain4j agentic reaching into the agent layer, and AgentScope spanning both layers

Suppose we want to add a support assistant to a Java application. It needs to answer questions, look up a customer’s ticket, and perhaps pass a difficult case to another service. We need a way to connect the language model to our Java code.

A model is the AI service that reads our request and produces an answer, such as Claude or a model running locally in Ollama. The frameworks in this article connect that model to the application; they are not models themselves.

Spring AI, LangChain4j, Embabel, and AgentScope Java can help with connecting our application to these LLM models, but they offer different ways to organize it.

  • Spring AI and LangChain4j are useful starting points for calling models and exposing Java methods as tools.
  • Embabel adds planning on top of Spring AI.
  • AgentScope Java provides agents that can call tools and delegate work to other agents. An agent uses a model to choose what to do next, such as looking up a ticket or asking a helper to investigate it.

Our LLM glossary explains the terms we will use in this article.

The first question we should ask what our application needs to do. We can start with the choices below, then compare the code and requirements before adding a dependency. The versions in this article were checked on October 25, 2026.

1. The Four Frameworks at a Glance

Spring AI fits the way Spring applications are configured. We can put model settings in properties, inject a client into a service, and use the application’s existing monitoring setup.

LangChain4j can be used directly in Java without starting Spring Boot. One of its main features is AI Services. We declare a Java interface, and the library creates an implementation that sends requests to a model. It also has integrations for Spring Boot, Quarkus, Helidon, and Micronaut.

Embabel runs on Spring AI. We write Java methods for the available actions, describe their inputs and outputs, and declare the result we want. Its planner can work out which actions are needed to produce that result.

AgentScope Java provides an agent runtime with model integrations and tools. Its ReActAgent can choose a tool, use the result, and continue until it has an answer. Its HarnessAgent supports broader tasks with a workspace, memory, and helper agents.

Before comparing APIs, we check whether each version fits our Java and Spring Boot versions. The table also shows which parts handle tool calls, planning, and work shared among agents.

Spring AILangChain4jEmbabelAgentScope Java
Version compared2.0.21.22.01.5.32.0.4
Current major version since2.0 in June 2026 (1.0 in May 2025)1.0 in May 20251.0 in July 20262.0 in July 2026
Minimum Java17172117
Spring BootNeeded for the starters, Boot 4.0 or 4.1Optional startersRequired, Boot 4.1Optional starter
Main APIChatClientAI Services (an interface LangChain4j implements for us)@Agent, @Action, @AchievesGoalReActAgent, HarnessAgent
How an agent runsA tool-calling loop inside ChatClientA tool-calling loop inside the AI Service, or agentic workflowsGoal-oriented planning selects actions by their input and output types; other planners are availableA repeated cycle of choosing a tool, using its result, and continuing
Multi-agent supportNo dedicated APIlangchain4j-agentic (beta, experimental)Supervisor planner and subagentsSubagents in HarnessAgent
MaintainerSpring team at BroadcomLangChain4j projectEmbabel, led by Rod JohnsonAgentScope project
LicenseApache 2.0Apache 2.0Apache 2.0Apache 2.0

All four methods can use a model running locally in Ollama. The examples therefore do not require an account key for a hosted model.

A stable core release does not mean every optional module is stable. For example, LangChain4j’s core version here is 1.22.0, while its langchain4j-agentic and langchain4j-mcp modules use 1.22.0-beta32. The agentic module is described as experimental by the project. We check the status of the module we intend to use, not just the main project’s version.

3. Integration Frameworks vs Agent Frameworks

The framework names can make this look like a choice among four replacements for the same library. That is not quite how they fit together.

Spring AI and LangChain4j handle the connection to the model. They can send questions, convert answers into Java objects, include earlier conversation messages, and run tools requested by the model. The application can also retrieve relevant documents and send them with a question. That approach is called retrieval-augmented generation, or RAG.

We can build an agent using these capabilities. For example, the model might look up a ticket, inspect the result, and then request a delivery lookup. Tool calling already allows the next step to depend on what the model finds.

A planning framework gives us another way to organize a larger task. In Embabel, we describe actions with Java input and output types. Its goal-oriented action planner, or GOAP, uses those available types to find actions that can produce the requested result. Embabel also offers other planners, including a model-driven supervisor.

Layer diagram with Spring AI and LangChain4j in the integration layer, Embabel above Spring AI in the agent layer, LangChain4j agentic reaching into the agent layer, and AgentScope spanning both layers
These roles overlap. Spring AI and LangChain4j provide model integration, Embabel adds planning, and AgentScope combines model integration with an agent runtime.

Embabel uses Spring AI for the model connection, so choosing Embabel does not mean replacing Spring AI. We use the two together.

LangChain4j also goes beyond individual model calls. Its optional langchain4j-agentic module provides ways to combine agents in sequences, loops, parallel work, and model-directed coordination. AgentScope includes its own model integrations and agent runtime without requiring Spring.

Evaluate Spring AI and LangChain4j first when the main job is adding model calls, tools, or document-based answers to an application. Then consider whether we need more help organizing the work. Embabel’s planning, LangChain4j’s agentic module, and AgentScope’s agent features are options to evaluate for that next requirement.

4. How the Same Tool Call Looks in Each Framework

We can see the programming differences by implementing the same small task in each framework. The user asks, “What is the status of ticket T-1001?” Our Java method, getTicketStatus(), returns “Waiting for the courier” for that ticket and “Unknown ticket” for any other value.

This is a demonstration method. It returns a fixed value rather than querying a real ticket system. Each version connects it to the same local Ollama model, qwen2.5:7b.

The examples show how each framework registers a tool and asks the model a question. The snippets were compiled against the stated versions, but they were not run against a model for this article. They do not compare answer quality, speed, or reliability.

Imports and some project setup are omitted from the snippets. The complete projects on GitHub contain that code. This one-tool task makes the APIs easier to compare; it does not demonstrate multi-step planning or collaboration among agents.

4.1. Spring AI

For Spring AI, we add spring-ai-starter-model-ollama. We use spring-ai-bom version 2.0.2 to select matching dependency versions.

The SupportTools class contains the method the model can request. Spring AI’s @Tool annotation describes what that method does.

public class SupportTools {

    @Tool(description = "Get the status of a support ticket")
    public String getTicketStatus(String ticketId) {
        return "T-1001".equals(ticketId) ? "Waiting for the courier" : "Unknown ticket";
    }
}

Spring Boot creates a ChatClient.Builder from the model settings in application.properties. We use the builder to create a client, supply the question, and register SupportTools with tools().

The call() method runs the request, and content() returns the text answer. We run this code at application startup through a CommandLineRunner.

@Bean
CommandLineRunner askAboutTicket(ChatClient.Builder builder) {
    return args -> {
        String answer = builder.build()
                .prompt("What is the status of ticket T-1001?")
                .tools(new SupportTools())
                .call()
                .content();
        System.out.println(answer);
    };
}
spring.ai.ollama.base-url=http://localhost:11434
spring.ai.ollama.chat.model=qwen2.5:7b

If the model requests the ticket lookup, Spring AI runs the Java method and sends its result back to the model. In Spring AI 2.0, ToolCallingAdvisor manages that loop through ChatClient. An advisor is a component that participates in processing a model request, and this one is registered automatically when tools are present.

The Spring AI getting-started guide shows how to create the project and configure the model.

4.2. LangChain4j

For LangChain4j, we add langchain4j and langchain4j-ollama, both version 1.22.0. Its @Tool annotation serves the same purpose as Spring AI’s annotation, but it comes from a different package.

We also declare a SupportAgent interface with a chat() method. AiServices creates the implementation for us. When we call chat(), that implementation contacts the model and handles any requests to use the registered tools.

public class SupportTools {

    @Tool("Get the status of a support ticket")
    public String getTicketStatus(String ticketId) {
        return "T-1001".equals(ticketId) ? "Waiting for the courier" : "Unknown ticket";
    }
}

public interface SupportAgent {

    String chat(String question);
}
ChatModel model = OllamaChatModel.builder()
        .baseUrl("http://localhost:11434")
        .modelName("qwen2.5:7b")
        .build();

SupportAgent agent = AiServices.builder(SupportAgent.class)
        .chatModel(model)
        .tools(new SupportTools())
        .build();

System.out.println(agent.chat("What is the status of ticket T-1001?"));

This example runs in plain Java. We create the model with a builder and pass it to AiServices; Spring Boot is not required.

If we use Spring Boot, the appropriate LangChain4j starter can create the AI Service as a bean using @AiService. The LangChain4j Spring Boot tutorial explains that setup. The starter version and Boot compatibility need to match our application.

4.3. Embabel

For Embabel, we add embabel-agent-starter and embabel-agent-starter-ollama, both version 1.5.3. This version uses Java 21 and Spring Boot 4.1.

Our agent class is SupportDeskAgent. The @Agent annotation identifies it as an agent, and @Action identifies a step the framework can run. Here, there is only one step. @AchievesGoal marks it as the action that produces the final result.

That result is SupportReply, a Java record containing ticketId, status, and message. The action receives the user’s question in UserInput. It uses OperationContext to access the model and request a SupportReply object. withToolObject() makes the ticket lookup available to the model.

@Agent(description = "Answers questions about support tickets")
public class SupportDeskAgent {

    @AchievesGoal(description = "The customer's ticket question is answered")
    @Action
    public SupportReply answer(UserInput input, OperationContext context) {
        return context.ai()
                .withDefaultLlm()
                .withToolObject(new SupportTools())
                .createObject("Answer the customer: " + input.getContent(), SupportReply.class);
    }
}

The Embabel project has its own SupportTools class. It uses the same lookup method as the Spring AI example, but marks it with Embabel’s @LlmTool annotation.

The starter creates an AgentPlatform bean, which runs agents. We pass that bean to AgentInvocation, ask for a SupportReply, and supply the user’s question.

SupportReply reply = AgentInvocation.builder(agentPlatform)
        .build(SupportReply.class)
        .invoke(new UserInput("What is the status of ticket T-1001?"));

For this one-step task, Embabel adds more structure than we need. Its planning becomes more relevant when several actions are available and the required order depends on the information we have.

For example, one action could look up a ticket and return a ticket record. Another could use that record to prepare a reply. By declaring the input and output types, we give the planner information about how the actions can connect. Our Embabel tutorial explores a multi-step example.

4.4. AgentScope Java

For AgentScope Java, we add agentscope-core and agentscope-extensions-model-ollama, both version 2.0.4. The provider-specific module supplies the Ollama connection.

We mark the lookup method with AgentScope’s @Tool annotation. @ToolParam describes the ticketId parameter so the model knows what to provide. A Toolkit holds the tools available to the agent.

public class SupportTools {

    @Tool(name = "get_ticket_status", description = "Get the status of a support ticket")
    public String getTicketStatus(
            @ToolParam(name = "ticketId", description = "The ticket id, such as T-1001") String ticketId) {
        return "T-1001".equals(ticketId) ? "Waiting for the courier" : "Unknown ticket";
    }
}
Toolkit toolkit = new Toolkit();
toolkit.registerTool(new SupportTools());

ReActAgent agent = ReActAgent.builder()
        .name("SupportDesk")
        .sysPrompt("You answer questions about support tickets.")
        .model(OllamaChatModel.builder()
                .baseUrl("http://localhost:11434")
                .modelName("qwen2.5:7b")
                .build())
        .toolkit(toolkit)
        .build();

Msg question = Msg.builder().textContent("What is the status of ticket T-1001?").build();
Msg reply = agent.call(question).block();

System.out.println(reply.getTextContent());

We create a ReActAgent with the model, instructions, and toolkit. ReAct means the agent can choose a tool, inspect the result, and choose what to do next. In this example, the only tool looks up the ticket.

We put the question in a Msg message and pass it to call(). The result is a Reactor Mono, which represents a value that becomes available when the operation completes. Calling block() waits for the reply so this small example can print it.

For larger tasks, HarnessAgent adds facilities such as a workspace and helper agents. The AgentScope Java documentation covers those features. Version 2.0 removed the older message-hub and pipeline classes, so examples written for 1.x may need changes before they work with 2.x.

4.5. A Quick Comparison

All four examples make the same Java lookup available to a model. The main differences are how we configure the model, register the method, and receive the reply.

Spring AILangChain4jEmbabelAgentScope Java
Dependencies1 starter (plus the BOM)22 starters2
Where the model is configuredapplication.propertiesA builder in codeapplication.propertiesA builder in code
How the tool is registeredPassed to the request with tools()Passed to the AI Service builderPassed to the operation with withToolObject()Registered in a Toolkit
What the call returnsA String (or a typed object with entity())Whatever the interface method declaresA typed result returned by the selected actionA Mono of Msg

5. What Is the Difference Between Spring AI and LangChain4j?

Both frameworks can call models, run tools, remember conversation messages, retrieve documents for RAG, and return Java objects. The choice is usually about how those capabilities fit the application.

Spring AI fits Spring Boot’s configuration and monitoring conventions. LangChain4j lets us describe an AI service as a Java interface and use it with or without Spring.

Chat memory means keeping earlier conversation messages available for later questions. Structured output means asking for an answer that can be read as a Java object, rather than only as text. MCP, the Model Context Protocol, lets an application use tools exposed by another program.

FeatureSpring AI 2.0.2LangChain4j 1.22.0
Programming styleFluent calls on ChatClientDeclarative interfaces (AI Services)
Configurationapplication.properties and auto-configurationBuilders in code, or framework starters
Spring Boot starterStable, part of the projectlangchain4j-spring-boot4-starter, versioned beta
Tools@Tool, run by ToolCallingAdvisor@Tool, run by the AI Service
Chat memoryChatMemory with MessageChatMemoryAdvisorChatMemory, such as MessageWindowChatMemory
RAGQuestionAnswerAdvisor, RetrievalAugmentationAdvisor, an ETL pipeline for documentsContentRetriever, a retrieval augmentor, document loaders
Structured outputentity(Class)The return type of the interface method
MCPClient and server startersClient module (beta)
Monitoring model requestsMicrometer observations built inListeners and integrations
TestingEvaluators and Spring Boot test supportPlain JUnit tests
Multi-agentNo dedicated APIlangchain4j-agentic (beta)

Spring AI is convenient when the application already uses Spring Boot. We can configure model providers, vector stores, and MCP clients with properties. A vector store holds representations of documents that help us find relevant text for a question. MCP clients connect to those external tools.

Spring AI also uses Micrometer, the monitoring library commonly used in Spring applications, to record information about model requests. Our ChatClient guide explains its request-building API in more detail.

LangChain4j is a useful option outside Spring, or when the team prefers Java interfaces for AI features. Its framework integrations help create and configure those services, while the plain Java API remains available.

Its langchain4j-agentic module is also worth evaluating if we want built-in ways to combine several agents. That module is experimental, so we account for possible API changes when deciding whether to depend on it.

The version matters when copying tool-calling examples. In Spring AI 2.0, the model implementation no longer runs Java tools internally. ChatClient manages that work through its advisor. Calling ChatModel directly returns tool requests for our code to handle; it does not automatically execute them.

The Spring AI upgrade notes explain the change. Our Spring AI migration guide shows how to update existing code.

6. Which Framework Should You Use to Build AI Agents in Java?

We can narrow the choice by looking at the application we already have and the work we want the model to do. These recommendations are places to start a small evaluation, rather than claims that only one framework can handle each situation.

Your situationPickWhy
A Spring Boot application that needs chat, tools, or document-based answersSpring AIConfiguration, testing, and observability work the Spring way
Plain Java, Quarkus, or MicronautLangChain4jNo Spring dependency, with integrations for those frameworks
A Spring Boot application where typed actions and goal-based planning help organize the workEmbabel on Spring AITyped, testable actions, with a planner that chains them
Several agents in an explicit order, such as a sequence, a loop, or parallel workLangChain4j agenticReady-made workflow builders, but the module is beta
Long-running agents that start subagents, outside SpringAgentScope JavaHarnessAgent gives an agent a workspace, memory, and subagents
A team that is new to AISpring AI or LangChain4jStart with model calls and tools; evaluate planning when the task needs it

Combining frameworks can be appropriate, but it should solve a specific problem. Embabel uses Spring AI for model access. Spring AI and LangChain4j can also coexist, although using both for the same model calls gives the team two APIs and configurations to maintain.

Before adopting a planning or multi-agent feature, we try one representative task. We check whether the model uses the right tools, what happens when a tool fails, and whether the final result meets the application’s requirements. The examples in this article establish compilation only; those runtime checks still need to be done.

7. Other Java AI Tools Worth Considering

The four frameworks above cover many Java applications, but other projects offer different ways to organize agents. The versions below were checked on October 25, 2026.

7.1. Google Agent Development Kit (ADK) for Java

Google’s Agent Development Kit, or ADK, provides tools for building, evaluating, and deploying agents. It is designed around Gemini models. Its google-adk-langchain4j module also connects it to model providers supported by LangChain4j, including Ollama.

The Java version compared here is 1.13.0 and requires Java 17. Its README labels it as a preview under Google’s pre-GA terms. The ADK Java documentation describes the setup.

7.2. Spring AI Alibaba

Spring AI Alibaba builds agent and workflow features on Spring AI. Its Graph module helps run connected steps and provides support for saving progress and streaming results.

The stable 1.1.2.3 release uses Spring AI 1.1. Its 2.0 line is still a milestone release, so we do not assume the stable release can be added to a Spring AI 2.0 project. The project repository lists the supported versions.

7.3. Semantic Kernel for Java

Semantic Kernel is Microsoft’s SDK for connecting models to application code through plugins. The Java release compared here is 1.5.0, published in April 2026.

Microsoft continues to support Semantic Kernel 1.x and describes Microsoft Agent Framework as its successor for new agent capabilities. That does not by itself establish a Java migration path. We check Java-specific support before choosing it for a new application. The Semantic Kernel documentation covers the Java SDK.

7.4. Koog

Koog is JetBrains’ agent framework. It is written in Kotlin and provides a Java API. We can describe an agent as connected steps, including branches and repeated work.

Version 1.3.0 requires JDK 17 on the JVM. The project also targets JavaScript, WebAssembly, and iOS. It is an option to evaluate when the team already uses Kotlin or wants to define the workflow explicitly. See the Koog documentation.

7.5. LangGraph4j

LangGraph4j is a community project for workflows that keep state between steps. It represents the workflow as a graph, where steps can branch or loop. It has integrations for both LangChain4j and Spring AI.

Version 1.9.7 includes experimental features, while the 1.8 line is the long-term support version. The LangGraph4j repository explains the available versions.

8. FAQs

8.1. Is Spring AI worth it?

Spring AI is worth considering when we already use Spring Boot and need features such as tool calling, document retrieval, or monitoring model requests. It lets us use those features within the application’s existing configuration.

If the requirement is one simple call to a single provider, that provider’s SDK may be enough. We choose the extra framework when its features remove work we would otherwise implement ourselves.

8.2. Can I build AI agents in Java without Python?

Yes. We can write the application and its tools in Java with any of these frameworks. The model can run locally through Ollama or be accessed through a hosted API. Python is not required to use an existing model from Java.

8.3. Is Python or Java better for AI?

Python has a larger ecosystem for training models and experimenting with machine learning. Java is a practical choice for adding model-based features to an existing Java application.

For the applications compared here, we use existing models rather than train new ones. The useful question is which language and framework fit the team’s application, skills, and deployment process.

8.4. Is AgentScope free to use?

AgentScope Java is open source under the Apache 2.0 license, with no framework usage fee. A hosted model provider can charge for requests. Running a local model also uses our own computing resources.

8.5. How is Embabel different from Spring AI?

Embabel adds planning and agent features on top of Spring AI. We declare actions and the result we want, and Embabel can work out how to connect those actions. Spring AI provides the model connection and related application features.

We can also build tool-calling agents directly with Spring AI. Embabel becomes relevant when its approach to planning helps organize the task. Section 3 explains that distinction.

9. Conclusion

For a Spring Boot application that needs chat, tools, or document-based answers, Spring AI is a sensible first option. LangChain4j is a useful alternative when we prefer its interface-based API or work outside Spring.

We consider Embabel when we want to describe Java actions and let a planner connect them. AgentScope is an option when its agent loop, workspace, and helper-agent features match the task. LangChain4j’s experimental agentic module offers another way to organize work among agents.

The choice does not follow from a feature count alone. We use the same representative task to check model support, tool failures, result handling, and how easily the code fits our application.

We also check the exact module versions before copying an example. Embabel here requires Java 21, some LangChain4j modules are beta, and AgentScope changed its agent APIs in 2.0. The snippets in this article show the programming differences. They are not a runtime performance or answer-quality comparison.

10. References

You can share questions about choosing a Java AI framework in the comments.

Happy Learning!

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.