Java AI 应用开发实践:基于 Spring Boot 实现 Chat、Memory、RAG 与 Tool Calling
前言这两年 AI 应用开发非常火越来越多开发者开始尝试把大模型能力接入到自己的业务系统中比如智能客服、知识库问答、企业助手、代码助手、数据分析助手等。不过在实际开发过程中我发现一个比较明显的问题很多 AI 应用框架和示例更偏向 Python 生态而企业级业务系统里Java / Spring Boot 仍然是非常常见的技术栈。对于 Java 开发者来说如果想在现有系统中接入大模型能力通常会遇到这些问题大模型 API 调用方式不统一流式输出需要自己封装多轮对话记忆需要额外维护RAG 知识库问答链路比较长Tool Calling 与业务方法集成不够自然Agent 执行流程缺少统一抽象Spring Boot 项目中接入 AI 能力的工程化成本较高所以我最近基于 Java / Spring Boot 的技术体系整理并实现了一个轻量级 AI 应用开发框架VertexFlow AI Framework。它的目标不是简单封装一个大模型接口而是围绕真实 AI 应用开发场景把 Chat、Memory、RAG、Tool Calling、Agent、Spring Boot Starter 等能力串起来让 Java 开发者可以用更熟悉的方式构建 AI 应用。一、为什么 Java 也需要自己的 AI 应用开发框架现在很多人一提到 AI 应用开发第一反应就是 Python。Python 生态确实非常强比如各种大模型调用框架、RAG 框架、Agent 框架都比较成熟。但是从企业业务系统角度来看Java 仍然有几个非常明显的优势。1. 企业系统大量使用 Java / Spring Boot很多公司的核心业务系统、后台管理系统、订单系统、用户系统、客服系统、权限系统都是 Java / Spring Boot 技术栈。如果 AI 能力最终要接入真实业务系统那么 Java 侧一定需要比较自然的接入方式。比如一个智能客服系统可能需要调用订单服务、用户服务、商品服务、售后服务。如果这些服务本身就是 Java 写的那么直接在 Java 体系中集成大模型能力会比单独拆一个 Python 服务更加自然。2. Java 工程化能力成熟Java 在工程化方面非常成熟比如Spring Boot 自动配置Maven 依赖管理配置文件管理日志体系Bean 生命周期管理微服务生态数据库访问缓存权限认证监控告警这些能力对于 AI 应用落地非常重要。AI 应用并不是只调用一次大模型接口就结束了。真正上线到业务系统中还需要考虑配置管理、异常处理、权限控制、日志追踪、接口安全、服务稳定性等问题。这些正是 Java / Spring Boot 比较擅长的地方。3. AI 应用最终还是要和业务系统结合AI 应用不是单纯的聊天机器人。真实业务里通常需要查询数据库调用内部接口读取知识库识别用户意图调用业务工具维护上下文做权限校验返回结构化结果这些事情本身就是 Java 后端比较擅长的领域。因此我认为 Java 不是不能做 AI 应用而是需要一套更贴合 Java / Spring Boot 开发习惯的 AI 应用开发方式。二、一个 Java AI 应用框架应该具备哪些能力如果从实际业务场景出发一个 Java AI 应用框架至少应该包含以下几个核心模块。1. Chat大模型基础对话能力Chat 是最基础的能力也就是封装大模型的普通对话调用。常见流程是用户输入问题↓构造 Prompt↓调用大模型 API↓解析模型结果↓返回给用户在框架层面Chat 模块需要屏蔽不同模型厂商之间的差异。比如 DeepSeek、通义千问、OpenAI、智谱等模型它们的 API 格式可能不完全一致但对于业务开发者来说最好只面对一个统一的调用接口。示例代码String answer chatClient.call(“请介绍一下 RAG 是什么”);System.out.println(answer);这样业务层只关心“我要问什么”和“模型回答什么”不用每次都关心 HTTP 请求、鉴权、JSON 解析、异常处理等细节。这类统一封装对于业务项目很重要。因为一旦模型厂商发生变化比如从 DeepSeek 切换到通义千问业务代码不应该大面积修改而是尽量通过配置或适配层完成切换。⸻Streaming Chat流式输出能力在 AI 对话类应用中流式输出体验非常重要。如果用户提了一个比较长的问题模型完整生成可能需要几秒甚至十几秒。如果后端等模型全部生成完再返回用户体验会比较差。更好的方式是边生成边返回也就是流式输出。常见场景包括AI 聊天助手智能客服知识库问答代码生成长文本总结流式输出在后端通常需要处理SSEWebSocket模型返回的增量内容前端逐字展示异常中断处理会话状态维护框架层可以把这些复杂度封装起来让业务侧只关心模型生成的内容。示例伪代码streamingChatModel.stream(“请解释一下 Spring Boot 自动配置原理”, chunk - {System.out.print(chunk);});这样可以让 Java 后端更容易构建类似 ChatGPT 的交互体验。如果是 Web 项目也可以结合 SSE 进行输出GetMapping(value “/stream”, produces MediaType.TEXT_EVENT_STREAM_VALUE)public SseEmitter stream(RequestParam String message) {SseEmitter emitter new SseEmitter();streamingChatModel.stream(message, chunk - {try {emitter.send(chunk);} catch (IOException e) {emitter.completeWithError(e);}});return emitter;}当然真实项目中还需要考虑超时、异常、连接关闭、前端重连等问题。⸻Memory多轮对话记忆能力很多 AI 应用都不是单轮问答而是多轮对话。比如用户帮我推荐一个 Java AI 项目架构AI可以使用 Spring Boot RAG Tool Calling…用户那这个项目怎么接入知识库AI这里的“这个项目”需要理解为上一轮提到的 Java AI 项目第二个问题里的“这个项目”依赖上一轮上下文。如果没有 Memory模型就无法理解用户真正指的是什么。因此Memory 模块需要维护会话上下文例如sessionIduserIdmessage historysystem promptuser messageassistant message历史消息裁剪策略简单来说就是让模型“记住当前对话中发生过什么”。示例设计chatMemory.addUserMessage(sessionId, “什么是 RAG”);chatMemory.addAssistantMessage(sessionId, “RAG 是检索增强生成…”);然后在下一次调用模型时把必要的上下文重新组装到 Prompt 中。示例List history chatMemory.getMessages(sessionId);String answer chatClient.call(history, “那它适合用在哪些场景”);chatMemory.addUserMessage(sessionId, “那它适合用在哪些场景”);chatMemory.addAssistantMessage(sessionId, answer);Memory 的关键不是无限保存所有历史而是合理控制上下文长度避免 Token 过长同时保留对回答最有价值的信息。常见策略包括保留最近 N 轮对话对历史对话进行摘要根据当前问题检索相关历史区分短期记忆和长期记忆对不同用户、不同会话进行隔离如果 Memory 设计不好很容易出现两个问题第一历史上下文太短模型无法理解多轮对话。第二历史上下文太长导致 Token 成本变高甚至超过模型限制。所以 Memory 是 AI 应用工程化中非常重要的一环。⸻RAG知识库增强生成能力RAG 是当前 AI 应用开发中非常重要的能力。它的全称是 Retrieval-Augmented Generation也就是检索增强生成。为什么需要 RAG因为大模型本身不一定知道你的私有知识比如公司内部文档产品说明书业务规则订单政策用户手册项目接口文档数据库说明代码规范如果直接问大模型它可能不知道甚至会编造答案。RAG 的核心思路是用户提问↓从知识库中检索相关内容↓把检索到的内容拼接进 Prompt↓让大模型基于资料回答一个基础 RAG 流程通常包括文档加载↓文本切分↓向量化↓存入向量库↓用户提问↓问题向量化↓相似度检索↓构造增强 Prompt↓模型生成答案在 Java 框架中可以把这些步骤拆成几个组件DocumentLoader 文档加载TextSplitter 文本切分EmbeddingModel 向量模型VectorStore 向量存储Retriever 检索器PromptTemplate 提示词模板ChatModel 大模型生成示例伪代码List documents documentLoader.load(“docs/manual.pdf”);List chunks textSplitter.split(documents);vectorStore.add(chunks);List relatedChunks retriever.retrieve(“如何配置 API Key”);String answer ragClient.ask(“如何配置 API Key”, relatedChunks);RAG 的价值在于它可以让 AI 应用基于真实资料回答问题而不是完全依赖模型自己的记忆。不过 RAG 也不是简单把文档塞给模型就可以了。实际开发中需要考虑文档格式如何解析文本切分粒度如何设置chunk 太大还是太小向量模型怎么选择检索结果如何排序是否需要重排序Prompt 如何设计如何让模型减少幻觉如何返回引用来源如何更新知识库这些都是 RAG 工程化落地时需要重点处理的问题。⸻Tool Calling让大模型调用业务工具Tool Calling 是 AI 应用从“聊天机器人”走向“业务助手”的关键能力。普通 Chat 只能回答问题而 Tool Calling 可以让模型根据用户意图调用具体工具。比如用户问帮我查询一下订单 10086 的物流状态这时候模型不能只回答“我无法查询物流”而是应该识别出用户想查询订单然后调用后端的订单查询方法。比如AiTool(name “queryOrderStatus”, description “查询订单物流状态”)public OrderStatus queryOrderStatus(String orderNo) {return orderService.queryStatus(orderNo);}调用流程大概是用户输入↓模型识别是否需要调用工具↓生成工具名称和参数↓后端执行对应 Java 方法↓拿到工具执行结果↓再次交给模型生成自然语言回答Tool Calling 的关键点包括工具注册工具描述参数定义参数解析方法调用结果返回异常处理权限控制在 Java / Spring Boot 体系中Tool Calling 可以和 Bean、注解、反射、业务 Service 结合起来让大模型自然调用后端已有能力。比如可以设计成这样Componentpublic class OrderTools {private final OrderService orderService;public OrderTools(OrderService orderService) {this.orderService orderService;}AiTool(name “queryOrderStatus”, description “根据订单号查询订单状态”)public String queryOrderStatus(String orderNo) {return orderService.queryStatus(orderNo);}}这样业务开发者只需要把允许 AI 调用的方法标记出来框架负责完成工具注册、参数解析和调用执行。当然Tool Calling 也需要注意安全问题。不是所有接口都应该暴露给 AI 调用。比较合理的做法是只注册允许 AI 调用的方法为工具设置清晰描述和参数约束对高风险操作增加人工确认记录工具调用日志对异常结果做兜底处理对用户权限进行校验Tool Calling 做好了AI 应用就不再只是一个问答机器人而是可以真正连接业务系统帮助用户完成具体任务。⸻Agent任务规划与执行流程Agent 可以理解为更进一步的智能体能力。普通 Chat 是问一句答一句。Tool Calling 是模型可以调用工具。Agent 则更像是模型可以围绕一个目标进行多步骤规划和执行。比如用户说帮我分析这个项目的 README并生成一份优化建议Agent 可能需要执行读取 README↓分析项目定位↓检查文档结构↓总结问题↓生成优化建议一个简单 Agent 通常包含任务输入任务规划工具选择工具执行中间结果最终回答在框架设计上可以先实现 Simple Agent不必一开始就做特别复杂的多 Agent 协作。先让它能完成基本的“理解任务 → 调用工具 → 生成结果”就已经能覆盖很多业务场景。示例伪代码AgentResult result simpleAgent.run(“分析项目 README并生成优化建议”);System.out.println(result.getFinalAnswer());Agent 的难点在于控制执行过程。如果完全放任模型自己规划可能会出现执行步骤不可控、工具调用错误、成本过高等问题。所以在企业应用中Agent 更适合做成可控流程例如限制最大执行轮数限制可调用工具范围记录每一步执行日志对关键操作进行人工确认对失败步骤进行兜底处理这样 Agent 才更容易落地到真实业务系统中。⸻三、VertexFlow AI Framework 的设计思路基于上面的思考我整理了一个面向 Java / Spring Boot 开发者的轻量级 AI 应用开发框架VertexFlow AI Framework。它的定位是让 Java 开发者用熟悉的 Spring Boot 方式快速构建 AI 应用。目前框架主要包含以下能力Chat 大模型调用Streaming 流式对话Memory 多轮会话记忆Prompt Template 提示词模板RAG 知识库问答Document Loader 文档加载Text Splitter 文本切分Tool Calling 工具调用Simple Agent 智能体Spring Boot Starter 自动配置整体目标不是做一个“大而全”的复杂框架而是先把 Java AI 应用开发中最常用的能力抽象出来降低 Java 开发者接入 AI 的成本。⸻四、框架整体架构可以把 VertexFlow AI Framework 理解成几层应用层↓AI Client 层↓能力编排层↓模型适配层↓基础设施层应用层应用层就是业务系统例如AI 助手智能客服知识库问答企业内部助手Agent 工作流代码助手这些应用不应该直接关心底层模型 API 的细节。业务开发者最好只需要调用一个简单的方法就可以完成 AI 能力接入。AI Client 层这一层提供统一入口例如chatClient.call(message);ragClient.ask(question);agent.run(task);让业务开发者可以用简单 API 调用 AI 能力。能力编排层这一层负责组合不同模块例如ChatMemoryPromptRAGTool CallingAgent比如 RAG 问答不是单独调用模型而是要先检索知识再构造 Prompt再调用模型生成答案。Tool Calling 也不是单独调用业务方法而是要先让模型识别工具调用意图再执行工具再把工具结果交给模型生成最终回答。模型适配层这一层负责适配不同大模型厂商。不同模型 API 的请求格式、响应格式、鉴权方式可能不同但框架应该尽量统一上层接口。这样业务代码不用关心底层模型是谁只需要关注自己的业务逻辑。基础设施层这一层包括HTTP ClientJSON 序列化配置管理日志异常处理向量存储文件读取Spring Boot 自动配置这些能力决定了框架是否真正适合工程化落地。⸻五、Spring Boot Starter 的意义对于 Java 开发者来说Spring Boot Starter 是非常熟悉的接入方式。理想情况下开发者只需要三步就可以使用 AI 能力。引入依赖io.github.guoqingniu vertexflow-ai-spring-boot-starter 0.4.x配置模型参数vertexflow:ai:model:provider: deepseekapi-key: ${DEEPSEEK_API_KEY}注入并使用RestControllerRequestMapping(“/ai”)public class AiController {private final ChatClient chatClient;public AiController(ChatClient chatClient) {this.chatClient chatClient;}GetMapping(“/chat”)public String chat(String message) {return chatClient.call(message);}}这种方式对于 Spring Boot 开发者来说非常自然。不需要每个项目都重复写模型调用、配置读取、Bean 注册、异常处理等基础代码。Spring Boot Starter 的意义在于降低接入成本。如果一个框架需要大量手动配置开发者很可能还没跑通 Demo 就放弃了。而 Starter 可以让开发者更快进入业务开发阶段。⸻六、一个简单的 Chat 示例下面是一个最基础的 AI 对话接口示例。RestControllerRequestMapping(“/chat”)public class ChatController {private final ChatClient chatClient;public ChatController(ChatClient chatClient) {this.chatClient chatClient;}GetMappingpublic String chat(RequestParam String message) {return chatClient.call(message);}}调用接口curl “http://localhost:8080/chat?message什么是RAG”返回结果示例RAG 是 Retrieval-Augmented Generation 的缩写中文通常叫检索增强生成。它通过先从知识库中检索相关资料再让大模型基于这些资料进行回答从而提升回答的准确性和可控性。这个例子虽然简单但它体现了框架最基础的目标让 Java 开发者不用重复关心底层模型 API而是专注于业务本身。⸻七、一个简单的 Memory 示例多轮对话可以通过 sessionId 来区分不同会话。示例PostMapping(“/chat”)public String chat(RequestParam String sessionId,RequestParam String message) {chatMemory.addUserMessage(sessionId, message);List history chatMemory.getMessages(sessionId);String answer chatClient.call(history);chatMemory.addAssistantMessage(sessionId, answer);return answer;}这样每个 session 都可以拥有自己的上下文。用户连续提问时模型可以结合历史消息理解当前问题。例如用户什么是 RAGAIRAG 是检索增强生成…用户它适合用在哪些场景AI这里的“它”指的是 RAG所以可以继续回答 RAG 的应用场景。在真实业务中还可以把 Memory 存储到 Redis 或数据库中避免服务重启后上下文丢失。⸻八、一个简单的 RAG 示例RAG 示例可以拆成几个步骤。加载文档List documents documentLoader.load(“docs/product-manual.md”);文本切分List chunks textSplitter.split(documents);存入向量库vectorStore.add(chunks);用户提问并检索List relatedChunks retriever.retrieve(“如何配置模型 API Key”);构造增强 Prompt 并生成答案String answer ragClient.ask(“如何配置模型 API Key”, relatedChunks);完整链路可以理解为用户问题 检索到的资料 Prompt 模板 → 大模型 → 最终答案RAG 的难点不只在模型调用而在整个链路的工程化处理。比如文档格式如何加载文本如何切分chunk 大小如何设置检索结果如何排序Prompt 如何设计如何避免模型胡编如何返回引用来源这些都是后续需要持续优化的地方。⸻九、Tool Calling 示例Tool Calling 的目标是让大模型可以调用后端业务方法。比如有一个天气查询工具Componentpublic class WeatherTools {private final WeatherService weatherService;public WeatherTools(WeatherService weatherService) {this.weatherService weatherService;}AiTool(name “getWeather”, description “根据城市名称查询天气”)public String getWeather(String city) {return weatherService.query(city);}}用户输入帮我查一下北京今天的天气模型可以识别出{“tool”: “getWeather”,“arguments”: {“city”: “北京”}}然后后端执行对应方法拿到结果后再交给模型组织成自然语言回答。这个过程对于业务系统非常有价值因为它可以让 AI 助手不只是“回答问题”而是可以“执行动作”。例如查询订单查询库存查询用户信息创建工单生成报表调用第三方接口触发业务流程当然Tool Calling 也需要注意权限控制不能让模型随意调用敏感接口。比较合理的做法是只注册允许 AI 调用的方法为工具设置描述和参数约束对高风险操作增加人工确认记录工具调用日志对异常结果做兜底处理⸻十、开发这个框架过程中的一些思考在开发 VertexFlow AI Framework 的过程中我最大的感受是AI 应用开发并不是简单调用一个大模型 API。真正要落地到业务系统里需要考虑很多工程化问题。模型调用要统一不同模型厂商接口不同如果每接一个模型都在业务代码里写一套调用逻辑后期维护成本会很高。比较好的方式是通过统一接口屏蔽底层差异。业务层只依赖 ChatClient、EmbeddingModel、StreamingChatModel 这类抽象而不是直接依赖某个厂商的 HTTP API。Prompt 要可管理Prompt 不应该散落在业务代码中应该有统一的模板管理方式。否则项目变大之后Prompt 很难维护也不方便调整和复用。Memory 要可控多轮对话不能无限追加历史需要考虑 Token 限制和上下文裁剪。对于一些长对话场景可以考虑摘要记忆、最近消息窗口、重要信息抽取等方式。RAG 要可解释知识库问答不能只给一个结果最好能说明答案来自哪些资料。这样用户才更容易信任 AI 的回答。Tool Calling 要安全模型可以调用工具但不能无限制调用所有业务方法。尤其是涉及支付、删除、修改、审批等高风险操作时需要额外增加确认机制。Spring Boot 接入要简单如果一个 AI 框架接入成本很高Java 开发者就很难在真实项目中使用它。所以 VertexFlow AI 的设计目标一直是轻量、清晰、可扩展、适合 Java / Spring Boot 项目接入。⸻十一、项目当前状态目前 VertexFlow AI Framework 还在持续迭代中已经整理了以下方向模型调用流式输出Prompt 模板多轮记忆RAG 检索增强生成文档加载文本切分Tool CallingSimple AgentSpring Boot Starter 自动配置后续计划继续完善更多模型适配更完整的 RAG Demo向量数据库集成示例Tool Calling 参数校验Agent 执行链路优化更多 Spring Boot 示例项目文档和快速开始教程⸻十二、相关实践项目为了验证上面的设计思路我整理了一个开源实践项目VertexFlow AI Framework。它主要用于演示 Java / Spring Boot 中 Chat、Memory、RAG、Tool Calling、Agent 等能力的封装方式。项目地址Giteehttps://gitee.com/crayon-old-and-small/vertexflow-ai-framework项目目前还在持续迭代中欢迎体验、提 Issue、交流建议。如果你也在做 Java AI 应用开发欢迎在评论区交流你的使用场景。我后续会根据大家反馈继续补充 RAG、Tool Calling、Agent、Spring Boot Starter 等模块的实现细节。⸻十三、总结Java 生态并不是不能做 AI 应用。相反在企业级系统中Java / Spring Boot 仍然有很强的工程化优势。如果能把大模型能力和 Java 后端体系结合起来就可以让很多已有业务系统更自然地接入 AI 能力。VertexFlow AI Framework 的目标就是让 Java 开发者可以用熟悉的 Spring Boot 方式快速构建 Chat、Memory、RAG、Tool Calling、Agent 等 AI 应用能力。后续我会继续更新几篇文章Java 实现 RAG 知识库问答文档加载、切分、检索与增强生成Java Tool Calling 实践让大模型调用 Spring Boot 业务方法Spring Boot Starter 自动配置在 AI 框架中的设计实践Java Agent 简单实现从任务理解到工具调用如果这些方向你也感兴趣可以关注后续更新。