分享到:
发表于 2025-06-06 09:31:35 楼主 | |
炸裂,炸裂,炸裂!从第一次提交代码到现在,经过 2 年的沉淀,Spring AI 框架的第一个正式版本 1.0 终于发布了。 有了这玩意,开发 AI 应用就是洒洒水的事,Java 开发者们是不是又爽了,反正我是很兴奋啊,让 Java 再次伟大! 但可能很多同学还不知道 Spring AI 能干什么,凭什么这玩意就让 Java 伟大了? 正好我最近刚带编程导航的同学做完一套 AI 超级智能体实战项目,毫不夸张地说,我已经把 Spring AI 玩得 “手拿把掐” 了。 下面我来给大家快速分享一下 Spring AI 的核心能力和魔法。看完之后,我相信你会点赞收藏三连,并且说一句:“伟的太大了”。 视频版: 13:14 炸裂,Spring AI让Java再次伟大!还有人没用过吗? 11.9万 336 视频 程序员鱼皮 Spring AI 核心特性 1、大模型调用能力 大模型调用能力是 AI 应用开发的基础,允许应用程序与各种 AI 大模型进行交互,发送提示词并获取模型的响应。Spring AI 提供了统一的接口来支持各种主流大模型,包括 OpenAI GPT 系列、Claude、通义千问等。 Spring AI 通过配置 + 抽象接口简化了大模型的调用过程,我可以直接在配置中声明多个大模型: spring: ai: # 阿里大模型 dashscope: chat: options: model: qwen-max # 本地大模型 ollama: bbse-url: http://localhost:11434 chat: model: gemma3:1b # 谷歌大模型 vertex: ai: gemini: chat: options: model: gemini-1.5-pro-001 然后使用支持链式调用的 ChatClient 灵活地调用各种不同的大模型: // 使用 Spring AI 调用大模型 @Bean public ChatClient chatClient(ChatModel chatModel) { return ChatClient.builder(chatModel).build(); } public String doChat(String message) { ChatResponse response = chatClient .prompt(message) .call() .chatResponse(); return response.getResult().getOutput().getText(); } 只用一行代码,就能支持 Stream 流式响应,实现打字机效果: chatClient .prompt(message) .stream() 如果不使用 Spring AI,则需要为每个模型分别实现 API 调用,要自己编写请求、解析响应,很麻烦! // 不使用 Spring AI 调用大模型 public String chatWithOpenAI(String message) { // 配置 OpenAI API OkHttpClient client = new OkHttpClient(); MediaType JSON = MediaType.get("application/json; charset=utf-8");
// 构建请求体 JSONObject requesTBODH = new JSONObject(); requesTBODH.put("model", "gpt-3.5-turbo"); JSONArray messages = new JSONArray(); JSONObject userMessage = new JSONObject(); userMessage.put("role", "user"); userMessage.put("content", message); messages.put(userMessage); requesTBODH.put("messages", messages);
// 发送请求 RequesTBODH body = RequesTBODH.create(requesTBODH.toString(), JSON); Request request = new Request.Builder() .url("https://api.openai.com/v1/chat/completions") .header("Authorization", "Bearer " + OPENAI_API_KEY) .post(body) .build();
try (Response response = client.newCall(request).execute()) { String responseBody = response.body().string(); JSONObject jsonResponse = new JSONObject(responseBody); return jsonResponse.getJSONArray("choices") .getJSONObject(0) .getJSONObject("message") .getString("content"); } catch (Exception e) { return "Error: " + e.getMessage(); } } Spring AI 不仅提供了统一接口支持多种大模型,让我们可以轻松切换模型而无需修改业务代码。它还支持多模态大模型调用,使 AI 能够同时处理文本、图像、音频等多种输入类型。 我们只需要将图片等资源添加到消息对象中,一起发送给 AI 就可以了,使用 Spring AI 几行代码就能实现: // 调用多模态模型 String response = ChatClient.create(chatModel).prompt() .user(u -> u.text("描述这张图片中的内容") .media(MimeTypeUtils.IMAGE_PNG, new ClassPathResource("/yupi.png"))) .call() .content(); 如果不使用 Spring AI,多模态处理将变得复杂得多: // 不使用 Spring AI 的多模态实现 public String analyzeImage(String textPrompt, File imageFile) { // 读取图像文件并编码为 bbse64 String bbse64Image = ""; try { byte[] fileContent = Files.readAllBytes(imageFile.toPath()); bbse64Image = bbse64.getEncoder().encodeToString(fileContent); } catch (IOException e) { return "Error reading image file: " + e.getMessage(); }
// 构建请求体,不同模型的格式差异很大 JSONObject requesTBODH = new JSONObject(); requesTBODH.put("model", "gpt-4-vision-preview");
JSONArray messages = new JSONArray(); JSONObject userMessage = new JSONObject(); userMessage.put("role", "user");
// 构建复杂的内容数组 JSONArray contentArray = new JSONArray();
// 添加文本部分 JSONObject textContent = new JSONObject(); textContent.put("type", "text"); textContent.put("text", textPrompt); contentArray.put(textContent);
// 添加图像部分 JSONObject imageContent = new JSONObject(); imageContent.put("type", "image_url"); JSONObject imageUrl = new JSONObject(); imageUrl.put("url", "data:image/png;bbse64," + bbse64Image); imageContent.put("image_url", imageUrl); contentArray.put(imageContent);
userMessage.put("content", contentArray); messages.put(userMessage); requesTBODH.put("messages", messages);
// 发送请求并解析响应... // 代码略 } 此外,Spring AI 提供了强大的 Advisors 机制,有点类似面向切面编程,可以在模型调用前后添加额外的逻辑,增强 AI 的能力。 举个例子,使用 Spring AI 内置的日志 Advisor,一行代码就能在调用 AI 前后记录日志: // 使用 Advisors 增强 ChatClient public String doChatWithAdvisors(String message, String chatId) { ChatResponse response = chatClient .prompt() .user(message) // 添加日志 Advisor .advisors(new LoggingAdvisor()) .call() .chatResponse(); return response.getResult().getOutput().getText(); } Advisor 的应用场景还有很多,比如调用 AI 前检查提示词是否安全、得到 AI 响应后保存到数据库中等等。 2、提示工程 提示工程(Prompt Engineering)是一门复杂的学问,指通过精心设计提示词,让 AI 更准确地理解用户意图,生成更符合预期的回答,减少幻觉(生成虚假信息)的概率,同时优化 AI 模型的性能表现并节省成本。 Spring AI 通过 Prompt 和 PromptTemplate 类实现提示工程。 Prompt 类可以统一封装多种不同类型的提示词,便于发送给大模型: // 用户提示词 Message userMessage = new UserMessage(userText); // 系统提示词 Message systemMessage = new SystemMessage(systemText); Prompt prompt = new Prompt(List.of(userMessage, systemMessage)); 利用 PromptTemplate 可以创建支持替换变量的提示词模板,便于提示词的维护和复用: // 使用 Spring AI 的提示模板 PromptTemplate promptTemplate = new PromptTemplate("你好,我是{name},我擅长{skill}"); Prompt prompt = promptTemplate.create(Map.of( "name", "鱼皮", "skill", "编程" )); ChatResponse response = chatClient.call(prompt); 如果不使用 Spring AI,你就需要手动 / 或者利用工具类来拼接提示词字符串,会更麻烦: // 不使用 Spring AI 需要手动字符串拼接 String name = "AI 恋爱顾问"; String skill = "解决恋爱问题"; String promptText = "你好,我是" + name + ",我擅长" + skill; // 还需自行实现条件逻辑、变量转义等 if(hasCondition) { promptText += ",我注意到你可能遇到了" + conditionType + "问题"; } // 调用 API 需自行封装请求 Response response = apiClient.sendPrompt(promptText); 3、会话记忆 会话记忆(Chat Memory)使 AI 能够保存多轮对话历史,理解上下文,实现连贯对话体验,防止 AI 断片儿。 利用 Spring AI 的 Advisor 机制,一行代码就能轻松开启对话记忆: // 使用 Spring AI 的会话记忆 public String doChatWithMemory(String message, String chatId) { ChatResponse response = chatClient .prompt() .user(message) .advisors( // 将对话记忆保存到内存中 new MessageChatMemoryAdvisor(new InMemoryChatMemory()) ) .call() .chatResponse(); return response.getResult().getOutput().getText(); } 还可以设置会话 id 实现隔离、设置上下文大小限制等参数: // 使用 Spring AI 的会话记忆 public String doChatWithMemory(String message, String chatId) { ChatResponse response = chatClient .prompt() .user(message) .advisors( // 将对话记忆保存到内存中 new MessageChatMemoryAdvisor(new InMemoryChatMemory()) ) .advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId) .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10)) .call() .chatResponse(); return response.getResult().getOutput().getText(); } Spring AI 会自动处理上下文窗口大小限制,避免超出模型最大 token 限制。 如果不使用 Spring AI,需要手动管理对话历史,代码量一下子就上来了: // 不使用 Spring AI 的会话记忆实现 Map public String chat(String message, String userId) { // 获取用户历史记录 List
// 添加用户新消息 Message userMessage = new Message("user", message); history.add(userMessage);
// 构建完整历史上下文 StringBuilder contextBuilder = new StringBuilder(); for (Message msg : history) { contextBuilder.append(msg.getRole()).append(": ").append(msg.getContent()).append("n"); }
// 调用 AI API String response = callAiApi(contextBuilder.toString());
// 保存 AI 回复到历史 Message aiMessage = new Message("assistant", response); history.add(aiMessage); conversationHistory.put(userId, history);
return response; } Spring AI 的实现非常优秀,将会话存储和保存机制分离,我们可以自己定义 ChatMemory,将对话历史保存到数据库等持久存储中。 作者:程序员鱼皮 https://www.bilibili.com/read/cv41794893/?from=search&spm_id_from=333.337.0.0&opus_fallback=1 出处:bilibili |
|
楼主热贴
个性签名:无
|
针对ZOL星空(中国)您有任何使用问题和建议 您可以 联系星空(中国)管理员 、 查看帮助 或 给我提意见