
Ollama 是一个开源的大型语言模型LLM平台Ollama 提供了简洁易用的命令行界面和服务器使用户能够轻松下载、运行和管理各种开源 LLM通过 Ollama用户可以方便地加载和使用各种预训练的语言模型支持文本生成、翻译、代码编写、问答等多种自然语言处理任务。ollama官网https://ollama.comSpring AI支持使用Ollama管理的模型下面介绍Spring AI中如何使用OllamaChat和Ollama Embeddings。3.1. Ollama下载与安装Ollama下载地址:https://github.com/ollama/ollama,这里以window中下载为例下载完成后双击“OllamaSetup.exe”进行安装默认安装在“C\users{user}\AppData\Local\Programs”目录下建议C盘至少要有10G 剩余的磁盘空间因为后续Ollama中还要下载其他模型到相应目录中。安装完成后电脑右下角自动有“Ollama”图标并开机启动。可以在cmd中运行模型进行会话#命令 ollama run模型 deepseek-r1:1.5b ollama run deepseek-r1:1.5b你是谁think/think您好我是由中国的深度求索DeepSeek公司开发的智能助手DeepSeek-R1。如您有任何任何问题我会尽我所能为您提供帮助。注意使用run命令第一次运行模型如果模型不存在会自动下载然后进入模型交互窗口。后续使用会自动进入到交互窗口。在浏览器中输入“localhost:11434”可以访问ollama输出“Ollama is running”。默认情况下Ollama 服务仅监听本地回环地址127.0.0.1这意味着只有在本地计算机上运行的应用程序才能访问该服务如果想要使用“windows ip:11434”访问ollama需要在环境变量中加入“OLLAMA_HOST”为“0.0.0.0”,这样就将 Ollama 的监听地址设置为 0.0.0.0使其监听所有网络接口包括本机 IP 地址。注意以上环境变量设置完成后需要重启ollama。3.2. Ollama Chat1) 配置项目pom.xml?xml version1.0encodingUTF-8?project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersionparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion3.5.0/versionrelativePath/!--lookup parent from repository--/parentgroupIdcom.example/groupIdartifactIdSpringAIOllama/artifactIdversion0.0.1-SNAPSHOT/versionnameSpringAIOllama/namedescriptionSpringAIOllama/descriptionpropertiesjava.version17/java.version/properties!--导入SpringAIBOM用于统一管理SpringAI依赖的版本 引用每个SpringAI模块时不用再写version只要依赖什么模块Mavens自动使用BOM推荐的版本--dependencyManagementdependenciesdependencygroupIdorg.springframework.ai/groupIdartifactIdspring-ai-bom/artifactIdversion1.0.0-SNAPSHOT/versiontypepom/typescopeimport/scope/dependency/dependencies/dependencyManagementdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.ai/groupIdartifactIdspring-ai-starter-model-ollama/artifactId/dependency/dependencies!--声明仓库 用于获取SpringAI以及相关预发布版本--repositoriesrepositoryidspring-snapshots/idnameSpringSnapshots/nameurlhttps://repo.spring.io/snapshot/urlreleasesenabledfalse/enabled/releases/repositoryrepositorynameCentralPortalSnapshots/nameidcentral-portal-snapshots/idurlhttps://central.sonatype.com/repository/maven-snapshots//urlreleasesenabledfalse/enabled/releasessnapshotsenabledtrue/enabled/snapshots/repository/repositories/project2) 配置resources/application.propertiesspring.application.nameSpringAIOllamaserver.port8080#配置Ollama的基础URL和使用模型 spring.ai.ollama.base-urlhttp://localhost:11434spring.ai.ollama.chat.options.modeldeepseek-r1:1.5b spring.ai.ollama.chat.options.temperature0.83.2.1. 基本聊天importorg.springframework.ai.deepseek.DeepSeekChatModel;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RequestParam;importorg.springframework.web.bind.annotation.RestController;RestControllerRequestMapping(/ai)publicclassChatController{AutowiredprivateOllamaChatModelchatModel;GetMapping(/generate)publicStringgenerate(RequestParam(valuemessage,defaultValue给我讲个笑话)Stringmessage){System.out.println(收到消息message);StringresultchatModel.call(message);//模型返回的内容System.out.println(result);returnresult;}}}启动项目后浏览器输入“http://localhost:8080/ai/generate?message你是谁”可以看到输出内容如下我是DeepSeekChat由深度求索公司DeepSeek开发的智能AI助手✨ 我可以帮你解答问题、提供建议、陪你聊天还能处理各种文本、文档等内容。无论是学习、工作还是日常生活中的疑问都可以来问我哦 有什么我可以帮你的吗3.2.2. Stream流式聊天//流式获取模型返回的内容获取返回的 Text 内容GetMapping(/generateStream2)publicFluxStringgenerateStream2(RequestParam(valuemessage,defaultValue给我讲个笑话)Stringmessage,HttpServletResponseresponse){// 避免返回乱码response.setCharacterEncoding(UTF-8);System.out.println(收到消息message);varpromptnewPrompt(newUserMessage(message));FluxStringresultchatModel.stream(prompt).map(chatResponse-chatResponse.getResult().getOutput().getText());returnresult;}重新启动项目后可以在浏览器输入“http://localhost:8080/ai/generateStream2?message你是谁”查看模型Stream流式返回结果。3.2.3. 运行时参数设置Spring AI 使用Ollama中的模式时也支持运行参数设置可以在调用模型时创建一个prompt并嵌入一个新的OllamaOptions来覆盖启动配置。//运行时参数设置GetMapping(/runtimeOptions)publicStringruntimeOptions(RequestParam(valuemessage)Stringmessage,RequestParam(valuetemp,requiredfalse)Doubletemp){System.out.println(收到消息message);Promptprompt;if(temp!null){// 构建带 temperature 的 DeepSeekChatOptions覆盖默认 temperaturevaroptsOllamaOptions.builder().temperature(temp).build();promptnewPrompt(message,opts);System.out.println(使用运行时覆盖 temperaturetemp);}else{// 无 temperature 传入时使用默认配置promptnewPrompt(message);System.out.println(使用默认 temperature);}ChatResponserespchatModel.call(prompt);Stringresultresp.getResult().getOutput().getText();System.out.println(模型返回result);returnresult;}以上代码编写好后重启项目可以传入不同的参数http://localhost:8080/ai/runtimeOptions?message1加1等于几temp0.13.3. Ollama EmbeddingsOllama Embeddings 是基于 Spring AI 中 EmbeddingModel 接口的实现使用 Ollama 本地部署的模型生成文本嵌入embeddings。使用Ollam Embeddings你需要准备如下内容本地安装OllamaOllama中拉取下载了Embedding模型3.3.1. 下载Embedding模型Ollama支持很多模型可以通过“https://ollama.com/library”查看可用的模型列表在本机Ollama运行7B模型至少需要8GB内存运行13B模型至少需要16G内存运行33B模型至少需要32G内存。注意“7B”、“13B” 和 “33B” 分别表示模型中参数的数量级分别为 70 亿、130 亿和 330 亿个参数。模型的参数数量直接影响其对内存的需求参数越多模型越复杂所需的内存也就越大运行这些模型时确保系统具有足够的内存。这里在Ollama中下载“nomic-embed-text:latest”嵌入模型命令如下ollama pull nomic-embed-text3.3.2. Embedding案例-查找相似文本按照如下步骤完成Ollama Embedding案例该案例和上一章节中 “Embedding案例1”代码一样只是换成了Ollama中的Embedding模型需要准备如下内容1.创建SpringBoot项目引入“spring-ai-starter-model-ollama”相关依赖2.在resources/application.properties配置中引入Ollama的嵌入模型1) 准备Service及对应方法importorg.springframework.ai.embedding.EmbeddingModel;importorg.springframework.stereotype.Service;importjava.util.List;ServicepublicclassEmbeddingService{privateEmbeddingModelembeddingModel;privatefinalListfloat[]docVectors;// 1. 准备知识库文本内容privatefinalListStringdocsList.of(美食非常美味服务员也很友好。,这部电影既刺激又令人兴奋。,阅读书籍是扩展知识的好方法。);publicEmbeddingService(EmbeddingModelembeddingModel){this.embeddingModelembeddingModel;// 2. 启动时将所有文档向量化this.docVectorsthis.embeddingModel.embed(docs);}/** * 输入用户查询返回最相似文档的索引 使用余弦相似度计算 * param query 用户输入的查询文本 * return 最相似的知识库文本 */publicStringqueryBestMatch(Stringquery){//将用户的输入通过EmbeddingModel转换成向量float[]queryVecembeddingModel.embed(query);intbestIdx-1;//记录目前最匹配文档在列表中的索引位置doublebestSim-1;//记录目前的最高相似度// 遍历所有文档对应的向量计算与查询向量的相似度for(inti0;idocVectors.size();i){//计算余弦相似度doublesimcosineSimilarity(queryVec,docVectors.get(i));if(simbestSim){bestSimsim;bestIdxi;}}returndocs.get(bestIdx);}// 余弦相似度实现// 计算两个向量之间的余弦相似度数值范围在 [-1, 1] 之间// 相似度越高越接近1越接近0越不相似privatedoublecosineSimilarity(float[]a,float[]b){doubledot0,na0,nb0;for(inti0;ia.length;i){dota[i]*b[i];naa[i]*a[i];nbb[i]*b[i];}returndot/(Math.sqrt(na)*Math.sqrt(nb));}}AutowiredprivateEmbeddingServiceservice;//文本相似检测GetMapping(/similarity)publicMapString,Stringsimilarity(RequestParam(query)Stringquery){Stringansservice.queryBestMatch(query);returnMap.of(query,query,answer,ans);}2) 启动项目并测试启动Spring Boot项目浏览器中输入如下内容进行相似文本查找由于Embedding模型大小原因导致匹配不精准#输入http://localhost:8080/ai/similarity?query美食{query:美食,answer:美食非常美味服务员也很友好。}#输入http://localhost:8080/ai/similarity?query电影{answer:美食非常美味服务员也很友好。,query:电影}#输入http://localhost:8080/ai/similarity?query书籍{answer:美食非常美味服务员也很友好。,query:书籍}