Implementing the Planning Pattern With Java Enterprise and LangChain4j
Learn how to implement the Planning Pattern with Enterprise Java, Jakarta EE, CDI, and LangChain4j, enabling AI to transform business goals into executable workflows.
Join the DZone community and get the full member experience.
Join For FreeArtificial intelligence is evolving beyond basic chat interfaces to play an active role in enterprise applications. While initial AI integrations often focus on text generation, summarization, or retrieval-augmented generation (RAG), many business challenges demand more advanced solutions. These require breaking down complex objectives into sequenced tasks and coordinating their execution. The Planning Pattern addresses this need by enabling AI to function as both a content generator and a strategist that creates execution plans.
For software engineers and architects, the Planning Pattern marks a significant advancement in intelligent systems. It separates reasoning from execution, allowing applications to use large language models while ensuring governance, observability, and reliability in enterprise settings.
This article demonstrates how to implement the Planning Pattern in Java, showing how an AI model can convert a high-level business goal into an actionable plan executed by deterministic application services. The resulting architecture blends AI creativity with the predictability and control needed for production systems.
Project Setup and Dependencies
To demonstrate the Planning Pattern, we will build a simple customer service application using Jakarta EE, CDI, and LangChain4j. The scenario is intentionally limited to highlight architectural concepts over business complexity. The application will serve as a customer support assistant, interpreting user requests and routing them to the correct workflow. For this article, we will implement only order cancellation.
This approach keeps the AI layer independent from the business implementation. The assistant interprets customer intent and creates a plan, while application services remain deterministic and enforce business rules. This separation aligns with the Planning Pattern, which treats reasoning and execution as distinct responsibilities.
The following dependencies form the foundation of our sample. Weld SE enables Jakarta CDI in standalone Java applications, SmallRye Config provides configuration support, and LangChain4j CDI integrates AI models into the Jakarta EE programming model.
<dependencies>
<dependency>
<groupId>io.smallrye.config</groupId>
<artifactId>smallrye-config-core</artifactId>
<version>3.17.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.smallrye.config</groupId>
<artifactId>smallrye-config</artifactId>
<version>3.17.2</version>
</dependency>
<dependency>
<groupId>org.jboss.weld.se</groupId>
<artifactId>weld-se-core</artifactId>
<version>6.0.4.Final</version>
</dependency>
<dependency>
<groupId>dev.langchain4j.cdi</groupId>
<artifactId>langchain4j-cdi-portable-ext</artifactId>
<version>${langchain4j-cdi.version}</version>
</dependency>
<dependency>
<groupId>dev.langchain4j.cdi.mp</groupId>
<artifactId>langchain4j-cdi-config</artifactId>
<version>${langchain4j-cdi.version}</version>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai</artifactId>
<version>1.15.0</version>
</dependency>
</dependencies>
With the project configured, the next step is to create our first AI agent. With the project configured, the next step is to create the first AI agent. This agent will serve as the entry point for customer support, receiving natural-language requests and converting them into structured execution plans.
Creating the AI Agent Contract
The first component of our solution is the agent contract. In LangChain4j, an agent is represented as a simple Java interface, enabling developers to focus on business logic instead of framework details. This interface serves as the application's entry point to the AI model. In our customer support scenario, the agent's role is to receive customer requests and determine the appropriate resolution.
public interface CustomerResolutionAgent {
String resolveCustomer(String text);
}
While this interface appears simple, it represents a key architectural concept. Rather than embedding prompts, workflows, or AI-specific logic across the application, we define a business-oriented contract. LangChain4j dynamically generates the implementation, allowing the AI component to function like any other CDI-managed service.
Implementing Enterprise Tools
The Planning Pattern separates reasoning from execution. The model determines required actions, while business operations are implemented as deterministic services. These services are exposed as tools the AI can invoke when building and executing a plan.
@ApplicationScoped
public class EnterpriseTools {
@Tool("Finds the internal customer id given a customer email address")
public String getCustomerId(String email) {
System.out.println("searching for email " + email);
return "CUS-001";
}
@Tool("Finds the order id given a customer id")
public String getOrder(String customerId) {
System.out.println("searching for customer " + customerId);
return "ORD-001";
}
@Tool("Cancels an order given its order id")
public String cancelOrder(String orderId) {
System.out.println("cancelling order " + orderId);
return "cancelled";
}
}
Each method represents a business capability available to the agent. The @Tool annotation offers a natural language description to help the model determine when to use each operation. In production, these methods would interact with databases, external APIs, messaging systems, or domain services. For this example, we simulate the workflow by returning predefined values.
The order cancellation process consists of several independent operations. The AI first identifies the customer, then locates the order, and finally executes the cancellation. This decomposition highlights the value of the Planning Pattern: the model determines the sequence of actions, while the application ensures each action is executed safely and predictably.
Building and Running the Agent
With the contract and tools defined, we can assemble the agent. The factory connects the language model, toolset, and interface contract into a single CDI-managed component.
@ApplicationScoped
public class ResolutionAgentFactory {
@Inject
private ChatModel chatModel;
@Inject
private EnterpriseTools tools;
@Produces
public CustomerResolutionAgent create() {
return AiServices.builder(CustomerResolutionAgent.class)
.chatModel(chatModel)
.tools(tools)
.build();
}
}
Conclusion
The Planning Pattern represents an important architectural evolution in enterprise AI systems. Rather than treating a language model as a simple text generator, it elevates AI to the role of strategist, capable of decomposing business objectives into executable plans while leaving execution to deterministic application services.
By separating reasoning from execution, architects gain the flexibility of AI-driven decision-making without sacrificing governance, observability, or reliability. The language model determines what should happen, while enterprise services remain responsible for how those actions are performed. This distinction preserves existing business rules, security controls, and integration boundaries while enabling more adaptive user experiences.
In this article, we implemented a customer support assistant using Jakarta EE, CDI, and LangChain4j. The agent interpreted a high-level customer request, identified the required sequence of operations, and coordinated enterprise tools to complete the workflow. Although the example focused on order cancellation, the same architecture can support a wide range of enterprise scenarios, including customer onboarding, account management, claims processing, inventory management, and operational workflows.
As organizations move beyond chatbots and retrieval-based applications, patterns such as Planning become increasingly valuable. They provide a structured approach for integrating AI into business processes while maintaining the predictability and control expected from enterprise software. The result is an architecture where AI contributes reasoning and adaptability, while deterministic services continue to provide the reliability required for production environments.
Opinions expressed by DZone contributors are their own.
Comments