网站建设合同的结构,windows云桌面,江苏军民融合网站建设,自己如何做棋牌网站LangGraph4j 是一个 Java实现的开源 AI 工作流框架#xff0c;它受到了 Python 版本 LangGraph的启发#xff0c;能够与 LangChain4j 和 Spring AI无缝集成#xff0c;而且这个框架还是开源的。
核心特性
1、StateGraph 工作流图
在LangGraph4j 中#xff0c;StateGraph 是…LangGraph4j 是一个 Java实现的开源 AI 工作流框架它受到了 Python 版本 LangGraph的启发能够与 LangChain4j 和 Spring AI无缝集成而且这个框架还是开源的。核心特性1、StateGraph 工作流图在LangGraph4j 中StateGraph 是主要使用的核心类用于定义应用程序的结构。它将复杂的AI工作流抽象为一个有向图 的概念。每个 节点 代表一个具体的操作单元比如调用 LLM 生成文本、搜索外部数据、处理用户输入等。节点之间通过 边 来连接多个节点之间通过 状态 来共享数据形成了一个完整的处理流程。和传统的有向无环图不同LangGraph4j 支持循环比如一个智能体可能需要根据结果回到之前的步骤进行重试或者需要在某个条件满足之前持续循环执行某个逻辑。注意使用图之前必须编译编译过程不仅会进行基础的结构检查还会定义运行时参数创建一个不可变的、可运行的图。2、AgentState 状态AgentState 是整个工作流的状态载体它本质上是一个Map在不同节点之间传递。每个节点都可以从这个状态中读取数据并返回对状态的更新。注意实际应用中如果不需要利用 LangChain4j 的持久化机制就不建议大家用内置的 Schema 和 Reducer 来维护状态了。不如自己定义一个Context 上下文类来管理状态想怎么操作状态就怎么操作不用理解 LangGraph4j 自己的一套语法。3、Nodes工作节点节点是图的构建块负责执行具体的操作。工作流程首先接收当前的AgentState 状态作为输入然后执行某些计算比如调用 LLM、执行工具、运行自定义业务逻辑最后返回一个 MapStringObject表示对状态的更新。这些更新会根据 Schema中定义的 Reducer应用到 AgentState 中。节点可以是同步的也可以是异步的甚至可以多个节点同时执行。LangGraph4j 还定义了两个特殊的节点START 和 END。START 节点表示图的入口点END节点表示执行路径的结束点。importstaticorg.bsc.langgraph4j.StateGraph.START;importstaticorg.bsc.langgraph4j.StateGraph.END;graph.addEdge(START,nodeA);graph.addEdge(nodeA,END);4、Edges 边边定义了节点之间的控制流决定了工作流的执行路径。正如官方文档所说“节点负责干活边负责决定下一步”。LangGraph4j 支持几种不同类型的边● 普通边最简单的边类型提供一个节点到另外一个节点的无条件转换。可以通过addEdgesourceNodeName,destinationNodeName来定义普通边。● 条件边下一个节点是根据当前AgentState动态确定的更加灵活。当源节点完成后会执行一个判断函数这个函数接收当前状态并返回下一个要执行的节点名称。相当于实现了if else 分支逻辑。比如智能体决定使用工具就跳转到“执行工具”节点否则跳转到“回复用户”节点。● 入口点可以定义当用户输入到达首先调用哪个节点同样支持条件入口点5、Checkpoints 检查点检查点允许你保存图在任何步骤的状态也就是状态的持久化有利于调试和恢复复杂的工作流。检查点的核心作用主要体现在两个方面● 支持人类检查、中断喝批准工作步骤。在某些场景下人类必须能够在任何时间点查看土地状态并且图必须能够在人类对状态进行任何更新后恢复执行。这种“人在环路”的设计在许多实际应用中都是必须的。● 允许通过线程隔离不同用户的交互并且相同用户可以恢复之前的记忆。这对于构建多用户的AI 应用来说特别重要每个用户都可以由自己的执行历史。根我们之前学习的 Chat Memory对话记忆类似给工作流传入不同的 thread_id 配置即可varconfigRunnableConfig.builder().threadId(a).build();graph.invoke(inputs,config);LangGraph4j默认提供了基于内存的检查点器varsavernewMemorySaver();Demo了解核心特性后我们来运行一个demo1、引入pom!-- LangGraph4j -- dependency groupIdorg.bsc.langgraph4j/groupId artifactIdlanggraph4j-core/artifactId version1.6.0-rc2/version /dependency2、引入代码packagecom.yuliang.aicodemother.langgraph4j.demo;importorg.bsc.langgraph4j.action.NodeAction;importjava.util.Collections;importjava.util.List;importjava.util.Map;// Node that adds a greetingclassGreeterNodeimplementsNodeActionSimpleState{OverridepublicMapString,Objectapply(SimpleStatestate){System.out.println(GreeterNode executing. Current messages: state.messages());returnMap.of(SimpleState.MESSAGES_KEY,Hello from GreeterNode!);}}// Node that adds a responseclassResponderNodeimplementsNodeActionSimpleState{OverridepublicMapString,Objectapply(SimpleStatestate){System.out.println(ResponderNode executing. Current messages: state.messages());ListStringcurrentMessagesstate.messages();if(currentMessages.contains(Hello from GreeterNode!)){returnMap.of(SimpleState.MESSAGES_KEY,Acknowledged greeting!);}returnMap.of(SimpleState.MESSAGES_KEY,No greeting found.);}}packagecom.yuliang.aicodemother.langgraph4j.demo;importorg.bsc.langgraph4j.state.AgentState;importorg.bsc.langgraph4j.state.Channels;importorg.bsc.langgraph4j.state.Channel;importjava.util.*;// Define the state for our graphclassSimpleStateextendsAgentState{publicstaticfinalStringMESSAGES_KEYmessages;// Define the schema for the state.// MESSAGES_KEY will hold a list of strings, and new messages will be appended.publicstaticfinalMapString,Channel?SCHEMAMap.of(MESSAGES_KEY,Channels.appender(ArrayList::new));publicSimpleState(MapString,ObjectinitData){super(initData);}publicListStringmessages(){returnthis.ListStringvalue(messages).orElse(List.of());}}packagecom.yuliang.aicodemother.langgraph4j.demo;importorg.bsc.langgraph4j.GraphRepresentation;importorg.bsc.langgraph4j.StateGraph;importorg.bsc.langgraph4j.GraphStateException;importstaticorg.bsc.langgraph4j.action.AsyncNodeAction.node_async;importstaticorg.bsc.langgraph4j.StateGraph.START;importstaticorg.bsc.langgraph4j.StateGraph.END;importjava.util.List;importjava.util.Map;publicclassSimpleGraphApp{publicstaticvoidmain(String[]args)throwsGraphStateException{// Initialize nodesGreeterNodegreeterNodenewGreeterNode();ResponderNoderesponderNodenewResponderNode();// Define the graph structurevarstateGraphnewStateGraph(SimpleState.SCHEMA,initData-newSimpleState(initData)).addNode(greeter,node_async(greeterNode)).addNode(responder,node_async(responderNode))// Define edges.addEdge(START,greeter)// Start with the greeter node.addEdge(greeter,responder).addEdge(responder,END)// End after the responder node;// Compile the graphvarcompiledGraphstateGraph.compile();GraphRepresentationdemostateGraph.getGraph(GraphRepresentation.Type.MERMAID,demo);System.out.println(demo.toString());// Run the graph// The stream method returns an AsyncGenerator.// For simplicity, well collect results. In a real app, you might process them as they arrive.// Here, the final state after execution is the item of interest.for(varitem:compiledGraph.stream(Map.of(SimpleState.MESSAGES_KEY,Lets, begin!))){System.out.println(item);}}}运行结果得到的图