当Python生态中的LangChain、LangGraph如火如荼时,Java开发者是否只能望洋兴叹?答案是否定的!LangGraph4j —— 这个专为Java打造的AI智能体编排框架,正在悄然改变Java AI开发的格局。

本文将带你从零开始,深入理解LangGraph4j的核心原理,掌握多智能体系统的设计与实现,并通过大量实战案例,让你快速成为Java AI智能体开发高手!


一、为什么Java开发者需要LangGraph4j?

1.1 AI智能体开发的痛点

在传统的AI应用开发中,Java开发者面临着诸多挑战:

❌ 状态管理混乱:多轮对话、上下文传递、中间结果保存,这些都需要手动维护,代码复杂且容易出错。

❌ 流程编排困难:当需要多个AI模型协作、条件分支判断、循环重试时,代码嵌套严重,难以维护。

❌ 调试困难:AI推理过程像黑盒,出现问题难以定位,无法查看中间状态。

❌ 缺乏可视化:无法直观地看到智能体的工作流程,团队协作困难。

1.2 LangGraph4j的诞生

LangGraph4j 是受到Python版LangGraph启发,专门为Java生态设计的库,用于构建有状态的、多智能体的LLM应用

它与 LangChain4jSpring AI 无缝集成,为Java开发者提供了一套完整的AI智能体开发解决方案。

核心优势:

状态图模型:用图的方式描述智能体的工作流程,清晰直观
多智能体协作:支持多个智能体之间的任务传递和协作
可视化调试:内置Studio工具,可实时查看和调试智能体执行过程
异步流式支持:充分利用Java的CompletableFuture,支持流式响应
持久化检查点:可随时保存和恢复状态,支持"时间旅行"调试


二、核心概念详解

在深入代码之前,我们先来理解LangGraph4j的核心概念。

2.1 StateGraph(状态图)

StateGraph 是LangGraph4j的核心,它定义了整个智能体系统的结构。

一个StateGraph由以下元素组成:

  • Nodes(节点):执行具体任务的单元,如调用LLM、执行工具等
  • Edges(边):定义节点之间的执行流程
  • State(状态):在节点之间传递和共享的数据

2.2 AgentState(智能体状态)

AgentState 是图的状态容器,本质上是一个 Map<String, Object>,但它有更强大的功能:

class ConversationStateextendsAgentState {    publicstaticfinalStringMESSAGES_KEY="messages";    publicstaticfinalStringSTEP_COUNT_KEY="step_count";        publicstaticfinal Map<String, Channel<?>> SCHEMA = Map.of(        MESSAGES_KEY, Channels.appender(ArrayList::new),        STEP_COUNT_KEY, Channels.base(() -> 0)    );        publicConversationState(Map<String, Object> initData) {        super(initData);    }        public List<String> messages() {        returnthis.<List<String>>value(MESSAGES_KEY).orElse(List.of());    }}

关键点:

  • Schema定义:通过Schema定义状态的结构和更新规则
  • Channel.Reducer:定义状态如何被更新(覆盖、追加等)
  • Channel.Appender:常用的类型,将新值追加到列表中

2.3 Nodes(节点)

节点是执行具体逻辑的地方,通常实现 NodeAction<S> 接口:

class GreeterNode implements NodeAction<SimpleState> {    @Override    public Map<String, Object> apply(SimpleState state) {        System.out.println("执行问候节点");        return Map.of(SimpleState.MESSAGES_KEY, "Hello!");    }}

节点的作用:

  1. 接收当前状态
  2. 执行计算(调用LLM、执行工具、业务逻辑)
  3. 返回状态更新

2.4 Edges(边)

定义了节点之间的执行流程,分为两种:

1. 普通边(Normal Edge):无条件跳转

.addEdge("nodeA", "nodeB")  // nodeA执行完后总是跳转到nodeB

2. 条件边(Conditional Edge):根据状态动态决定下一个节点

class RoutingEdgeimplementsEdgeAction<ConversationState> {    @Override    public String apply(ConversationState state) {        if (state.needsTool()) {            return"tool_executor";        } else {            return"response_generator";        }    }}.addConditionalEdges("analyzer", newRoutingEdge(),     Map.of("tool_executor", "tool_executor",           "response_generator", "response_generator"))

2.5 编译与执行

定义好图后,需要编译才能执行:

CompiledGraph<ConversationState> compiledGraph = stateGraph.compile();

编译后的图是不可变的,经过结构验证(检查孤立节点等)。

执行方式有两种:

1. invoke():等待执行完成,返回最终状态

Optional<ConversationState> finalState = compiledGraph.invoke(initialState);

2. stream():流式获取每个节点执行后的状态

for (var state : compiledGraph.stream(initialState)) {    System.out.println("当前状态:" + state);}

三、快速开始:5分钟打造你的第一个智能体

3.1 环境准备

要求: Java 17+

Maven依赖:

<properties>    <langgraph4j.version>1.8.4</langgraph4j.version></properties><dependencies>    <!-- 核心库 -->    <dependency>        <groupId>org.bsc.langgraph4j</groupId>        <artifactId>langgraph4j-core</artifactId>        <version>${langgraph4j.version}</version>    </dependency>        <!-- 如果使用LangChain4j -->    <dependency>        <groupId>org.bsc.langgraph4j</groupId>        <artifactId>langgraph4j-langchain4j</artifactId>        <version>${langgraph4j.version}</version>    </dependency>        <!-- 如果使用Spring AI -->    <dependency>        <groupId>org.bsc.langgraph4j</groupId>        <artifactId>langgraph4j-spring-ai</artifactId>        <version>${langgraph4j.version}</version>    </dependency></dependencies>

3.2 实战案例1:简单的线性工作流

让我们创建一个简单的三节点工作流:问候 -> 处理 -> 响应

步骤1:定义状态

class ConversationStateextendsAgentState {    publicstaticfinalStringMESSAGES_KEY="messages";    publicstaticfinalStringSTEP_COUNT_KEY="step_count";        publicstaticfinal Map<String, Channel<?>> SCHEMA = Map.of(        MESSAGES_KEY, Channels.appender(ArrayList::new),        STEP_COUNT_KEY, Channels.base(() -> 0)    );        publicConversationState(Map<String, Object> initData) {        super(initData);    }        public List<String> messages() {        returnthis.<List<String>>value(MESSAGES_KEY).orElse(List.of());    }        publicintstepCount() {        returnthis.<Integer>value(STEP_COUNT_KEY).orElse(0);    }}

步骤2:定义节点

// 问候节点classGreeterNodeimplementsNodeAction<ConversationState> {    @Override    public Map<String, Object> apply(ConversationState state) {        System.out.println("👋 问候节点执行");        return Map.of(            MESSAGES_KEY, "Hi, this is greeter.",            STEP_COUNT_KEY, state.stepCount() + 1        );    }}// 处理节点classProcessorNodeimplementsNodeAction<ConversationState> {    @Override    public Map<String, Object> apply(ConversationState state) {        System.out.println("⚙️ 处理节点执行");        return Map.of(            MESSAGES_KEY, "I am processor, I've processed your request.",            STEP_COUNT_KEY, state.stepCount() + 1        );    }}// 响应节点classResponderNodeimplementsNodeAction<ConversationState> {    @Override    public Map<String, Object> apply(ConversationState state) {        System.out.println("💬 响应节点执行");        return Map.of(            MESSAGES_KEY, "This responder. I acknowledged greeting!",            STEP_COUNT_KEY, state.stepCount() + 1        );    }}

步骤3:构建并执行图

public classSimpleLinearGraphExample {    publicstaticvoidmain(String[] args)throws GraphStateException {        // 创建节点        GreeterNodegreeter=newGreeterNode();        ProcessorNodeprocessor=newProcessorNode();        ResponderNoderesponder=newResponderNode();                // 构建图        StateGraph<ConversationState> stateGraph = newStateGraph<>(            ConversationState.SCHEMA,             ConversationState::new        )        .addNode("greeter", node_async(greeter))        .addNode("processor", node_async(processor))        .addNode("responder", node_async(responder))        // 定义边        .addEdge(START, "greeter")        .addEdge("greeter", "processor")        .addEdge("processor", "responder")        .addEdge("responder", END);                // 编译图        CompiledGraph<ConversationState> compiledGraph = stateGraph.compile();                // 初始状态        Map<String, Object> initialState = Map.of(            MESSAGES_KEY, "User Message: Hi, there!"        );                // 执行        compiledGraph.invoke(initialState)            .ifPresent(finalState -> {                System.out.println("✅ 最终状态: " + finalState);                System.out.println("📝 消息列表: " + finalState.messages());                System.out.println("🔢 步骤数: " + finalState.stepCount());            });    }}

执行结果:

👋 问候节点执行⚙️ 处理节点执行💬 响应节点执行✅ 最终状态: {step_count=3, messages=[User Message: Hi, there!,     Hi, this is greeter.,     I am processor, I've processed your request.,     This responder. I acknowledged greeting!]}📝 消息列表: [User Message: Hi, there!, Hi, this is greeter.,     I am processor, I've processed your request.,     This responder. I acknowledged greeting!]🔢 步骤数: 3

3.3 实战案例2:条件路由智能工作流

现在让我们创建一个更复杂的例子:智能路由系统,根据用户意图决定执行路径。

场景:

  • • 用户询问天气 → 调用天气工具
  • • 用户要求计算 → 调用计算工具
  • • 普通聊天 → 直接回复

完整代码:

// 扩展状态,增加意图判断字段classConversationStateextendsAgentState {    publicstaticfinalStringMESSAGES_KEY="messages";    publicstaticfinalStringUSER_INTENT_KEY="user_intent";    publicstaticfinalStringNEEDS_TOOL_KEY="needs_tool";    publicstaticfinalStringTOOL_RESULT_KEY="tool_result";        publicstaticfinal Map<String, Channel<?>> SCHEMA = Map.of(        MESSAGES_KEY, Channels.appender(ArrayList::new),        USER_INTENT_KEY, Channels.base(() -> ""),        NEEDS_TOOL_KEY, Channels.base(() -> false),        TOOL_RESULT_KEY, Channels.base(() -> "")    );        // ... getter方法省略}// 意图分析节点classIntentAnalyzerimplementsNodeAction<ConversationState> {    @Override    public Map<String, Object> apply(ConversationState state) {        List<String> messages = state.messages();        StringlastMessage= messages.get(messages.size() - 1).toLowerCase();                String intent;        booleanneedsTool=false;                if (lastMessage.contains("weather")) {            intent = "weather_query";            needsTool = true;        } elseif (lastMessage.contains("calculate") || lastMessage.contains("math")) {            intent = "calculation";            needsTool = true;        } else {            intent = "general_chat";        }                System.out.println("🎯 意图分析: " + intent + ", 需要工具: " + needsTool);                return Map.of(            USER_INTENT_KEY, intent,            NEEDS_TOOL_KEY, needsTool,            MESSAGES_KEY, "Intent analyzed: " + intent        );    }}// 工具执行节点classToolExecutorimplementsNodeAction<ConversationState> {    @Override    public Map<String, Object> apply(ConversationState state) {        String result;        switch (state.userIntent()) {            case"weather_query":                result = "🌤️ 当前天气: 20°C, 晴朗少云";                break;            case"calculation":                result = "🧮 计算结果: 625 (生命、宇宙以及任何事情的终极答案)";                break;            default:                result = "无需工具";        }                System.out.println("🔧 工具执行结果: " + result);                return Map.of(            TOOL_RESULT_KEY, result,            MESSAGES_KEY, "Tool executed: " + result        );    }}// 响应生成节点classResponseGeneratorimplementsNodeAction<ConversationState> {    @Override    public Map<String, Object> apply(ConversationState state) {        String response;        if (state.needsTool()) {            response = "✅ 基于工具执行结果: " + state.toolResult() +                       "\n还有什么可以帮助您的吗?";        } else {            response = "💬 您好!我能为您提供什么帮助?";        }                return Map.of(MESSAGES_KEY, response);    }}// 条件路由逻辑classRoutingEdgeimplementsEdgeAction<ConversationState> {    @Override    public String apply(ConversationState state) {        if (state.needsTool()) {            return"tool_executor";        } else {            return"response_generator";        }    }}// 主程序publicclassConditionalRoutingExample {    publicstaticvoidmain(String[] args)throws GraphStateException {        // 创建节点和路由        IntentAnalyzerintentAnalyzer=newIntentAnalyzer();        ToolExecutortoolExecutor=newToolExecutor();        ResponseGeneratorresponseGenerator=newResponseGenerator();        RoutingEdgeroutingEdge=newRoutingEdge();                // 构建图        StateGraph<ConversationState> stateGraph = newStateGraph<>(            ConversationState.SCHEMA, ConversationState::new        )        .addNode("intent_analyzer", node_async(intentAnalyzer))        .addNode("tool_executor", node_async(toolExecutor))        .addNode("response_generator", node_async(responseGenerator))                .addEdge(START, "intent_analyzer")        // 条件边:根据意图分析结果决定路由        .addConditionalEdges("intent_analyzer", edge_async(routingEdge),            Map.of("tool_executor", "tool_executor",                   "response_generator", "response_generator"))        .addEdge("tool_executor", "response_generator")        .addEdge("response_generator", END);                CompiledGraph<ConversationState> graph = stateGraph.compile();                // 测试不同场景        String[] testMessages = {            "How's the weather today?",            "Can you calculate 25 * 25?",            "Hi, I just want to chat!"        };                for (String msg : testMessages) {            System.out.println("\n========== 测试: " + msg + " ==========");            Map<String, Object> initialState = Map.of(MESSAGES_KEY, msg);            graph.invoke(initialState)                .ifPresent(state ->                     System.out.println("最终消息: " + state.messages())                );        }    }}

执行结果:

========== 测试: How's the weather today? ==========🎯 意图分析: weather_query, 需要工具: true🔧 工具执行结果: 🌤️ 当前天气: 20°C, 晴朗少云最终消息: [..., Intent analyzed: weather_query,           Tool executed: 🌤️ 当前天气: 20°C, 晴朗少云,          ✅ 基于工具执行结果: 🌤️ 当前天气: 20°C, 晴朗少云          还有什么可以帮助您的吗?]========== 测试: Can you calculate 25 * 25? ==========🎯 意图分析: calculation, 需要工具: true🔧 工具执行结果: 🧮 计算结果: 625最终消息: [..., ✅ 基于工具执行结果: 🧮 计算结果: 625 ...]========== 测试: Hi, I just want to chat! ==========🎯 意图分析: general_chat, 需要工具: false最终消息: [..., 💬 您好!我能为您提供什么帮助?]

四、多智能体架构:Agent Handoff实战

4.1 什么是多智能体架构?

多智能体系统由多个 specialized(专业化)的智能体组成,每个智能体负责特定的任务,通过协作完成复杂的目标。

核心概念:Agent Handoff(智能体交接)

Agent Handoff 是指控制权和上下文从一个智能体转移到另一个智能体的机制。这种模式在以下场景非常有用:

  • 任务需要多种专业技能:如电商场景,需要搜索专家、支付专家、物流专家协作
  • 提高执行效率:不同智能体专注于不同领域,提高整体效率
  • 模块化设计:每个智能体独立开发、测试、维护

4.2 实战:电商多智能体系统

让我们构建一个电商场景的多智能体系统:

场景描述:

    1. Marketplace Agent(市场代理):负责商品搜索和信息查询
    1. Payment Agent(支付代理):负责处理支付和交易

用户说:“搜索产品’X’并购买它”

架构设计:

完整实现:

// 1. 定义Marketplace AgentpublicclassAgentMarketplaceextendsAbstractAgentExecutor<AgentMarketplace.Builder> {        // 内部工具定义    staticclassTools {        recordProduct(            @JsonPropertyDescription("产品名称") String name,            @JsonPropertyDescription("产品价格")double price,            @JsonPropertyDescription("货币单位") String currency        ) {}                @Tool(description = "在市场中搜索特定产品")        Product searchByProduct(            @ToolParam(description = "产品名称") String product        ) {            // 模拟搜索            returnnewProduct(product, 99.99, "USD");        }    }        // Builder模式构建Agent    publicstaticclassBuilderextendsAbstractAgentExecutor.Builder<Builder> {        public AgentMarketplace build()throws GraphStateException {            this.name("marketplace")                .description("市场代理,提供产品信息查询服务")                .parameterDescription("产品查询信息")                .defaultSystem("""                    你是一个市场代理,负责提供产品信息。                """)                .toolsFromObject(newTools());                        returnnewAgentMarketplace(this);        }    }        publicstatic Builder builder() {        returnnewBuilder();    }        protectedAgentMarketplace(Builder builder)throws GraphStateException {        super(builder);    }}// 2. 定义Payment AgentpublicclassAgentPaymentextendsAbstractAgentExecutor<AgentPayment.Builder> {        staticclassTools {        recordTransaction(            @JsonPropertyDescription("购买的产品") String product,            @JsonPropertyDescription("交易码") String code        ) {}                @Tool(description = "提交支付请求")        Transaction submitPayment(            @ToolParam(description = "产品名") String product,            @ToolParam(description = "价格") double price,            @ToolParam(description = "货币") String currency,            @ToolParam(description = "银行账号") String iban        ) {            // 模拟支付            returnnewTransaction(product, "TXN-" + System.currentTimeMillis());        }                @Tool(description = "获取银行账号信息")        String retrieveIBAN() {            return"DE89370400440532013000";        }    }        publicstaticclassBuilderextendsAbstractAgentExecutor.Builder<Builder> {        public AgentPayment build()throws GraphStateException {            this.name("payment")                .description("支付代理,处理交易和支付")                .parameterDescription("支付相关信息")                .defaultSystem("""                    你是一个支付代理,负责处理支付事务。                """)                .toolsFromObject(newTools());                        returnnewAgentPayment(this);        }    }        publicstatic Builder builder() {        returnnewBuilder();    }        protectedAgentPayment(Builder builder)throws GraphStateException {        super(builder);    }}// 3. 构建Agent Handoff系统publicclassMultiAgentHandoffExample {    publicstaticvoidmain(String[] args)throws GraphStateException {        // 配置LLM模型(使用Ollama本地模型)        varmodel= OllamaChatModel.builder()            .ollamaApi(newOllamaApi("http://localhost:11434"))            .defaultOptions(OllamaOptions.builder()                .model("qwen2.5:7b")                .temperature(0.1)                .build())            .build();                // 创建两个Agent        varagentMarketPlace= AgentMarketplace.builder()            .chatModel(model)            .build();                varagentPayment= AgentPayment.builder()            .chatModel(model)            .build();                // 构建Agent Handoff系统        varhandoffExecutor= AgentHandoff.builder()            .chatModel(model)            .agent(agentMarketPlace)  // 添加市场代理            .agent(agentPayment)      // 添加支付代理            .build()            .compile();                // 测试:搜索并购买产品        Stringinput="搜索产品'iPhone 15'并购买它";                varresult= handoffExecutor.invoke(            Map.of("messages", newUserMessage(input))        );                varresponse= result            .flatMap(MessagesState::lastMessage)            .map(Content::getText)            .orElseThrow();                System.out.println("🎉 最终结果: " + response);    }}

执行流程:

用户输入: "搜索产品'iPhone 15'并购买它"         ↓LLM分析: 需要搜索和购买 → 生成执行计划         ↓Marketplace Agent: 搜索"iPhone 15"         → 返回: Product(name="iPhone 15", price=999.99, currency="USD")         ↓Payment Agent: 获取IBAN → 提交支付         → 返回: Transaction(product="iPhone 15", code="TXN-1234567890")         ↓最终响应: "已成功为您购买iPhone 15,价格$999.99,交易码: TXN-1234567890"

4.3 关键实现原理

为什么Agent Handoff能工作?

关键在于 Function Calling(函数调用) 机制:

  1. LLM生成执行计划:LLM根据用户输入,生成一系列要执行的动作
  2. 动作即Agent:每个动作实际上是由一个专门的Agent执行
  3. 上下文传递:前一个Agent的输出成为后一个Agent的输入

核心代码分析:

// AbstractAgentExecutor 结合了 AgentExecutor 和 FunctionpublicabstractclassAbstractAgentExecutor<B extendsAbstractAgentExecutor.Builder<B>>     extendsAgentExecutorimplementsFunction {        // name: Agent的名称    // description: Agent的能力描述(供LLM理解)    // parameterDescription: 输入参数描述        @Override    public String name() {        returnthis.name;    }        @Override    public String description() {        returnthis.description;    }}// AgentHandoff 将多个Agent作为Tools集成publicclassAgentHandoff {    publicstatic Builder builder() {        returnnewBuilder();    }        publicstaticclassBuilder {        private List<AbstractAgentExecutor> agents = newArrayList<>();                public Builder agent(AbstractAgentExecutor agent) {            this.agents.add(agent);            returnthis;        }                public CompiledGraph compile() {            // 将每个Agent作为Tool添加到主Agent的工具链中            // LLM会自动决定调用哪个Agent            return AgentExecutor.builder()                .chatModel(chatModel)                .tools(agents)  // 关键:Agent作为Tools                .build()                .compile();        }    }}

五、高级特性

5.1 异步与流式支持

LangGraph4j充分利用Java的异步特性,支持非阻塞流式执行。

异步节点:

// 使用node_async包装异步操作.addNode("llm_call", node_async(state -> {    // 模拟耗时的LLM调用    return CompletableFuture.supplyAsync(() -> {        try {            Thread.sleep(3000); // 模拟网络延迟            return Map.of("response", "AI Response");        } catch (InterruptedException e) {            throw new RuntimeException(e);        }    });}))

流式执行:

// 实时获取每个节点的执行结果compiledGraph.stream(initialState)    .forEach(state -> {        System.out.println("节点执行后的状态: " + state);        // 可以实时推送给前端    });

5.2 持久化与时间旅行

Checkpoint(检查点) 功能允许你保存和恢复图的状态。

// 使用MemorySaver(内存存储)varsaver=newMemorySaver();varconfig= RunnableConfig.builder()    .checkpointSaver(saver)    .build();// 执行并保存检查点varresult1= graph.invoke(initialState, config);// 获取检查点IDStringcheckpointId= saver.getLatestCheckpointId();// 时间旅行:恢复到之前的状态varrestoredState= saver.getCheckpoint(checkpointId);// 从检查点继续执行varconfig2= RunnableConfig.builder()    .checkpointSaver(saver)    .parentCheckpointId(checkpointId)    .build();varresult2= graph.invoke(restoredState, config2);

应用场景:

  • 调试:查看中间状态,定位问题
  • 长任务恢复:程序崩溃后从断点继续
  • 人机交互:等待用户输入后继续

5.3 子图(Subgraphs)

复杂系统可以通过子图实现模块化。

子图 Subgraph

子图开始
子节点1
子节点2
子图结束
父图 Parent Graph

开始
子图节点Subgraph Node
结束
// 创建子图StateGraph<SubState> subGraph = new StateGraph<>(...)    .addNode("sub_node1", ...)    .addNode("sub_node2", ...)    .addEdge(START, "sub_node1")    .addEdge("sub_node1", "sub_node2")    .addEdge("sub_node2", END);// 将子图作为节点添加到父图StateGraph<ParentState> parentGraph = new StateGraph<>(...)    .addNode("subgraph_node", subGraph.compile())    .addEdge(START, "subgraph_node")    .addEdge("subgraph_node", END);

5.4 并行执行

// 并行分支执行StateGraph<State> graph = newStateGraph<>(...)    .addNode("branch1", ...)    .addNode("branch2", ...)    .addNode("branch3", ...)    .addNode("join", ...)        // 从start并行启动三个分支    .addEdge(START, "branch1")    .addEdge(START, "branch2")    .addEdge(START, "branch3")        // 三个分支都完成后汇聚到join节点    .addEdge("branch1", "join")    .addEdge("branch2", "join")    .addEdge("branch3", "join")    .addEdge("join", END);

5.5 可视化:Studio与PlantUML

LangGraph4j Studio 是一个强大的Web可视化工具,提供以下功能:

  • • 📊 实时状态查看:监控智能体执行过程
  • • 🔄 时间旅行调试:回溯到任意检查点
  • 消息历史:查看所有交互记录
  • • ⚙️ 配置管理:动态调整参数

集成方式:

// Spring Boot集成@SpringBootApplicationpublicclassMyAgentApp {    publicstaticvoidmain(String[] args) {        // 启动Studio        StudioServerserver=newStudioServer(8080);        server.registerGraph("my-agent", compiledGraph);        server.start();                // 访问 http://localhost:8080/studio    }}

PlantUML可视化:

// 生成PlantUML图String plantUml = graph.toPlantUml();System.out.println(plantUml);// 输出:// @startuml// [*] --> greeter// greeter --> processor// processor --> responder// responder --> [*]// @enduml

六、与Spring AI集成

6.1 集成配置

<dependency>    <groupId>org.springframework.ai</groupId>    <artifactId>spring-ai-openai-spring-boot-starter</artifactId>    <version>1.0.3</version></dependency><dependency>    <groupId>org.bsc.langgraph4j</groupId>    <artifactId>langgraph4j-spring-ai</artifactId>    <version>1.8.4</version></dependency>

6.2 实战:智能客服系统

@ConfigurationpublicclassAgentConfig {        @Bean    public CompiledGraph<AgentState> customerServiceAgent(        ChatModel chatModel    )throws GraphStateException {                // 定义工具        classTools {            @Tool(description = "查询订单状态")            String getOrderStatus(                @ToolParam(description = "订单号") String orderId            ) {                return"订单 " + orderId + " 状态: 已发货";            }                        @Tool(description = "处理退款请求")            String processRefund(                @ToolParam(description = "订单号") String orderId            ) {                return"退款已处理,订单: " + orderId;            }        }                // 构建Agent        varagent= AgentExecutor.builder()            .chatModel(chatModel)            .toolsFromObject(newTools())            .defaultSystem("""                你是客服助手,帮助用户查询订单和处理退款。            """)            .build()            .compile();                return agent;    }        @RestController    @RequestMapping("/api/agent")    publicclassAgentController {                @Autowired        private CompiledGraph<AgentState> agent;                @PostMapping("/chat")        public ResponseEntity<String> chat(@RequestBody String message) {            varresult= agent.invoke(                Map.of("messages", newUserMessage(message))            );                        return result                .flatMap(AgentState::lastMessage)                .map(content -> ResponseEntity.ok(content.getText()))                .orElse(ResponseEntity.notFound().build());        }    }}

七、最佳实践与性能优化

7.1 设计原则

1. 单一职责原则
每个节点/Agent只负责一项特定任务:

// ❌ 不好的设计:一个节点做所有事classMegaNodeimplementsNodeAction<State> {    public Map<String, Object> apply(State state) {        // 分析意图、调用LLM、执行工具、生成响应...    }}// ✅ 好的设计:职责分离classIntentAnalyzerimplementsNodeAction<State> { ... }classLLMCallerimplementsNodeAction<State> { ... }classToolExecutorimplementsNodeAction<State> { ... }classResponseGeneratorimplementsNodeAction<State> { ... }

2. 状态设计要显式

// ✅ 明确定义状态schemaclass MyState extends AgentState {    public static final Map<String, Channel<?>> SCHEMA = Map.of(        "messages", Channels.appender(ArrayList::new),        "step_count", Channels.base(() -> 0),        "user_intent", Channels.base(() -> "")    );}

3. 使用Channels有效传递数据

// Appender:累积消息历史Channels.appender(ArrayList::new)// Base:覆盖旧值Channels.base(() -> defaultValue)// Default:提供默认值Channels.defaultVal(supplier)

7.2 性能优化

1. 异步化LLM调用

// 使用CompletableFuture包装LLM调用.addNode("llm_call", node_async(state ->     CompletableFuture.supplyAsync(() ->         llm.generate(state.getMessages())    )))

2. 并行执行独立任务

// 并行查询多个数据源.parallelBranch("query_db1", "query_db2", "query_db3")    .joinAt("aggregate_results")

3. 合理使用检查点

// 仅在关键节点保存检查点.addNode("critical_step", action)    .metadata(Map.of("interrupt_before", true)) // 执行前暂停

7.3 调试技巧

1. 启用详细日志

Logging.basicConfig(level=Logging.DEBUG);

2. 使用Studio可视化

// 启动Studio服务器StudioServer server = new StudioServer(8080);server.registerGraph("my-graph", compiledGraph);server.start();

3. 打印中间状态

compiledGraph.stream(initialState)    .forEach(state -> {        System.out.println("=== 当前状态 ===");        System.out.println(state);    });

八、实际应用场景

8.1 智能代码审查系统

// 多Agent协作:代码审查// 1. 语法检查Agent// 2. 安全审计Agent  // 3. 性能优化Agent// 4. 代码风格Agent// 5. 汇总报告AgentStateGraph<CodeReviewState> graph = newStateGraph<>(...)    .addNode("syntax_checker", ...)    .addNode("security_auditor", ...)    .addNode("performance_analyzer", ...)    .addNode("style_checker", ...)    .addNode("report_generator", ...)        // 并行执行多个检查    .addEdge(START, "syntax_checker")    .addEdge(START, "security_auditor")    .addEdge(START, "performance_analyzer")    .addEdge(START, "style_checker")        // 所有检查完成后生成报告    .addEdge("syntax_checker", "report_generator")    .addEdge("security_auditor", "report_generator")    .addEdge("performance_analyzer", "report_generator")    .addEdge("style_checker", "report_generator")    .addEdge("report_generator", END);

8.2 数据分析Pipeline


不通过
通过

原始数据
数据清洗
特征工程
模型训练
评估结果
报告生成
分析完成
// 数据分析工作流// 1. 数据清洗// 2. 特征工程// 3. 模型训练// 4. 结果评估// 5. 报告生成graph    .addNode("data_cleaning", ...)    .addNode("feature_engineering", ...)    .addNode("model_training", ...)    .addNode("evaluation", ...)    .addNode("report", ...)        .addEdge(START, "data_cleaning")    .addEdge("data_cleaning", "feature_engineering")    .addEdge("feature_engineering", "model_training")    .addConditionalEdges("model_training", evaluationRouter,        Map.of("retrain", "feature_engineering",               "success", "report"))    .addEdge("report", END);

8.3 智能问答机器人(RAG系统)

// RAG (Retrieval Augmented Generation) 系统// 1. 意图识别// 2. 知识检索// 3. 答案生成// 4. 质量检查graph    .addNode("intent_classifier", ...)    .addNode("knowledge_retriever", ...)    .addNode("answer_generator", ...)    .addNode("quality_checker", ...)        .addEdge(START, "intent_classifier")    .addEdge("intent_classifier", "knowledge_retriever")    .addEdge("knowledge_retriever", "answer_generator")    .addEdge("answer_generator", "quality_checker")    .addConditionalEdges("quality_checker", qualityRouter,        Map.of("regenerate", "answer_generator",               "approve", END))    .addEdge("quality_checker", END);

九、学习资源

9.1 官方资源

  • GitHub仓库:https://github.com/langgraph4j/langgraph4j
  • 官方文档:https://langgraph4j.github.io/langgraph4j/
  • 示例代码:https://github.com/langgraph4j/langgraph4j/tree/main/how-tos

9.2 相关项目推荐

  • research4j:基于LangGraph4j的深度研究助手
  • KUI:基于Spring Boot + LangChain4j + LangGraph4j的多智能体代码助手
  • Dynamo Multi AI Agent:Spring AI + LangGraph4j的多智能体POC

十、总结与展望

10.1 LangGraph4j的核心价值

通过本文的学习,你应该已经理解了LangGraph4j的核心价值:

简化复杂流程:用图的方式描述工作流,代码清晰易维护
支持多智能体协作:Agent Handoff机制让智能体分工明确
强大的调试能力:检查点、可视化、状态追踪
灵活的集成能力:与LangChain4j、Spring AI无缝对接
企业级特性:异步、流式、持久化、并行执行

学AI大模型的正确顺序,千万不要搞错了

🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!

有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!

就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋

在这里插入图片描述

📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇

学习路线:

✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经

以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!

我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

在这里插入图片描述

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐