LangChain4j Agentic Framework provides a comprehensive Java library for building multi-agent AI systems with support for workflow orchestration, supervisor agents, planning-based execution, declarative configuration, agent-to-agent communication, and human-in-the-loop workflows.
Complete API reference for creating and configuring individual agents with chat models, tools, memory, RAG, guardrails, and custom behavior.
import dev.langchain4j.agentic.AgenticServices;
import dev.langchain4j.agentic.UntypedAgent;
// Create simple agent
UntypedAgent agent = AgenticServices.agentBuilder()
.chatModel(chatModel)
.tools(calculator)
.build();
Object result = agent.invoke("Calculate 15 * 7");Central factory class for creating all types of agents and builders.
class AgenticServices {
/**
* Create an untyped agent builder
* @return UntypedAgentBuilder for configuring untyped agents
*/
static UntypedAgentBuilder agentBuilder();
/**
* Create a typed agent builder for a specific agent interface
* @param agentServiceClass The agent interface class
* @return AgentBuilder for configuring typed agents
*/
static <T> AgentBuilder<T, ?> agentBuilder(Class<T> agentServiceClass);
}Usage Examples:
// Untyped agent
UntypedAgent agent = AgenticServices.agentBuilder()
.chatModel(chatModel)
.tools(calculator)
.build();
// Typed agent
interface MathAgent {
String calculate(String expression);
}
MathAgent mathAgent = AgenticServices.agentBuilder(MathAgent.class)
.chatModel(chatModel)
.tools(calculator)
.build();Fluent builder for configuring typed agents.
/**
* Fluent builder for configuring typed agents
* @param <T> Agent service interface type
* @param <B> Builder type for method chaining
*/
interface AgentBuilder<T, B> {
/**
* Build and return the configured agent
* @return Configured agent instance
*/
T build();
}Configure the language model for the agent.
/**
* Set the chat model for agent conversations
* @param model ChatModel instance from langchain4j-core
* @return Builder for chaining
*/
B chatModel(dev.langchain4j.model.chat.ChatModel model);
/**
* Set the streaming chat model for agent conversations
* @param streamingChatModel StreamingChatModel instance from langchain4j-core
* @return Builder for chaining
*/
B streamingChatModel(dev.langchain4j.model.chat.StreamingChatModel streamingChatModel);Usage Examples:
import dev.langchain4j.agentic.AgenticServices;
import dev.langchain4j.agentic.UntypedAgent;
UntypedAgent agent = AgenticServices.agentBuilder()
.chatModel(chatModel)
.build();Configure agent name, description, and output behavior.
/**
* Set agent name
* @param name Agent name
* @return Builder for chaining
*/
B name(String name);
/**
* Set agent description
* @param description Agent description
* @return Builder for chaining
*/
B description(String description);
/**
* Set output key for storing results in AgenticScope
* @param outputKey String key for output
* @return Builder for chaining
*/
B outputKey(String outputKey);
/**
* Set typed output key for storing results in AgenticScope
* @param outputKey TypedKey class for output
* @return Builder for chaining
*/
B outputKey(Class<? extends TypedKey<?>> outputKey);
/**
* Set whether agent executes asynchronously
* @param async True for async execution
* @return Builder for chaining
*/
B async(boolean async);Usage Examples:
UntypedAgent agent = AgenticServices.agentBuilder()
.chatModel(chatModel)
.name("research-agent")
.description("Researches topics using web search")
.outputKey("research_results")
.async(false)
.build();Configure tools that the agent can invoke.
/**
* Add tools from objects with @Tool annotated methods
* @param objectsWithTools Objects containing tool methods
* @return Builder for chaining
*/
B tools(Object... objectsWithTools);
/**
* Add tools from a map of specifications to executors
* @param toolsMap Map of ToolSpecification to ToolExecutor
* @return Builder for chaining
*/
B tools(Map<ToolSpecification, ToolExecutor> toolsMap);
/**
* Add tools with immediate return tool names
* @param toolsMap Map of tools
* @param immediateReturnToolNames Set of tool names that return immediately
* @return Builder for chaining
*/
B tools(Map<ToolSpecification, ToolExecutor> toolsMap, Set<String> immediateReturnToolNames);
/**
* Set tool provider for dynamic tool loading
* @param toolProvider ToolProvider instance
* @return Builder for chaining
*/
B toolProvider(ToolProvider toolProvider);
/**
* Set maximum sequential tool invocations
* @param maxSequentialToolsInvocations Maximum number of sequential tool calls
* @return Builder for chaining
*/
B maxSequentialToolsInvocations(int maxSequentialToolsInvocations);
/**
* Set strategy for handling hallucinated tool names
* @param hallucinatedToolNameStrategy Function to handle hallucinated tool requests
* @return Builder for chaining
*/
B hallucinatedToolNameStrategy(Function<ToolExecutionRequest, ToolExecutionResultMessage> hallucinatedToolNameStrategy);Usage Examples:
import dev.langchain4j.agent.tool.Tool;
class Calculator {
@Tool("Add two numbers")
public int add(int a, int b) {
return a + b;
}
@Tool("Multiply two numbers")
public int multiply(int a, int b) {
return a * b;
}
}
UntypedAgent agent = AgenticServices.agentBuilder()
.chatModel(chatModel)
.tools(new Calculator())
.maxSequentialToolsInvocations(5)
.build();Enable parallel execution of multiple tool calls.
/**
* Enable concurrent tool execution with default executor
* @return Builder for chaining
*/
B executeToolsConcurrently();
/**
* Enable concurrent tool execution with custom executor
* @param executor Custom Executor for tool execution
* @return Builder for chaining
*/
B executeToolsConcurrently(Executor executor);Usage Examples:
// Default concurrent execution
UntypedAgent agent = AgenticServices.agentBuilder()
.chatModel(chatModel)
.tools(calculator)
.executeToolsConcurrently()
.build();
// Custom executor
ExecutorService customExecutor = Executors.newFixedThreadPool(5);
UntypedAgent agent = AgenticServices.agentBuilder()
.chatModel(chatModel)
.tools(calculator)
.executeToolsConcurrently(customExecutor)
.build();Configure error handlers for tool arguments and execution.
/**
* Set error handler for tool argument parsing errors
* @param toolArgumentsErrorHandler Error handler
* @return Builder for chaining
*/
B toolArgumentsErrorHandler(ToolArgumentsErrorHandler toolArgumentsErrorHandler);
/**
* Set error handler for tool execution errors
* @param toolExecutionErrorHandler Error handler
* @return Builder for chaining
*/
B toolExecutionErrorHandler(ToolExecutionErrorHandler toolExecutionErrorHandler);Usage Examples:
UntypedAgent agent = AgenticServices.agentBuilder()
.chatModel(chatModel)
.tools(calculator)
.toolExecutionErrorHandler((error, toolExecutionRequest) -> {
System.err.println("Tool error: " + error.getMessage());
return "Error executing tool: " + toolExecutionRequest.name();
})
.build();Configure chat memory for maintaining conversation history.
/**
* Set chat memory for conversation history
* @param chatMemory ChatMemory instance from langchain4j-core
* @return Builder for chaining
*/
B chatMemory(dev.langchain4j.memory.ChatMemory chatMemory);
/**
* Set chat memory provider for multi-user scenarios
* @param chatMemoryProvider Provider of ChatMemory instances from langchain4j-core
* @return Builder for chaining
*/
B chatMemoryProvider(dev.langchain4j.memory.chat.ChatMemoryProvider chatMemoryProvider);Usage Examples:
import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
ChatMemory memory = MessageWindowChatMemory.withMaxMessages(10);
UntypedAgent agent = AgenticServices.agentBuilder()
.chatModel(chatModel)
.chatMemory(memory)
.build();Configure how the agent receives context from other agents.
/**
* Set context provider function
* @param contextProvider Function that generates context from AgenticScope
* @return Builder for chaining
*/
B context(Function<AgenticScope, String> contextProvider);
/**
* Set agents whose context should be summarized
* @param contextProvidingAgents Names of agents to include in summarized context
* @return Builder for chaining
*/
B summarizedContext(String... contextProvidingAgents);Usage Examples:
UntypedAgent agent = AgenticServices.agentBuilder()
.chatModel(chatModel)
.context(scope -> scope.contextAsConversation("agent1", "agent2"))
.build();
// Or use summarized context
UntypedAgent agent2 = AgenticServices.agentBuilder()
.chatModel(chatModel)
.summarizedContext("research-agent", "planning-agent")
.build();Configure system and user message templates.
/**
* Set static system message
* @param systemMessage System message text
* @return Builder for chaining
*/
B systemMessage(String systemMessage);
/**
* Set dynamic system message provider
* @param systemMessageProvider Function to generate system message
* @return Builder for chaining
*/
B systemMessageProvider(Function<Object, String> systemMessageProvider);
/**
* Set static user message template
* @param userMessage User message template
* @return Builder for chaining
*/
B userMessage(String userMessage);
/**
* Set dynamic user message provider
* @param userMessageProvider Function to generate user message
* @return Builder for chaining
*/
B userMessageProvider(Function<Object, String> userMessageProvider);Usage Examples:
UntypedAgent agent = AgenticServices.agentBuilder()
.chatModel(chatModel)
.systemMessage("You are a helpful assistant specialized in mathematics.")
.userMessage("Please solve: {{input}}")
.build();Configure Retrieval Augmented Generation for the agent.
/**
* Set content retriever for RAG
* @param contentRetriever ContentRetriever instance from langchain4j-core
* @return Builder for chaining
*/
B contentRetriever(dev.langchain4j.rag.content.retriever.ContentRetriever contentRetriever);
/**
* Set retrieval augmentor for RAG
* @param retrievalAugmentor RetrievalAugmentor instance from langchain4j-core
* @return Builder for chaining
*/
B retrievalAugmentor(dev.langchain4j.rag.RetrievalAugmentor retrievalAugmentor);Usage Examples:
import dev.langchain4j.rag.content.retriever.ContentRetriever;
UntypedAgent agent = AgenticServices.agentBuilder()
.chatModel(chatModel)
.contentRetriever(retriever)
.build();Configure input and output validation guardrails.
/**
* Set input guardrails configuration
* @param inputGuardrailsConfig Configuration from langchain4j-core
* @return Builder for chaining
*/
B inputGuardrailsConfig(dev.langchain4j.guardrail.config.InputGuardrailsConfig inputGuardrailsConfig);
/**
* Set output guardrails configuration
* @param outputGuardrailsConfig Configuration from langchain4j-core
* @return Builder for chaining
*/
B outputGuardrailsConfig(dev.langchain4j.guardrail.config.OutputGuardrailsConfig outputGuardrailsConfig);
/**
* Set input guardrail classes
* @param inputGuardrailClasses Classes of input guardrails from langchain4j-core
* @return Builder for chaining
*/
<I extends dev.langchain4j.guardrail.InputGuardrail> B inputGuardrailClasses(Class<? extends I>... inputGuardrailClasses);
/**
* Set output guardrail classes
* @param outputGuardrailClasses Classes of output guardrails from langchain4j-core
* @return Builder for chaining
*/
<O extends OutputGuardrail> B outputGuardrailClasses(Class<? extends O>... outputGuardrailClasses);
/**
* Set input guardrail instances
* @param inputGuardrails Input guardrail instances
* @return Builder for chaining
*/
<I extends InputGuardrail> B inputGuardrails(I... inputGuardrails);
/**
* Set output guardrail instances
* @param outputGuardrails Output guardrail instances
* @return Builder for chaining
*/
<O extends OutputGuardrail> B outputGuardrails(O... outputGuardrails);Configure default key-value pairs for AgenticScope.
/**
* Set default key-value pair for AgenticScope
* @param key String key
* @param value Default value
* @return Builder for chaining
*/
B defaultKeyValue(String key, Object value);
/**
* Set typed default key-value pair for AgenticScope
* @param key TypedKey class
* @param value Default value
* @return Builder for chaining
*/
<K> B defaultKeyValue(Class<? extends TypedKey<K>> key, K value);Usage Examples:
UntypedAgent agent = AgenticServices.agentBuilder()
.chatModel(chatModel)
.defaultKeyValue("temperature", 0.7)
.defaultKeyValue("max_retries", 3)
.build();Add listeners for monitoring agent execution.
/**
* Add agent listener for observability
* @param agentListener AgentListener instance
* @return Builder for chaining
*/
B listener(AgentListener agentListener);Usage Examples:
import dev.langchain4j.agentic.observability.AgentListener;
import dev.langchain4j.agentic.observability.AgentRequest;
import dev.langchain4j.agentic.observability.AgentResponse;
AgentListener listener = new AgentListener() {
@Override
public void beforeAgentInvocation(AgentRequest request) {
System.out.println("Invoking: " + request.agentName());
}
@Override
public void afterAgentInvocation(AgentResponse response) {
System.out.println("Completed in: " + response.duration());
}
};
UntypedAgent agent = AgenticServices.agentBuilder()
.chatModel(chatModel)
.listener(listener)
.build();Extended builder for untyped agents with additional configuration methods.
/**
* Builder for untyped agents with enhanced configuration
*/
interface UntypedAgentBuilder extends AgentBuilder<UntypedAgent, UntypedAgentBuilder> {
/**
* Set return type for the agent
* @param returnType Class representing the return type
* @return Builder for chaining
*/
UntypedAgentBuilder returnType(Class<?> returnType);
/**
* Set agent input arguments
* @param arguments Agent input argument definitions
* @return Builder for chaining
*/
UntypedAgentBuilder inputs(AgentArgument... arguments);
/**
* Map input key for specific parameter type
* @param parameterType Parameter class type
* @param key Key name for the parameter
* @return Builder for chaining
*/
UntypedAgentBuilder inputKey(Class<?> parameterType, String key);
/**
* Map two input keys for parameters
* @param key1Type First parameter type
* @param key1 First key name
* @param key2Type Second parameter type
* @param key2 Second key name
* @return Builder for chaining
*/
UntypedAgentBuilder inputKeys(Class<?> key1Type, String key1, Class<?> key2Type, String key2);
/**
* Map three input keys for parameters
* @param key1Type First parameter type
* @param key1 First key name
* @param key2Type Second parameter type
* @param key2 Second key name
* @param key3Type Third parameter type
* @param key3 Third key name
* @return Builder for chaining
*/
UntypedAgentBuilder inputKeys(Class<?> key1Type, String key1, Class<?> key2Type, String key2, Class<?> key3Type, String key3);
/**
* Map four input keys for parameters
* @param key1Type First parameter type
* @param key1 First key name
* @param key2Type Second parameter type
* @param key2 Second key name
* @param key3Type Third parameter type
* @param key3 Third key name
* @param key4Type Fourth parameter type
* @param key4 Fourth key name
* @return Builder for chaining
*/
UntypedAgentBuilder inputKeys(Class<?> key1Type, String key1, Class<?> key2Type, String key2, Class<?> key3Type, String key3, Class<?> key4Type, String key4);
}Usage Examples:
// Create untyped agent with return type
UntypedAgent agent = AgenticServices.agentBuilder()
.chatModel(chatModel)
.returnType(String.class)
.build();
// Create with input arguments
UntypedAgent agentWithInputs = AgenticServices.agentBuilder()
.chatModel(chatModel)
.inputs(
new AgentArgument(String.class, "query"),
new AgentArgument(Integer.class, "maxResults", 10)
)
.build();
// Map input keys to parameters
UntypedAgent agentWithKeys = AgenticServices.agentBuilder()
.chatModel(chatModel)
.inputKey(String.class, "user_query")
.inputKey(Integer.class, "limit")
.build();
// Map multiple keys at once
UntypedAgent multiKeyAgent = AgenticServices.agentBuilder()
.chatModel(chatModel)
.inputKeys(
String.class, "query",
Integer.class, "maxResults"
)
.build();Defines input argument metadata for untyped agents.
/**
* Argument definition for untyped agents
*/
class AgentArgument {
/**
* Create agent argument
* @param type Parameter type
* @param name Parameter name
*/
public AgentArgument(Type type, String name);
/**
* Create agent argument with default value
* @param type Parameter type
* @param name Parameter name
* @param defaultValue Default value for parameter
*/
public AgentArgument(Type type, String name, Object defaultValue);
/**
* Get parameter type
* @return Type of the parameter
*/
public Type type();
/**
* Get parameter name
* @return Name of the parameter
*/
public String name();
/**
* Get default value
* @return Default value or null
*/
public Object defaultValue();
/**
* Get raw class type
* @return Class representing the type
*/
public Class<?> rawType();
}Usage Examples:
// Create simple arguments
AgentArgument queryArg = new AgentArgument(String.class, "query");
AgentArgument limitArg = new AgentArgument(Integer.class, "limit", 10);
// Use in agent builder
UntypedAgent agent = AgenticServices.agentBuilder()
.chatModel(chatModel)
.inputs(queryArg, limitArg)
.build();
// Access argument properties
System.out.println("Argument name: " + queryArg.name());
System.out.println("Argument type: " + queryArg.type());
System.out.println("Has default: " + (limitArg.defaultValue() != null));Interface for invoking untyped agents with various input formats.
/**
* Generic interface for untyped agent invocations
*/
interface UntypedAgent {
/**
* Invoke agent with string input
* @param input Input string
* @return Agent response
*/
Object invoke(String input);
/**
* Invoke agent with memory ID and input
* @param memoryId Memory identifier
* @param input Input string
* @return Agent response
*/
Object invoke(Object memoryId, String input);
/**
* Invoke agent with memory ID, input, and additional arguments
* @param memoryId Memory identifier
* @param input Input string
* @param args Additional arguments
* @return Agent response
*/
Object invoke(Object memoryId, String input, Object... args);
/**
* Invoke agent with argument map
* @param arguments Map of argument names to values
* @return Agent response
*/
Object invoke(Map<String, Object> arguments);
/**
* Invoke agent with memory ID and argument map
* @param memoryId Memory identifier
* @param arguments Map of argument names to values
* @return Agent response
*/
Object invoke(Object memoryId, Map<String, Object> arguments);
/**
* Invoke agent and return result with AgenticScope
* @param input Input string
* @return ResultWithAgenticScope containing result and scope
*/
ResultWithAgenticScope<Object> invokeWithAgenticScope(String input);
/**
* Invoke agent with memory ID and return result with AgenticScope
* @param memoryId Memory identifier
* @param input Input string
* @return ResultWithAgenticScope containing result and scope
*/
ResultWithAgenticScope<Object> invokeWithAgenticScope(Object memoryId, String input);
/**
* Invoke agent with memory ID, input, args and return result with AgenticScope
* @param memoryId Memory identifier
* @param input Input string
* @param args Additional arguments
* @return ResultWithAgenticScope containing result and scope
*/
ResultWithAgenticScope<Object> invokeWithAgenticScope(Object memoryId, String input, Object... args);
/**
* Invoke agent with argument map and return result with AgenticScope
* @param arguments Map of argument names to values
* @return ResultWithAgenticScope containing result and scope
*/
ResultWithAgenticScope<Object> invokeWithAgenticScope(Map<String, Object> arguments);
/**
* Invoke agent with memory ID, argument map and return result with AgenticScope
* @param memoryId Memory identifier
* @param arguments Map of argument names to values
* @return ResultWithAgenticScope containing result and scope
*/
ResultWithAgenticScope<Object> invokeWithAgenticScope(Object memoryId, Map<String, Object> arguments);
}Usage Examples:
UntypedAgent agent = AgenticServices.agentBuilder()
.chatModel(chatModel)
.build();
// Simple invocation
Object result = agent.invoke("Hello, world!");
// With memory ID
Object result2 = agent.invoke("user123", "What did I say before?");
// With arguments map
Map<String, Object> args = Map.of(
"query", "weather in NYC",
"format", "json"
);
Object result3 = agent.invoke(args);
// Get result with scope
ResultWithAgenticScope<Object> resultWithScope = agent.invokeWithAgenticScope("Hello!");
Object value = resultWithScope.result();
AgenticScope scope = resultWithScope.agenticScope();/**
* Wrapper for result with agentic scope
*/
record ResultWithAgenticScope<T>(T result, AgenticScope agenticScope) { }
/**
* Error context information
*/
record ErrorContext(Throwable error, AgenticScope agenticScope) { }
/**
* Error recovery result
*/
record ErrorRecoveryResult(Object result, boolean continueExecution) { }Install with Tessl CLI
npx tessl i tessl/maven-dev-langchain4j--langchain4j-agenticdocs
declarative
A2AClientAgent
ActivationCondition
Agent
ConditionalAgent
ErrorHandler
ExitCondition
HumanInTheLoop
HumanInTheLoopResponseSupplier
LoopAgent
LoopCounter
Output
ParallelAgent
ParallelExecutor
PlannerAgent
SequenceAgent
SupervisorAgent
SupervisorRequest
quick-start
workflows