LangGraph4j开发实战教程(非常详细),Java打造AI智能体从入门到精通,收藏这一篇就够了!
当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应用。
它与 LangChain4j 和 Spring 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!"); }}
节点的作用:
- 接收当前状态
- 执行计算(调用LLM、执行工具、业务逻辑)
- 返回状态更新
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 实战:电商多智能体系统
让我们构建一个电商场景的多智能体系统:
场景描述:
-
- Marketplace Agent(市场代理):负责商品搜索和信息查询
-
- 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(函数调用) 机制:
- LLM生成执行计划:LLM根据用户输入,生成一系列要执行的动作
- 动作即Agent:每个动作实际上是由一个专门的Agent执行
- 上下文传递:前一个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%免费】

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


所有评论(0)