CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-dev-langchain4j--langchain4j-agentic

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.

Overview
Eval results
Files

agent-builder.mddocs/api/

Agent Builder API

Complete API reference for creating and configuring individual agents with chat models, tools, memory, RAG, guardrails, and custom behavior.

Quick Start

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");

Factory Methods

AgenticServices

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();

Core Builder Interface

AgentBuilder

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();
}

Essential Configuration

Chat Model Configuration

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();

Agent Metadata

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();

Tools and Execution

Tools Configuration

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();

Concurrent Tool Execution

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();

Tool Error Handling

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();

Memory and Context

Memory Configuration

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();

Context Configuration

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();

Message Configuration

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();

Advanced Features

RAG Configuration

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();

Guardrails Configuration

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);

Default Values

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();

Observability

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();

Untyped Agent Builder

UntypedAgentBuilder

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();

AgentArgument Class

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));

Agent Invocation

UntypedAgent Interface

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();

Supporting Types

/**
 * 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-agentic

docs

index.md

tile.json