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.
class Calculator {
@Tool("Add two numbers")
public int add(int a, int b) {
return a + b;
}
}
UntypedAgent agent = AgenticServices.agentBuilder()
.chatModel(chatModel)
.tools(new Calculator())
.maxSequentialToolsInvocations(5)
.build();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();
// Invoke with memory ID
Object result = agent.invoke("user123", "What did I say before?");import dev.langchain4j.rag.content.retriever.ContentRetriever;
// Assuming you have a ContentRetriever (from langchain4j-core)
// ContentRetriever retriever = ...;
UntypedAgent agent = AgenticServices.agentBuilder()
.chatModel(chatModel)
.contentRetriever(retriever)
.build();UntypedAgent pipeline = AgenticServices.sequenceBuilder()
.subAgents(fetchAgent, processAgent, validateAgent)
.name("data-pipeline")
.build();
Object result = pipeline.invoke("Process this data");UntypedAgent parallel = AgenticServices.parallelBuilder()
.subAgents(analyzer1, analyzer2, analyzer3)
.threadPoolSize(3)
.name("multi-analyzer")
.build();
Object result = parallel.invoke("Analyze this text");UntypedAgent retryLoop = AgenticServices.loopBuilder()
.subAgents(apiCallAgent)
.maxIterations(3)
.exitCondition(scope -> scope.readState("success") != null)
.name("api-retry")
.build();UntypedAgent router = AgenticServices.conditionalBuilder()
.subAgents(
scope -> "premium".equals(scope.readState("tier")),
premiumAgent
)
.subAgents(
scope -> true, // Default fallback
standardAgent
)
.name("tier-router")
.build();import dev.langchain4j.agentic.supervisor.SupervisorAgent;
import dev.langchain4j.agentic.supervisor.SupervisorContextStrategy;
import dev.langchain4j.agentic.supervisor.SupervisorResponseStrategy;
SupervisorAgent supervisor = AgenticServices.supervisorBuilder()
.chatModel(chatModel)
.subAgents(researchAgent, analysisAgent, writingAgent)
.maxAgentsInvocations(10)
.contextGenerationStrategy(SupervisorContextStrategy.FULL)
.responseStrategy(SupervisorResponseStrategy.SUMMARY)
.build();UntypedAgent agent1 = AgenticServices.agentBuilder()
.chatModel(chatModel)
.name("fetcher")
.outputKey("raw_data")
.build();
UntypedAgent agent2 = AgenticServices.agentBuilder()
.chatModel(chatModel)
.name("processor")
.context(scope -> {
String data = (String) scope.readState("raw_data");
return "Process this data: " + data;
})
.build();
UntypedAgent pipeline = AgenticServices.sequenceBuilder()
.subAgents(agent1, agent2)
.build();UntypedAgent agent = AgenticServices.sequenceBuilder()
.subAgents(processor)
.errorHandler(ctx -> {
if (ctx.exception() instanceof RetryableException) {
int retries = ctx.agenticScope().readState("retry_count", 0);
if (retries < 3) {
ctx.agenticScope().writeState("retry_count", retries + 1);
return ErrorRecoveryResult.retry();
}
}
return ErrorRecoveryResult.throwException();
})
.build();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();interface DataPipeline {
@SequenceAgent(
name = "etl-pipeline",
subAgents = {Extractor.class, Transformer.class, Loader.class}
)
String runETL(String source);
}
interface Extractor {
@Agent(name = "extractor", outputKey = "raw_data")
String extract(String source);
}
interface Transformer {
@Agent(name = "transformer", outputKey = "transformed_data")
String transform(String input);
}
interface Loader {
@Agent(name = "loader")
String load(String input);
}
DataPipeline pipeline = AgenticServices.createAgenticSystem(DataPipeline.class, chatModel);
String result = pipeline.runETL("database://source");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