赞
踩
在AI大模型百花齐放的时代,很多人都对新兴技术充满了热情,都想尝试一下。但是,实际上要入门AI技术的门槛非常高。除了需要高端设备,还需要面临复杂的部署和安装过程,这让很多人望而却步。不过,随着开源技术的不断进步,使得入门AI变得越来越容易。通过使用Ollama,您可以快速体验大语言模型的乐趣,不再需要担心繁琐的设置和安装过程。另外,通过集成Spring AI,让更多Java爱好者能便捷的将AI能力集成到项目中,接下来,跟随我的脚步,一起来体验一把。
是 Spring 生态系统的一个新项目,它简化了 Java 中 AI 应用程序的创建。它提供以下功能:
是一个强大的框架,用于在 Docker 容器中部署 LLM(大型语言模型)。它的主要功能是在 Docker 容器内部署和管理 LLM 的促进者,使该过程变得简单。它可以帮助用户快速在本地运行大模型,通过简单的安装指令,用户可以执行一条命令就在本地运行开源大型语言模型。
Ollama 支持 GPU/CPU 混合模式运行,允许用户根据自己的硬件条件(如 GPU、显存、CPU 和内存)选择不同量化版本的大模型。它提供了一种方式,使得即使在没有高性能 GPU 的设备上,也能够运行大型模型。
下载地址:https://www.oracle.com/java/technologies/downloads/#jdk17-windows
类文件具有错误的版本 61.0, 应为 52.0
SpringBoot版本为3.2.3
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>3.2.3</version>
- <relativePath/> <!-- lookup parent from repository -->
- </parent>
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- <optional>true</optional>
- </dependency>
-
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-core</artifactId>
- </dependency>
-
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- </dependency>
-
- <dependency>
- <groupId>cn.hutool</groupId>
- <artifactId>hutool-core</artifactId>
- <version>5.8.24</version>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.ai</groupId>
- <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
- <version>0.8.0</version>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.ai</groupId>
- <artifactId>spring-ai-ollama-spring-boot-starter</artifactId>
- <version>0.8.0</version>
- </dependency>
参见:开源模型应用落地-工具使用篇-Ollama(六)-CSDN博客
- @RequestMapping("/chat")
- public String chat(){
- String systemPrompt = "{prompt}";
- SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemPrompt);
-
- String userPrompt = "广州有什么特产?";
- Message userMessage = new UserMessage(userPrompt);
-
- Message systemMessage = systemPromptTemplate.createMessage(MapUtil.of("prompt", "you are a helpful AI assistant"));
-
- Prompt prompt = new Prompt(List.of(userMessage, systemMessage));
-
- List<Generation> response = openAiChatClient.call(prompt).getResults();
-
- String result = "";
-
- for (Generation generation : response){
- String content = generation.getOutput().getContent();
- result += content;
- }
-
- return result;
- }
调用结果:
- @RequestMapping("/stream")
- public SseEmitter stream(HttpServletResponse response){
- response.setContentType("text/event-stream");
- response.setCharacterEncoding("UTF-8");
- SseEmitter emitter = new SseEmitter();
-
-
- String systemPrompt = "{prompt}";
- SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemPrompt);
-
- String userPrompt = "广州有什么特产?";
- Message userMessage = new UserMessage(userPrompt);
-
- Message systemMessage = systemPromptTemplate.createMessage(MapUtil.of("prompt", "you are a helpful AI assistant"));
- Prompt prompt = new Prompt(List.of(userMessage, systemMessage));
-
- openAiChatClient.stream(prompt).subscribe(x -> {
- try {
- log.info("response: {}",x);
- List<Generation> generations = x.getResults();
- if(CollUtil.isNotEmpty(generations)){
- for(Generation generation:generations){
- AssistantMessage assistantMessage = generation.getOutput();
- String content = assistantMessage.getContent();
- if(StringUtils.isNotEmpty(content)){
- emitter.send(content);
- }else{
- if(StringUtils.equals(content,"null"))
- emitter.complete(); // Complete the SSE connection
- }
- }
- }
-
-
- } catch (Exception e) {
- emitter.complete();
- log.error("流式返回结果异常",e);
- }
- });
-
- return emitter;
- }
流式输出返回的数据结构:
调用结果:
Spring封装的很好,基本和调用OpenAI的代码一致
- @RequestMapping("/chat")
- public String chat(){
- String systemPrompt = "{prompt}";
- SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemPrompt);
-
- String userPrompt = "广州有什么特产?";
- Message userMessage = new UserMessage(userPrompt);
-
- Message systemMessage = systemPromptTemplate.createMessage(MapUtil.of("prompt", "you are a helpful AI assistant"));
-
- Prompt prompt = new Prompt(List.of(userMessage, systemMessage));
-
- List<Generation> response = ollamaChatClient.call(prompt).getResults();
-
- String result = "";
-
- for (Generation generation : response){
- String content = generation.getOutput().getContent();
- result += content;
- }
-
- return result;
- }
调用结果:
Ollam的server.log输出
- @RequestMapping("/stream")
- public SseEmitter stream(HttpServletResponse response){
- response.setContentType("text/event-stream");
- response.setCharacterEncoding("UTF-8");
- SseEmitter emitter = new SseEmitter();
-
-
- String systemPrompt = "{prompt}";
- SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemPrompt);
-
- String userPrompt = "广州有什么特产?";
- Message userMessage = new UserMessage(userPrompt);
-
- Message systemMessage = systemPromptTemplate.createMessage(MapUtil.of("prompt", "you are a helpful AI assistant"));
- Prompt prompt = new Prompt(List.of(userMessage, systemMessage));
-
- ollamaChatClient.stream(prompt).subscribe(x -> {
- try {
- log.info("response: {}",x);
- List<Generation> generations = x.getResults();
- if(CollUtil.isNotEmpty(generations)){
- for(Generation generation:generations){
- AssistantMessage assistantMessage = generation.getOutput();
- String content = assistantMessage.getContent();
- if(StringUtils.isNotEmpty(content)){
- emitter.send(content);
- }else{
- if(StringUtils.equals(content,"null"))
- emitter.complete(); // Complete the SSE connection
- }
- }
- }
-
-
- } catch (Exception e) {
- emitter.complete();
- log.error("流式返回结果异常",e);
- }
- });
-
- return emitter;
- }
调用结果:
不能判断是否为''(即空字符串),以下代码将提前关闭连接
流式输出会返回''的情况
应该在返回内容为字符串null的时候关闭
- import cn.hutool.core.collection.CollUtil;
- import cn.hutool.core.map.MapUtil;
- import jakarta.servlet.http.HttpServletResponse;
- import lombok.extern.slf4j.Slf4j;
- import org.apache.commons.lang3.StringUtils;
- import org.springframework.ai.chat.Generation;
- import org.springframework.ai.chat.messages.AssistantMessage;
- import org.springframework.ai.chat.messages.Message;
- import org.springframework.ai.chat.messages.UserMessage;
- import org.springframework.ai.chat.prompt.Prompt;
- import org.springframework.ai.chat.prompt.SystemPromptTemplate;
- import org.springframework.ai.openai.OpenAiChatClient;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
- import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
-
- import java.util.List;
-
- @Slf4j
- @RestController
- @RequestMapping("/api")
- public class OpenaiTestController {
- @Autowired
- private OpenAiChatClient openAiChatClient;
-
- // http://localhost:7777/api/chat
- @RequestMapping("/chat")
- public String chat(){
- String systemPrompt = "{prompt}";
- SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemPrompt);
-
- String userPrompt = "广州有什么特产?";
- Message userMessage = new UserMessage(userPrompt);
-
- Message systemMessage = systemPromptTemplate.createMessage(MapUtil.of("prompt", "you are a helpful AI assistant"));
-
- Prompt prompt = new Prompt(List.of(userMessage, systemMessage));
-
- List<Generation> response = openAiChatClient.call(prompt).getResults();
-
- String result = "";
-
- for (Generation generation : response){
- String content = generation.getOutput().getContent();
- result += content;
- }
-
- return result;
- }
-
- @RequestMapping("/stream")
- public SseEmitter stream(HttpServletResponse response){
- response.setContentType("text/event-stream");
- response.setCharacterEncoding("UTF-8");
- SseEmitter emitter = new SseEmitter();
-
-
- String systemPrompt = "{prompt}";
- SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemPrompt);
-
- String userPrompt = "广州有什么特产?";
- Message userMessage = new UserMessage(userPrompt);
-
- Message systemMessage = systemPromptTemplate.createMessage(MapUtil.of("prompt", "you are a helpful AI assistant"));
- Prompt prompt = new Prompt(List.of(userMessage, systemMessage));
-
- openAiChatClient.stream(prompt).subscribe(x -> {
- try {
- log.info("response: {}",x);
- List<Generation> generations = x.getResults();
- if(CollUtil.isNotEmpty(generations)){
- for(Generation generation:generations){
- AssistantMessage assistantMessage = generation.getOutput();
- String content = assistantMessage.getContent();
- if(StringUtils.isNotEmpty(content)){
- emitter.send(content);
- }else{
- if(StringUtils.equals(content,"null"))
- emitter.complete(); // Complete the SSE connection
- }
- }
- }
-
-
- } catch (Exception e) {
- emitter.complete();
- log.error("流式返回结果异常",e);
- }
- });
-
- return emitter;
- }
- }
- import cn.hutool.core.collection.CollUtil;
- import cn.hutool.core.map.MapUtil;
- import jakarta.servlet.http.HttpServletResponse;
- import lombok.extern.slf4j.Slf4j;
- import org.apache.commons.lang3.StringUtils;
- import org.springframework.ai.chat.Generation;
- import org.springframework.ai.chat.messages.AssistantMessage;
- import org.springframework.ai.chat.messages.Message;
- import org.springframework.ai.chat.messages.UserMessage;
- import org.springframework.ai.chat.prompt.Prompt;
- import org.springframework.ai.chat.prompt.SystemPromptTemplate;
- import org.springframework.ai.ollama.OllamaChatClient;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
- import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
-
- import java.util.List;
-
- @Slf4j
- @RestController
- @RequestMapping("/api")
- public class OllamaTestController {
- @Autowired
- private OllamaChatClient ollamaChatClient;
-
- @RequestMapping("/chat")
- public String chat(){
- String systemPrompt = "{prompt}";
- SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemPrompt);
-
- String userPrompt = "广州有什么特产?";
- Message userMessage = new UserMessage(userPrompt);
-
- Message systemMessage = systemPromptTemplate.createMessage(MapUtil.of("prompt", "you are a helpful AI assistant"));
-
- Prompt prompt = new Prompt(List.of(userMessage, systemMessage));
-
- List<Generation> response = ollamaChatClient.call(prompt).getResults();
-
- String result = "";
-
- for (Generation generation : response){
- String content = generation.getOutput().getContent();
- result += content;
- }
-
- return result;
- }
-
-
- @RequestMapping("/stream")
- public SseEmitter stream(HttpServletResponse response){
- response.setContentType("text/event-stream");
- response.setCharacterEncoding("UTF-8");
- SseEmitter emitter = new SseEmitter();
-
-
- String systemPrompt = "{prompt}";
- SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemPrompt);
-
- String userPrompt = "广州有什么特产?";
- Message userMessage = new UserMessage(userPrompt);
-
- Message systemMessage = systemPromptTemplate.createMessage(MapUtil.of("prompt", "you are a helpful AI assistant"));
- Prompt prompt = new Prompt(List.of(userMessage, systemMessage));
-
- ollamaChatClient.stream(prompt).subscribe(x -> {
- try {
- log.info("response: {}",x);
- List<Generation> generations = x.getResults();
- if(CollUtil.isNotEmpty(generations)){
- for(Generation generation:generations){
- AssistantMessage assistantMessage = generation.getOutput();
- String content = assistantMessage.getContent();
- if(StringUtils.isNotEmpty(content)){
- emitter.send(content);
- }else{
- if(StringUtils.equals(content,"null"))
- emitter.complete(); // Complete the SSE connection
- }
- }
- }
-
-
- } catch (Exception e) {
- emitter.complete();
- log.error("流式返回结果异常",e);
- }
- });
-
- return emitter;
- }
- }
- spring:
- ai:
- openai:
- api-key: sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
- ollama:
- base-url: http://localhost:11434
- chat:
- model: qwen:1.8b-chat
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
-
- @SpringBootApplication
- public class AiApplication {
-
- public static void main(String[] args) {
- System.setProperty("http.proxyHost","127.0.0.1");
- System.setProperty("http.proxyPort","7078"); // 修改为你代理软件的端口
- System.setProperty("https.proxyHost","127.0.0.1");
- System.setProperty("https.proxyPort","7078"); // 同理
-
- SpringApplication.run(AiApplication.class, args);
- }
-
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。