Skip to content

logo LangChain4j Integrations

LangGraph4j seamlessly integrates with LangChain4j enabling developers to build powerful LLM-based applications using familiar tools in the Java ecosystem.

Features

  • Graph Nodes as Langchain4j Components: You can use LangChain4j tools (LLM, prompt templates, retrievers, etc.) as nodes in your LangGraph4j StateGraph.
  • Function Call Handling: Automatically supports LangChain4j’s structured function calling, parsing arguments directly into graph state.
  • Chain of Thought: Combine multiple LangChain4j calls in sequence, branching based on results.
  • Streaming: LangChain4j’s streaming responses can be processed and streamed through LangGraph4j’s async graph.

Benefits

✅ No need to rebuild logic – reuse your Langchain4j services

✅ Compose LLM workflows visually or programmatically

✅ Scalable, conditional execution of LLM calls

✅ Easy to debug and visualize

Adding Dependencies

<dependency>
    <groupId>org.bsc.langgraph4j</groupId>
    <artifactId>langgraph4j-langchain4j</artifactId>
    <version>1.7-SNAPSHOT</version>
</dependency>

Share LangGraph4j's state to tools

When you use LangGraph4j service LC4jToolService to invoke a tool you can pass the State throught the LangChain4j InvocationParameters see snippets below:

//
// Passing State information to the call
//

// create tool service
var toolService = LC4jToolService.builder()
                         .toolsFromObject( tools )
                         .build();

ToolExecutionRequest toolExecutionRequest = ... // The object returned by LLM response to notify tool invocation request

Map<String,Object> state = Map.of( "arg1", "value1" )

Command callResult = toolService.execute(
                            List.of(toolExecutionRequest),
                            InvocationContext.builder()
                                    .invocationParameters(InvocationParameters.from(state))
                                    .build()
                            , "messages" ).join();
//
// Retrieve State information from the tool
//
 class Tools {

    @Tool("tool for test passing context")
    String execTestWithContext(@P("test message") String message, InvocationParameters context ) {

        assertNotNull( context );
        assertEquals( "value1", context.get("arg1") );

        return "test tool executed: %s with context".formatted( message );
    }

}

It is also possible update state from the tool using SpringAIToolResponseBuilder

class Tools {
    //
    // Update State information from the tool
    //
    @Tool("tool for test passing context and return command")
    String execTestWithContextAndReturnCommand(@P("test message") String message, InvocationParameters context ) {

        assertNotNull( context );
        assertEquals( "value1", context.get("arg1") );

        return LC4jToolResponseBuilder.of( context )
                .update( Map.of( "arg2", "value2"))
                .buildAndReturn( "test tool executed: %s with context".formatted(message) );
    }
}

ReACT Agent

The Agent Executor is a runtime for agents.

Diagram

diagram

How to use

public class TestTool {
    private String lastResult;

    Optional<String> lastResult() {
        return Optional.ofNullable(lastResult);
    }

    @Tool("tool for test AI agent executor")
    String execTest(@P("test message") String message) {

        lastResult = format( "test tool executed: %s", message);
        return lastResult;
    }
}

public void main( String args[] ) throws Exception {

    var toolSpecification = ToolSpecification.builder()
            .name("getPCName")
            .description("Returns a String - PC name the AI is currently running in. Returns null if station is not running")
            .build();

    var toolExecutor = (toolExecutionRequest, memoryId) -> getPCName();

    var chatModel = OpenAiChatModel.builder()
            .apiKey( System.getenv( "OPENAI_API_KEY" ) )
            .modelName( "gpt-4o-mini" )
            .logResponses(true)
            .maxRetries(2)
            .temperature(0.0)
            .maxTokens(2000)
            .build();


    var agentExecutor = AgentExecutor.builder()
            .chatModel(chatModel)
            // add dynamic tool
            .toolsFromObject(new TestTool())
            // add dynamic tool
            .tool(toolSpecification, toolExecutor)
            .build();

    var workflow = agentExecutor.compile();

    var iterator =  workflow.stream( Map.of( "messages", UserMessage.from("Run my test!") ) );

    for( var step : iterator ) {
        System.out.println( step );
    }
}