Rod Johnson's Embabel Brings Deterministic GOAP Planning to Enterprise AI Agents on the JVM
Foreword
Recently, a name has been appearing frequently in various tech discussions — Rod Johnson.
If you don't know who he is, you certainly know what he built — the Spring Framework.
Yes, the very Spring that almost redefined how enterprise Java applications should be written.
Over twenty years ago, Rod Johnson ended the frustrating era of EJB with a book (Expert One-on-One J2EE Design and Development) and a framework (Spring).
More than twenty years later, he is back.
In April 2026, Rod Johnson officially released Embabel at the Microsoft JDConf developer conference — an open-source JVM framework for enterprise AI Agents.
On July 20, 2026, Embabel officially released its 1.0.0 GA version. The project is open-sourced under the Apache 2.0 license and is currently publicly available on GitHub.
In this article, I will dissect Embabel from its design philosophy to its underlying principles, from code practice to performance data, from start to finish.
I hope it will be helpful to you.
12 project practices at Java Assault Team Network: susan.net.cn/project
1. Why Now?
Before discussing the framework itself, let's first understand a key question — Why did Rod Johnson choose this moment to do this?
After SpringSource was acquired by VMware, Rod Johnson spent many years on boards and investing. It wasn't until the emergence of ChatGPT at the end of 2022 that he couldn't sit still anymore.
He realized the industry is at a massive turning point.
But what he saw wasn't "how powerful AI is," but rather that "there is a huge gap between the promise of AI and reality."
"You are essentially building systems with something that works 90% of the time and fails 10% of the time. In terms of effectiveness, that equals 'completely useless.'"
This sentence pinpoints the core dilemma of enterprise AI implementation:
- In personal assistant scenarios, 90% accuracy is good enough.
- But enterprise business systems cannot tolerate that 10% error.
Generative AI is a random, non-deterministic system — the same prompt can produce different results each time.
This doesn't matter for personal chat, but for financial transactions, order processing, and compliance auditing, unpredictability means unusability.
This is the problem Embabel aims to solve.
2. What Exactly is Embabel?
Some might ask: "Isn't Spring AI already available? What is Embabel's relationship with it?"
This is a very critical question.
Embabel and Spring AI operate on different levels.
An analogy: Spring AI is like the Servlet API, and Embabel is like Spring MVC.
Spring AI solves the problem of "how to access AI models" — providing a unified ChatModel interface, vector store abstraction, and tool invocation mechanisms.
It allows you to call large models, but how to organize Agent logic, how to plan multi-step tasks, and how to ensure process control — these require you to write code to implement.
Embabel solves the problem of "how to make AI Agents work stably in enterprise systems" — providing a complete Agent programming model, including core abstractions like Action, Goal, and Condition.
Simply put: Spring AI is the "parts box," Embabel is the "assembly blueprint + assembly line."
Rod Johnson's own positioning is more direct: "You can build better Agents in Java than in Python. The JVM is a better choice for real-world generative AI applications."
Embabel overall architecture diagram:
Embabel's core philosophy can be summarized in one sentence: Through deterministic planning, make non-deterministic AI work stably in deterministic enterprise systems.
3. The "Secret Weapon" Borrowed from Game AI
The GOAP algorithm is Embabel's most striking design, and it is the most fundamental difference between it and all other AI frameworks.
3.1 What is GOAP?
GOAP stands for Goal-Oriented Action Planning, originally used for NPC (non-player character) AI in games — for example, enemies in The Last of Us, units in StarCraft, which need to autonomously decide their next action based on the current state.
In GOAP, the Agent's workflow is as follows:
- Clarify the current state and goal
- Based on all available Actions and their preconditions and effects
- Dynamically plan the optimal sequence of actions from the current state to the goal
- After each step, re-plan based on the new state
This is like using navigation software — you don't plan the entire route before departure and never change it; instead, at each intersection, you recalculate the next route based on real-time traffic conditions.
3.2 Why is GOAP So Important for Enterprise AI?
Rod Johnson believes that existing AI Agent solutions have gone to two extremes:
- Either let the LLM make completely autonomous decisions — results are unpredictable and unauditable.
- Or manually exhaust all possible scenarios in advance — the workload is enormous and cannot scale.
GOAP finds a balance between the two — the planning logic is deterministic (explainable, auditable), but the planning result is dynamic (highly adaptable).
More importantly: The GOAP planner does not use an LLM at all.
What does this mean?
Each planning step consumes no Tokens.
In a workflow containing multiple Actions, this single cut directly saves 40%-60% of LLM calls.
Detailed GOAP planning process:
Understanding the essential difference between GOAP and LLM planning: LLM planning entrusts the "how to proceed" to a random system that can make mistakes, hallucinate, and deviate from the goal.
GOAP planning entrusts the "how to proceed" to a deterministic algorithm — it calculates the optimal path based on the preconditions, effects, costs, and values of Actions.
GOAP won't "think wrong," won't "go off track," won't "fabricate non-existent Actions." Every step of its decision-making is traceable, explainable, and auditable.
4. Strongly-Typed, Object-Oriented Agent Programming
If you have written Spring, Embabel will feel very familiar.
4.1 Core Abstractions: Agent, Action, Goal
Embabel's core abstractions are very clear:
- Agent: A self-contained component that encapsulates domain logic, AI capabilities, and tool usage, completing specific goals on behalf of the user.
- Action: A discrete step that an Agent can execute, marked with the
@Actionannotation, with strongly-typed domain objects as input and output. - Goal: The objective the Agent needs to achieve, marked with the
@Goalannotation.
// Define an Action — pure Java code, no string concatenation
@Action(description = "Retrieve relevant documents from the knowledge base")
class RetrieveDocumentsAction {
@ActionMethod
fun execute(
@Parameter(description = "User question") query: String
): List<Document> {
return vectorStore.similaritySearch(query, topK = 5)
}
}
4.2 Type Safety: Goodbye String Hell
Python's LangChain/LangGraph ecosystem has a core problem — heavy use of strings, dicts, dynamic Graphs, and hand-written node edges. These are "okay" in Python, but when moved to Java, they become a maintenance nightmare.
Embabel's design principle is strong typing and object orientation. All LLM interactions are strongly typed, providing compile-time checks, refactoring support, and IDE assistance.
No more string concatenation for Prompts, no more JSON parsing — everything is guaranteed by Java/Kotlin's type system.
// In Embabel, Action inputs and outputs are strongly-typed domain objects
@Action(description = "Query order status")
public OrderStatus getOrderStatus(
@Parameter(description = "Order ID") String orderId
) {
// Pure Java code, no string concatenation
return orderService.findStatus(orderId);
}
4.3 Two Planning Modes
Embabel supports two planning modes:
① GOAP (Default): Calculates the optimal Action sequence based on cost and value, does not use LLM for planning.
② Utility AI: Each Action is scored by a configurable utility function, and the Action with the highest score is executed at each step. In Stashbot (a RAG document assistant), the Utility AI mode allows the LLM to autonomously decide when and how to search documents.
4.4 Why Written in Kotlin?
Embabel's core code is written in Kotlin.
Rod Johnson explained:
- He personally prefers the Kotlin coding experience.
- Null safety, more concise syntax, reified generics reduce the impact of type erasure.
But the key point is — the language choice for implementing the framework does not dictate the language choice for building applications on top of it. Embabel has excellent interoperability with Java. When building applications with Java, you will never see Kt imports.
Whether you use Kotlin or Java, the core value of Embabel's type safety and rich domain model stands out.
5. Code in Practice
Theory alone is not enough; let's look at actual Embabel code.
Below is a simplified version based on Embabel's official examples.
5.1 Define the Domain Model
// Order domain model
public class Order {
private String orderId;
private OrderStatus status;
private BigDecimal amount;
// getters/setters...
}
// Order status enum
public enum OrderStatus {
PENDING, CONFIRMED, SHIPPED, DELIVERED, CANCELLED
}
5.2 Define Actions
import com.embabel.agent.api.annotation.Action;
import com.embabel.agent.api.annotation.ActionMethod;
import com.embabel.agent.api.annotation.Parameter;
@Action(description = "Query order status")
public class GetOrderStatusAction {
private final OrderService orderService;
public GetOrderStatusAction(OrderService orderService) {
this.orderService = orderService;
}
@ActionMethod
public OrderStatus execute(
@Parameter(description = "Order ID") String orderId
) {
return orderService.findStatus(orderId);
}
}
@Action(description = "Cancel order")
public class CancelOrderAction {
private final OrderService orderService;
@ActionMethod
public Order execute(
@Parameter(description = "Order ID") String orderId,
@Parameter(description = "Cancellation reason") String reason
) {
return orderService.cancel(orderId, reason);
}
}
5.3 Define the Agent
import com.embabel.agent.api.Agent
import com.embabel.agent.api.Goal
@Agent(
name = "Order Management Assistant",
description = "Helps users query and manage orders"
)
class OrderManagementAgent(
private val getStatusAction: GetOrderStatusAction,
private val cancelAction: CancelOrderAction
) {
@Goal
fun handleOrderRequest(
@Parameter(description = "User instruction") instruction: String
): String {
// The GOAP engine will automatically plan: analyze instruction → select Action → execute → return result
// No need to manually write if-else or flow control
return agent.planAndExecute(instruction)
}
}
5.4 Start the Application
@SpringBootApplication
class Application
fun main(args: Array<String>) {
runApplication<Application>(*args)
}
The essence of this code: You haven't written any flow control code (if-else, switch, for loops), nor specified "execute A first, then B." You simply defined what Actions are available and what the final goal is, and the GOAP engine automatically plans the optimal sequence of actions.
Each Action can be a piece of pure code logic (zero LLM calls) or driven by a small Prompt. This design allows developers to precisely control which steps use AI and which use deterministic code.
6. Embabel vs Spring AI: The Essential Difference
I did an in-depth comparison of Embabel and Spring AI:
| Comparison Dimension | Embabel | Spring AI |
|---|---|---|
| Core Positioning | Enterprise Agent Programming Model | AI Model Integration Framework |
| Planning Method | GOAP Algorithm (Deterministic, No LLM) | Developer Manually Orchestrates ReAct Loop |
| Planning Token Cost | 0 Tokens (Planning doesn't use LLM) | LLM Called for Every Planning Step |
| Type Safety | ✅ Strongly-Typed Domain Objects | ✅ Strongly-Typed |
| Auditability | ✅ Planning Process Explainable, Traceable | ⚠️ Depends on Implementation |
| Developer Experience | Declarative (Define Action and Goal, GOAP auto-plans) | Imperative (Write your own loop) |
| LLM Call Volume | On-demand within Actions only | Called for Every Decision |
| Open Source License | Apache 2.0 | Apache 2.0 |
The essential difference between Embabel and Spring AI is: Who makes the decisions?
- Spring AI: The developer manually orchestrates the ReAct loop — write a prompt, call a tool, write another prompt, call another tool. The decision logic is in the developer's code, each step's path is hardcoded.
- Embabel: The developer defines Actions and Goals, and the GOAP engine dynamically calculates the optimal path at runtime. The decision logic is in the algorithm, each step's path is dynamically calculated.
This leads to a fundamental difference:
In Spring AI, if you need the Agent to do three things (check inventory, calculate price, generate report), you must explicitly write the execution order in the code. If a step fails, you need to write your own retry logic.
In Embabel, you only need to define three Actions and the final goal. The GOAP engine dynamically decides based on the current state which to do first, which next, and what to do if something fails.
Rod Johnson's own words are quite blunt: "You can build better Agents in Java than in Python."
7. Performance and Cost Data
Embabel's advantages in cost and performance are supported by clear data:
| Optimization Point | Effect |
|---|---|
| GOAP Planner (No LLM) | Directly cuts 40-60% of LLM calls |
| Strongly-Typed Domain Model Precise Contract | Saves 20-40% of Token consumption |
| Overall Cost Optimization | 50-70% total cost reduction potential |
Why can a strongly-typed Domain Model save Tokens?
Traditional AI Agents use natural language or dicts to pass context, and the context passed to the LLM each time expands in a vicious cycle.
Embabel replaces natural language context with precise input/output contracts, eliminating ineffective Token consumption.
On July 20, 2026, Embabel officially released its 1.0.0 GA version.
A framework entering GA means it has undergone sufficient production validation and API stability is guaranteed.
8. Pros and Cons
Pros
1. GOAP Deterministic Planning, Explainable, Auditable The GOAP planner does not use an LLM at all, and the decision-making process is traceable and explainable. For enterprises, this means compliance and auditing are no longer issues.
2. Significant Cost Advantage GOAP planning without LLM directly cuts 40-60% of LLM calls; the strongly-typed Domain Model precise contract saves 20-40% of Token consumption. Total cost optimization potential is 50-70%.
3. Type Safety, Compile-Time Checks All LLM interactions are strongly typed, and the IDE provides full code completion and refactoring support.
4. Seamless Integration with the Spring Ecosystem Built on Spring Boot, Java/Kotlin developers have zero learning curve to integrate.
5. Avoids LLM "Over-engineering" GOAP planning minimizes unnecessary LLM calls, improving efficiency and cost control.
6. Strong Extensibility New Actions, goals, conditions, and domain objects can be added without modifying existing code.
Cons
1. Relatively Young Project Embabel 1.0 GA was only released in July 2026; the ecosystem and community are still in early stages.
2. Core Written in Kotlin Although fully compatible with Java, reading the framework source code requires understanding Kotlin syntax.
3. Learning Curve Concepts like GOAP and Utility AI are completely new to most Java developers.
4. Documentation Still Improving As a new project, documentation and examples are gradually being improved.
5. Gap with the Python Ecosystem Although Rod Johnson's goal is to "not only catch up with the Python ecosystem but surpass it," the maturity of the Python AI ecosystem currently still leads.
9. Applicable Scenarios
| Scenario | Recommendation Level | Reason |
|---|---|---|
| Enterprise AI Agent | ✅✅✅ Highly Recommended | Explainable, auditable, controllable cost |
| Existing Spring Boot Tech Stack | ✅✅✅ Highly Recommended | Zero learning curve to integrate |
| Finance/Compliance/Auditing Scenarios | ✅✅✅ Highly Recommended | GOAP deterministic planning, every decision traceable |
| Multi-step Complex Task Automation | ✅✅✅ Highly Recommended | GOAP automatically plans the optimal path |
| AI Empowerment for Traditional Enterprise Systems | ✅✅✅ Highly Recommended | No need to rewrite the tech stack |
| RAG Knowledge Base Q&A | ✅✅ Recommended | Official examples like Stashbot |
| High Cost-Sensitive Scenarios | ✅✅✅ Highly Recommended | Directly cuts 40-60% of LLM calls |
| Rapid Prototyping | ⚠️ Might be too heavy | Spring AI might be lighter |
12 project practices at Java Assault Team Network: susan.net.cn/project
10. Final Words
Back to the initial question: What exactly is the AI framework developed by the father of Spring upon his return?
Embabel is not just another "library for calling large models."
It is an enterprise-grade Agent programming model, attempting to answer a core question:
How to make non-deterministic AI work stably in deterministic enterprise systems?
Its answer is:
- Use the GOAP algorithm to provide deterministic planning — planning without LLM, directly cutting 40-60% of calls.
- Use a strongly-typed system to provide compile-time safety — precise contracts save 20-40% of Token consumption.
- Use the Spring ecosystem to provide enterprise-grade integration — based on Spring Boot, zero learning curve.
- Use the Apache 2.0 license to provide business-friendliness — free to use, modify, and commercialize.
- Use 1.0 GA to provide production-grade stability — officially GA on July 20, 2026.
Over twenty years ago, he wrote a book and built a framework, ending the EJB era.
More than twenty years later, he returns with Embabel.
This time, he wants to end the predicament that "AI can only do demos and cannot go into production."
And this time, he has a weapon that the Python ecosystem lacks — GOAP deterministic planning.
While the Python ecosystem is still stacking Agents using "lots of strings, dynamic Graphs, and hand-written node edges," Embabel is already bringing AI Agents into core enterprise business in a type-safe, cost-controllable, auditable, and traceable manner.