LangGraph4j 学习系列(3)-循环工作流

上节继续,本节将演示条件工作流如何用langgraph4j实现。

image

注:循环工作流可以看成 条件工作流的一个变种。node1 -> node2 -> node1 这样就形成了1个死循环(loop),为了能跳出死循环,用条件边来判定跳出时机。

 

一、定义节点
public class Node1Action implements NodeAction<AgentState> {
    @Override
    public Map<String, Object> apply(AgentState state) throws Exception {
        System.out.println("current Node: node-1");
        return Map.of("myData", "node1-my-value",
                "node1Key", "node1-value");
    }
}

  

public class Node2Action implements NodeAction<AgentState> {
    @Override
    public Map<String, Object> apply(AgentState state) throws Exception {
        System.out.println("current Node: node-2");
        return Map.of("myData", "node2-my-value",
                "node2Key", "node2-value");
    }
}

  

二、完整示例

public class LoopGraphApplication {

    public static void main(String[] args) throws GraphStateException {
        StateGraph<AgentState> sequenceGraph = getLoopGraph();
        System.out.println(sequenceGraph.getGraph(GraphRepresentation.Type.MERMAID, "loop Graph", true).content());
        sequenceGraph.compile().invoke(Map.of("loopCount", 0L)).ifPresent(c -> {
            System.out.println(c.data());
        });
    }

    private static final int MAX_LOOP_ITERATIONS = 3;

    public static StateGraph<AgentState> getLoopGraph() throws GraphStateException {
        return new StateGraph<>(AgentState::new)
                .addNode("node-1", node_async(new Node1Action()))
                .addNode("node-2", node_async(new Node2Action()))
                .addEdge(GraphDefinition.START, "node-1")
                .addEdge("node-2", "node-1")
                //循环的跳出条件比较简单,3次后退出,这里就不单独定义EdgeAction类了,用lambda表达式
                .addConditionalEdges("node-1", state -> {
                    long count = getLoopCount(state);
                    System.out.println("loop Count: " + count);
                    if (count >= MAX_LOOP_ITERATIONS) {
                        return CompletableFuture.completedFuture("exit");
                    }
                    return CompletableFuture.completedFuture("continue");
                }, Map.of(
                        "exit", GraphDefinition.END,
                        "continue", "node-2"));
    }

    private static long getLoopCount(AgentState state) {
        Optional<Object> loopCount = state.value("loopCount");
        if (loopCount.isEmpty()) {
            return 0L;
        }
        Object v = loopCount.get();
        if (v instanceof Number n) {
            return n.longValue();
        }
        return Long.parseLong(v.toString());
    }


}

  

三、运行结果

current Node: node-1
loop Count: 0
current Node: node-2
current Node: node-1
loop Count: 1
current Node: node-2
current Node: node-1
loop Count: 2
current Node: node-2
current Node: node-1
loop Count: 3
{node1Key=node1-value, loopCount=3, node2Key=node2-value, myData=node1-my-value}

  

posted @ 2026-03-01 12:57  菩提树下的杨过  阅读(32)  评论(0)    收藏  举报