GithubHelp home page GithubHelp logo

bsorrentino / langgraph4j Goto Github PK

View Code? Open in Web Editor NEW
54.0 8.0 7.0 7.37 MB

๐Ÿš€ LangGraph for Java. A library for building stateful, multi-actor applications with LLMs, built for work jointly with langchain4j

Home Page: https://bsorrentino.github.io/langgraph4j/

License: MIT License

Java 86.83% TypeScript 1.69% Dockerfile 0.08% Python 1.08% CSS 0.03% HTML 0.74% JavaScript 8.31% Mustache 1.13% Shell 0.12%
agents langchain4j langgraph

langgraph4j's Introduction

LangGraph for Java

Javadoc Static Badge Maven Central

๐Ÿฆœ๐Ÿ•ธ๏ธLangGraph for Java. A library for building stateful, multi-agents applications with LLMs, built for work with langchain4j

It is a porting of original LangGraph from LangChain AI project in Java fashion

News

Date Release info
Aug 02, 2024 1.0-beta1 first official beta release

Quick Start

Adding LangGraph dependency

Last stable version

Maven

<dependency>
    <groupId>org.bsc.langgraph4j</groupId>
    <artifactId>langgraph4j-core-jdk8</artifactId>
    <version>1.0-beta1</version>
<dependency>

Development Version

Maven

<dependency>
    <groupId>org.bsc.langgraph4j</groupId>
    <artifactId>langgraph4j-core-jdk8</artifactId>
    <version>1.0-SNAPSHOT</version>
<dependency>

Define the agent state

The main type of graph in langgraph is the StatefulGraph. This graph is parameterized by a state object that it passes around to each node. Each node then returns operations to update that state. These operations can either SET specific attributes on the state (e.g. overwrite the existing values) or ADD to the existing attribute. Whether to set or add is described in the state's schema provided to the graph. The schema is a Map of Channels, each Channel represent an attribute in the state. If an attribute is described with an AppendeChannel it will be a List and each element referring the attribute will be automaically added by graph during processing. The State must inherit from AgentState base class (that essentially is a Map wrapper).

public class AgentState {

   public AgentState( Map<String,Object> initData ) { ... }
   
   public final java.util.Map<String,Object> data() { ... }

   public final <T> Optional<T> value(String key) { ... }
   public final <T> T value(String key, T defaultValue ) { ... }
   public final <T> T value(String key, Supplier<T>  defaultProvider ) { ... }
    

}

Define the nodes

We now need to define a few different nodes in our graph. In langgraph, a node is an async/sync function that accept an AgentState as argument and returns a (partial) state update. There are two main nodes we need for this:

  1. The agent: responsible for deciding what (if any) actions to take.
  2. A function to invoke tools: if the agent decides to take an action, this node will then execute that action.
/**
 * Represents an asynchronous node action that operates on an agent state and returns state update.
 *
 * @param <S> the type of the agent state
 */
@FunctionalInterface
public interface AsyncNodeAction<S extends AgentState> extends Function<S, CompletableFuture<Map<String, Object>>> {

    CompletableFuture<Map<String, Object>> apply(S t);

    /**
     * Creates an asynchronous node action from a synchronous node action.
     */
    static <S extends AgentState> AsyncNodeAction<S> node_async(NodeAction<S> syncAction) { ... }
}

Define Edges

We will also need to define some edges. Some of these edges may be conditional. The reason they are conditional is that based on the output of a node, one of several paths may be taken. The path that is taken is not known until that node is run (the LLM decides).

  1. Conditional Edge: after the agent is called, we should either:
    • If the agent said to take an action, then the function to invoke tools should be called
    • If the agent said that it was finished, then it should finish
  2. Normal Edge: after the tools are invoked, it should always go back to the agent to decide what to do next
/**
 * Represents an asynchronous edge action that operates on an agent state and returns a new route.
 *
 * @param <S> the type of the agent state
 */
public interface AsyncEdgeAction<S extends AgentState> extends Function<S, CompletableFuture<String>> {

    CompletableFuture<String> apply(S t);

    /**
     * Creates an asynchronous edge action from a synchronous edge action.
     */
    static <S extends AgentState> AsyncEdgeAction<S> edge_async(EdgeAction<S> syncAction ) { ... }
}

Define the graph

We can now put it all together and define the graph! (see example below)

Integrate with LangChain4j

Like default use case proposed in LangGraph blog, We have ported AgentExecutor implementation from langchain using LangGraph4j. In the agents project's module, you can the complete working code with tests. Feel free to checkout and use it as a reference. Below you can find a piece of code of the AgentExecutor to give you an idea of how is has built in langgraph style.

public static class State implements AgentState {

    // the state's (partial) schema 
    static Map<String, Channel<?>> SCHEMA = mapOf(
        "intermediate_steps", AppenderChannel.<IntermediateStep>of(ArrayList::new)
    );

    public State(Map<String, Object> initData) {
        super(initData);
    }

    Optional<String> input() {
        return value("input");
    }
    Optional<AgentOutcome> agentOutcome() {
        return value("agent_outcome");
    }
    List<IntermediateStep> intermediateSteps() {
        return this.<List<IntermediateStep>>value("intermediate_steps").orElseGet(emptyList());
    }
   
}

var toolInfoList = ToolInfo.fromList( objectsWithTools );

final List<ToolSpecification> toolSpecifications = toolInfoList.stream()
        .map(ToolInfo::specification)
        .toList();

var agentRunnable = Agent.builder()
                        .chatLanguageModel(chatLanguageModel)
                        .tools( toolSpecifications )
                        .build();

// Fluent Interface
var app = new StateGraph<>(State.SCHEMA,State::new)
                .addEdge(START,"agent")
                .addNode( "agent", node_async( state ->
                    runAgent(agentRunnable, state))
                )
                .addNode( "action", node_async( state ->
                    executeTools(toolInfoList, state))
                )
                .addConditionalEdges(
                        "agent",
                        edge_async( state -> {
                            if (state.agentOutcome().map(AgentOutcome::finish).isPresent()) {
                                return "end";
                            }
                            return "continue";
                        }),
                        mapOf("continue", "action", "end", END)
                )
                .addEdge("action", "agent")
                .compile();

return  app.stream( inputs );

Samples

Playground Webapp

It is available an embed playground webapp able to run a Langgraph4j workflow in visual way.

Maven

<dependency>
    <groupId>org.bsc.langgraph4j</groupId>
    <artifactId>langgraph4j-server-jetty</artifactId>
    <version>1.0-SNAPSHOT</version>
<dependency>

Sample

Code

StateGraph<AgentState> workflow = new StateGraph<>( AgentState::new );

// define your workflow   

...

// compile workflow
CompiledGraph<AgentState> app = workflow.compile();

// connect playgroud webapp to workflow
var server = LangGraphStreamingServer.builder()
                                      .port(8080)
                                      .title("LANGGRAPH4j - TEST")
                                      .addInputStringArg("input")
                                      .build(app);
// start playground
server.start().join();

Demo

result

References

langgraph4j's People

Contributors

bsorrentino avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

langgraph4j's Issues

Evaluate to implement other use cases from langgraph tutorial

Original langgraph tutorial contains a lot of interesting examples, I would implements others to promote langgraph4j as first citizen in langchain4j eco-system:

RAG

Agent Architectures

Multi-Agent Systems

Planning Agents

Reflection & Critique

Development Plan

Thanks for your excellent project. I'm reaching out to ask if you could share the development roadmap or plans for the project.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.