Spring AI结合Ollama(三)
摘要:Ollama是一个开源的大型语言模型平台,提供命令行界面和服务器,支持下载、运行和管理各类开源LLM。本文介绍了如何在SpringAI中使用OllamaChat和OllamaEmbeddings,包括Windows环境下的安装配置、SpringBoot项目集成、流式聊天实现以及运行时参数设置。同时详细说明了OllamaEmbeddings的使用方法,包括模型下载、文本向量化处理以及基于余弦相
Ollama 是一个开源的大型语言模型(LLM)平台,Ollama 提供了简洁易用的命令行界面和服务器,使用户能够轻松下载、运行和管理各种开源 LLM,通过 Ollama,用户可以方便地加载和使用各种预训练的语言模型,支持文本生成、翻译、代码编写、问答等多种自然语言处理任务。
ollama官网:https://ollama.com
Spring AI支持使用Ollama管理的模型,下面介绍Spring AI中如何使用OllamaChat和Ollama Embeddings。这里默认已经安装好ollama。
Ollama下载与安装
Ollama下载地址:https://github.com/ollama/ollama,这里以window中下载为例

下载完成后双击“OllamaSetup.exe”进行安装,默认安装在“C\users\{user}\AppData\Local\Programs”目录下,建议C盘至少要有10G 剩余的磁盘空间,因为后续Ollama中还要下载其他模型到相应目录中。

安装完成后,电脑右下角自动有“Ollama”图标并开机启动。可以在cmd中运行模型进行会话

注意:使用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
Ollama Chat
下面以Spring AI中通过与Ollama中模型对话为例,演示Spring AI相关配置。
1) 创建SpringBoot项目,命名为“SpringAIOllama”


2) 配置项目pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>SpringAIOllama</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SpringAIOllama</name>
<description>SpringAIOllama</description>
<properties>
<java.version>17</java.version>
</properties>
<!-- 导入 Spring AI BOM,用于统一管理 Spring AI 依赖的版本,
引用每个 Spring AI 模块时不用再写 <version>,只要依赖什么模块 Mavens 自动使用 BOM 推荐的版本 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>1.0.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-ollama</artifactId>
</dependency>
</dependencies>
<!-- 声明仓库, 用于获取 Spring AI 以及相关预发布版本-->
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>
<repository>
<name>Central Portal Snapshots</name>
<id>central-portal-snapshots</id>
<url>https://central.sonatype.com/repository/maven-snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</project>

基本聊天

Stream流式聊天

//流式获取模型返回的内容,获取返回的 Text 内容
@GetMapping("/generateStream2")
public Flux<String> generateStream2(
@RequestParam(value = "message", defaultValue = "给我讲个笑话") String message,
HttpServletResponse response) {
// 避免返回乱码
response.setCharacterEncoding("UTF-8");
System.out.println("收到消息:"+message);
var prompt = new Prompt(new UserMessage(message));
Flux<String> result = chatModel.stream(prompt)
.map(chatResponse -> chatResponse.getResult().getOutput().getText());
return result;
}
重新启动项目后,可以在浏览器输入“http://localhost:8080/ai/generateStream2?message=你是谁”查看模型Stream流式返回结果
运行时参数设置
Spring AI 使用Ollama中的模式时也支持运行参数设置,可以在调用模型时,创建一个prompt,并嵌入一个新的OllamaOptions来覆盖启动配置。
在“SpringAIOllama”项目的“/controller/ChatController.java”代码中准备如下方法:
//运行时参数设置
@GetMapping("/runtimeOptions")
public String runtimeOptions(
@RequestParam(value = "message") String message,
@RequestParam(value = "temp", required = false) Double temp
) {
System.out.println("收到消息:"+message);
Prompt prompt;
if (temp != null) {
// 构建带 temperature 的 DeepSeekChatOptions,覆盖默认 temperature
var opts = OllamaOptions.builder()
.temperature(temp)
.build();
prompt = new Prompt(message, opts);
System.out.println("使用运行时覆盖 temperature=" + temp);
} else {
// 无 temperature 传入时,使用默认配置
prompt = new Prompt(message);
System.out.println("使用默认 temperature");
}
ChatResponse resp = chatModel.call(prompt);
String result = resp.getResult().getOutput().getText();
System.out.println("模型返回:"+ result);
return result;
}
以上代码编写好后,重启项目,可以传入不同的参数:
“http://localhost:8080/ai/runtimeOptions?message=1加1等于几&temp=0.1”
Ollama Embeddings
Ollama Embeddings 是基于 Spring AI 中 EmbeddingModel 接口的实现,使用 Ollama 本地部署的模型生成文本嵌入(embeddings)。使用Ollam Embeddings你需要准备如下内容:
* 本地安装Ollama
* Ollama中拉取下载了Embedding模型
下载Embedding模型

Embedding案例-查找相似文本
按照如下步骤完成Ollama Embedding案例,该案例和上一章节中 “Embedding案例1”代码一样,只是换成了Ollama中的Embedding模型,需要准备如下内容:
* 创建SpringBoot项目,引入“spring-ai-starter-model-ollama”相关依赖
* 在resources/application.properties配置中引入Ollama的嵌入模型
**1) 准备Service及对应方法**
在“SpringAIOllama”项目中创建“service”包,并在该包中创建“EmbeddingService.java”类,写入如下内容:
import org.springframework.ai.embedding.EmbeddingModel;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class EmbeddingService {
private EmbeddingModel embeddingModel;
private final List<float[]> docVectors;
// 1. 准备知识库文本内容
private final List<String> docs = List.of(
"美食非常美味,服务员也很友好。",
"这部电影既刺激又令人兴奋。",
"阅读书籍是扩展知识的好方法。"
);
public EmbeddingService(EmbeddingModel embeddingModel) {
this.embeddingModel = embeddingModel;
// 2. 启动时,将所有文档向量化
this.docVectors = this.embeddingModel.embed(docs);
}
/**
* 输入用户查询,返回最相似文档的索引 (使用余弦相似度计算)
* @param query 用户输入的查询文本
* @return 最相似的知识库文本
*/
public String queryBestMatch(String query) {
//将用户的输入通过EmbeddingModel转换成向量
float[] queryVec = embeddingModel.embed(query);
int bestIdx = -1; //记录目前最匹配文档在列表中的索引位置
double bestSim = -1; //记录目前的最高相似度
// 遍历所有文档对应的向量,计算与查询向量的相似度
for (int i = 0; i < docVectors.size(); i++) {
//计算余弦相似度
double sim = cosineSimilarity(queryVec, docVectors.get(i));
if (sim > bestSim) {
bestSim = sim;
bestIdx = i;
}
}
return docs.get(bestIdx);
}
// 余弦相似度实现
// 计算两个向量之间的余弦相似度,数值范围在 [-1, 1] 之间
// 相似度越高,越接近1,越接近0,越不相似
private double cosineSimilarity(float[] a, float[] b) {
double dot = 0, na = 0, nb = 0;
for (int i = 0; i < a.length; i++) {
dot += a[i] * b[i];
na += a[i] * a[i];
nb += b[i] * b[i];
}
return dot / (Math.sqrt(na) * Math.sqrt(nb));
}
}

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)