今天的文章,将讲解利用Spring Boot和LangChina4j实现多工具调用和RAG检索增强的实践。
01 — 系统架构全景图
核心逻辑流程:
- 用户输入问题 → 2. RAG检索相关知识 → 3. 判断是否需要工具调用 → 4. 结合知识库和工具结果 → 5. 生成最终回答
02 — 依赖及程序配置
1.Maven依赖配置(pom.xml)
<!-- Spring Boot Starter --> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-spring-boot-starter</artifactId> <version>1.10.0-beta18</version> </dependency> <!-- OpenAI 兼容 API --> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-open-ai-spring-boot-starter</artifactId> <version>1.10.0-beta18</version> </dependency> <!-- langChain4j自带内存向量存储(用于RAG) --> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-embeddings-all-minilm-l6-v2</artifactId> <version>1.10.0-beta18</version> </dependency> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-core</artifactId> <version>1.10.0</version> </dependency> <!-- 本地 ONNX --> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-embeddings</artifactId> <version>1.10.0-beta18</version> </dependency>配置说明:
- Spring Boot 3.2.6提供Web框架支持
- LangChain4j 1.10.0-beta18实现AI对话核心功能
- 使用自带AllMiniLML6V2作为默认的文本embedding模型
- 可以使用本地下载的embedding模型
2.程序配置(application.yml)
spring: application: name: LangChain4jRAG langchain4j: open-ai: chat-model: api-key: 自己的key # Kimi?API?? base-url: https://api.moonshot.cn/v1 # Kimi API?? model-name: kimi-k2-0905-preview # ???? temperature: 0.7 max-tokens: 2000 timeout: 60s log-requests: true log-responses: true embedding-model: #embedding模型配置 api-key: dfgegggegegeggegeg #假的api-key,真实使用时需替换 model-name: text-embedding-ada-002 timeout: 60s memory: chat-memory-store: type: in-memory chat-memory: max-messages: 20 server: port: 8080 logging: level: dev.langchain4j: DEBUG com.example.langchain4jdev: DEBUG03
—
对话记忆管理配置
聊天记忆配置(ChatMemoryConfig.java)
package com.example.langchain4jrag.config; import dev.langchain4j.memory.chat.ChatMemoryProvider; import dev.langchain4j.memory.chat.MessageWindowChatMemory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class ChatMemoryConfig { @Bean public ChatMemoryProvider chatMemoryProvider() { // 创建基于消息窗口的聊天记忆 // 每个会话独立存储,保留最近10条消息 return memoryId -> MessageWindowChatMemory.builder() .maxMessages(10) // 最大消息数 .id(memoryId) // 会话ID .build(); } }核心功能:
- 会话隔离:每个用户/对话拥有独立的记忆空间
- 窗口限制:只保留最近10条消息,避免内存无限增长
- 自动管理:系统自动处理消息的存储和清理
04 — RAG知识库构建
1.RAG配置(RagConfig.java)
package com.example.langchain4jrag.config; import dev.langchain4j.data.document.Document; import dev.langchain4j.data.document.splitter.DocumentSplitters; import dev.langchain4j.model.embedding.EmbeddingModel; import dev.langchain4j.model.embedding.onnx.allminilml6v2.AllMiniLmL6V2EmbeddingModel; import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever; import dev.langchain4j.store.embedding.EmbeddingStore; import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class RagConfig { // 嵌入模型:将文本转换为向量 @Bean public EmbeddingModel embeddingModel() { System.out.println("✅ 加载 AllMiniLmL6V2 嵌入模型"); return new AllMiniLmL6V2EmbeddingModel(); } // 向量存储:存储和检索文本向量 @Bean public EmbeddingStore<TextSegment> embeddingStore(EmbeddingModel embeddingModel) { EmbeddingStore<TextSegment> embeddingStore = new InMemoryEmbeddingStore<>(); // 构建默认知识库 String defaultKnowledge = """ 智能助手功能说明: 1. 天气查询:可以查询北京、上海等城市的天气 2. 数学计算:可以进行加减乘除运算 3. 时间查询:可以获取当前时间 公司信息: - 名称:AI教育科技公司 - 业务:人工智能培训、技术咨询 - 成立时间:2023年 """; // 分割文档并向量化存储 Document document = Document.from(defaultKnowledge); List<TextSegment> segments = DocumentSplitters.recursive(300, 50).split(document); for (TextSegment segment : segments) { Embedding embedding = embeddingModel.embed(segment).content(); embeddingStore.add(embedding, segment); } System.out.println("✅ 知识库加载完成,共 " + segments.size() + " 个片段"); return embeddingStore; } // 内容检索器:从向量库中查找相关内容 @Bean public EmbeddingStoreContentRetriever contentRetriever( EmbeddingStore<TextSegment> embeddingStore, EmbeddingModel embeddingModel) { return EmbeddingStoreContentRetriever.builder() .embeddingStore(embeddingStore) .embeddingModel(embeddingModel) .maxResults(3) // 最多返回3个相关片段 .minScore(0.5) // 相似度阈值0.5以上 .build(); } }2.RAG工作流程:
- 文档加载→ 2.文本分割→ 3.向量化→ 4.向量存储→ 5.相似度检索→ 6.结果返回
05 — 工具系统
1.天气查询工具(WeatherTools.java)
package com.example.langchain4jrag.tools; import dev.langchain4j.agent.tool.Tool; import org.springframework.stereotype.Component; import java.util.Map; @Component public class WeatherTools { @Tool("查询指定城市的天气情况") public String getWeather(String city) { // 模拟天气数据,实际项目可接入天气API Map<String, String> weatherData = Map.of( "北京", "北京:晴,25°C,湿度45%,北风3级", "上海", "上海:多云,28°C,湿度65%,东南风4级", "广州", "广州:阵雨,30°C,湿度80%,南风2级" ); return weatherData.getOrDefault(city, "暂时没有 " + city + " 的天气数据,请尝试其他城市"); } }2.计算器工具(CalculatorTools.java)
package com.example.langchain4jrag.tools; import dev.langchain4j.agent.tool.Tool; import org.springframework.stereotype.Component; @Component public class CalculatorTools { @Tool("执行四则运算:加(add/+)、减(subtract/-)、乘(multiply/*)、除(divide/)") public double calculate(String operation, double a, double b) { switch (operation.toLowerCase()) { case "add": case "+": return a + b; case "subtract": case "-": return a - b; case "multiply": case "*": return a * b; case "divide": case "/": if (b == 0) throw new IllegalArgumentException("除数不能为零"); return a / b; default: throw new IllegalArgumentException("不支持的操作: " + operation); } } @Tool("计算圆的面积") public double calculateCircleArea(double radius) { return Math.PI * radius * radius; } }3.时间工具(DateTimeTools.java)
package com.example.langchain4jrag.tools; import dev.langchain4j.agent.tool.Tool; import org.springframework.stereotype.Component; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @Component public class DateTimeTools { @Tool("获取当前日期和时间") public String getCurrentDateTime() { return LocalDateTime.now().format( DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss") ); } @Tool("计算两个日期之间的天数差,日期格式:yyyy-MM-dd") public int calculateDaysBetween(String startDate, String endDate) { try { java.time.LocalDate start = java.time.LocalDate.parse(startDate); java.time.LocalDate end = java.time.LocalDate.parse(endDate); long days = java.time.temporal.ChronoUnit.DAYS.between(start, end); return Math.abs((int) days); } catch (Exception e) { return -1; // 表示计算失败 } } }工具系统特点:
- 注解驱动:使用@Tool注解声明工具函数
- 自动注册:Spring自动扫描并注册工具
- 类型安全:强类型参数和返回值
- 错误处理:内置异常处理和默认值
06 — 服务层
助手接口定义(Assistant.java)
package com.example.langchain4jrag.service; import dev.langchain4j.service.MemoryId; import dev.langchain4j.service.SystemMessage; import dev.langchain4j.service.UserMessage; import dev.langchain4j.service.spring.AiService; @AiService public interface Assistant { @SystemMessage(""" 你是一个智能助手,具备以下功能: 1. 使用天气工具查询城市天气 2. 使用计算器工具进行数学计算 3. 使用时间工具获取时间和计算日期 如果用户问题涉及上述功能,请使用相应工具。 其他问题请基于你的知识库和通用知识回答。 回答时请简洁明了,一次回答一个问题。 """) String chat(@MemoryId String sessionId, @UserMessage String message); }注解说明:
@AiService:声明这是AI服务接口@SystemMessage:系统提示词,指导AI行为@MemoryId:标识会话ID,用于记忆管理@UserMessage:用户输入的消息
07 — REST API控制器
控制器实现(AssistantController.java)
package com.example.langchain4jrag.controller; import com.example.langchain4jrag.service.Assistant; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.UUID; @RestController @RequestMapping("/api/assistant") public class AssistantController { @Autowired private Assistant assistant; // 现有会话聊天 @GetMapping("/chat") public String chat(@RequestParam String message, @RequestParam(defaultValue = "default") String sessionId) { return assistant.chat(sessionId, message); } // 创建新会话 @PostMapping("/chat/new") public String startNewChat(@RequestBody String message) { String newSessionId = UUID.randomUUID().toString(); String response = assistant.chat(newSessionId, message); return String.format(""" 新会话ID: %s 助手回答: %s """, newSessionId, response); } // 批量处理消息 @PostMapping("/chat/batch") public List<String> batchChat(@RequestBody List<String> messages, @RequestParam String sessionId) { List<String> responses = new ArrayList<>(); for (String message : messages) { responses.add(assistant.chat(sessionId, message)); } return responses; } }API端点:
GET /api/assistant/chat- 现有会话聊天POST /api/assistant/chat/new- 创建新会话POST /api/assistant/chat/batch- 批量处理消息
08 — 知识库
09 — 测试
在浏览器中输入:http://localhost:8080/chat?message=你是谁?
系统会去知识库检索,然后回答:
我是大模型应用开发,软件工程大三,爱好踢足球
- 天气
3.http://localhost:8080/chat?message=刚才我们都聊了什么?
我们刚才的对话记录: 1. 你问我是谁,我自我介绍是“大模型应用开发,软件工程大三,爱好踢足球”。 2. 你让我算 12+15,我给出结果 27。 3. 你又问“我是谁”,我重复了同样的自我介绍。
那么,如何系统的去学习大模型LLM?
作为一名深耕行业的资深大模型算法工程师,我经常会收到一些评论和私信,我是小白,学习大模型该从哪里入手呢?我自学没有方向怎么办?这个地方我不会啊。如果你也有类似的经历,一定要继续看下去!这些问题啊,也不是三言两语啊就能讲明白的。
所以我综合了大模型的所有知识点,给大家带来一套全网最全最细的大模型零基础教程。在做这套教程之前呢,我就曾放空大脑,以一个大模型小白的角度去重新解析它,采用基础知识和实战项目相结合的教学方式,历时3个月,终于完成了这样的课程,让你真正体会到什么是每一秒都在疯狂输出知识点。
由于篇幅有限,⚡️ 朋友们如果有需要全套 《2025全新制作的大模型全套资料》,扫码获取~
👉大模型学习指南+路线汇总👈
我们这套大模型资料呢,会从基础篇、进阶篇和项目实战篇等三大方面来讲解。
👉①.基础篇👈
基础篇里面包括了Python快速入门、AI开发环境搭建及提示词工程,带你学习大模型核心原理、prompt使用技巧、Transformer架构和预训练、SFT、RLHF等一些基础概念,用最易懂的方式带你入门大模型。
👉②.进阶篇👈
接下来是进阶篇,你将掌握RAG、Agent、Langchain、大模型微调和私有化部署,学习如何构建外挂知识库并和自己的企业相结合,学习如何使用langchain框架提高开发效率和代码质量、学习如何选择合适的基座模型并进行数据集的收集预处理以及具体的模型微调等等。
👉③.实战篇👈
实战篇会手把手带着大家练习企业级的落地项目(已脱敏),比如RAG医疗问答系统、Agent智能电商客服系统、数字人项目实战、教育行业智能助教等等,从而帮助大家更好的应对大模型时代的挑战。
👉④.福利篇👈
最后呢,会给大家一个小福利,课程视频中的所有素材,有搭建AI开发环境资料包,还有学习计划表,几十上百G素材、电子书和课件等等,只要你能想到的素材,我这里几乎都有。我已经全部上传到CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】
相信我,这套大模型系统教程将会是全网最齐全 最易懂的小白专用课!!