Spring AI 与 Ollama 的协同作用:利用 LLM 转变本地 AI 交互

即使在当今时代,Java 和 Spring 仍引领着大多数开发社区,而 Python 则是 AI 领域(机器学习或生成式 AI)的主要武器。如果 Java 开发人员不愿意使用 Python,他们该如何利用或使用 LLM?这就是 Spring AI 弥补差距的地方。当我阅读 Spring AI 门户时,我更想做的是创建 Spring 应用程序和可以在本地运行的 LLM 之间的集成。这让所有 Java 开发人员都能够开发 AI 驱动的应用程序。

img

议程

在本文中,我们将了解如何使用 Ollama 在本地运行 LLM,并将考虑四个方面。

  1. 在本地安装并运行 Ollama 和 LLM
  2. 创建SpringAI项目并详细查看项目配置。
  3. 访问本地嵌入。
  4. 访问本地聊天模型。

安装并运行 Ollama

导航至https://ollama.com/download下载适用于特定操作系统的 ollama。

img

下载 ollama 后,打开终端并输入以下命令来提取 LLM 并在本地运行它们。您可以通过导航到Models
上图中的菜单来检查可用的模型。有关更多说明,请转到 Ollama 文档并检查可用的不同选项。

ollama run llama2 # 拉动 llama2 LLM 模型
ollama run mistral # 拉动并运行 mistral LLM

创建 Spring AI 项目

如果您使用任何 IDE(我的情况是 IntelliJ)或基于 Web 的,Spring Intializr那么您现在可以看到可以直接从中添加 AI 依赖项Spring Intializr。在这种情况下,我们将添加Ollama。在执行此步骤之前,请确保您已按照步骤 1 安装ollama并在本地运行。

img

一旦您填写了所有必需的详细信息,项目的脚手架将如下所示。

img

让我们深入application.yaml了解一下不同的项目配置ollama.

img

一些配置的解释

spring:
  ai:
    ollama:
      嵌入:
        模型: “llama2”
        选项:
          温度: 0.5 
          top-p: 0.2 
          top-k: 2 
          num-gpu: 1# 在MAC上启用金属gpu 
      base-url: “http://localhost:11434”

关于嵌入和聊天模型的更多配置可以分别在这里和这里找到。请注意,Spring 默认配置适用于MistralLLM,但我们已明确覆盖了llama2.

代码

首先我们将创建两个记录Payload,Response并且名称更加直观。

包 org.vaslabs.springai2.records;

公共 记录 有效负载(字符串字符串) { 
}
包org.vaslabs.springai2.records;

导入java.util.List;

公共 记录 响应(List <Double> 数据) { 
}

现在让我们创建一个服务类,它将帮助我们生成Embeddings给定的输入字符串。

包org.vaslabs.springai2.service;

导入org.springframework.ai.embedding.EmbeddingClient;
导入org.springframework.ai.embedding.EmbeddingRequest; 导入 org.springframework.ai.embedding.EmbeddingResponse ;
导入org.springframework.ai.ollama.api.OllamaOptions ;
导入org.springframework.stereotype.Service;导入 org.vaslabs.springai2.records.Payload; 导入java.util.List; 导入java.util.Map 
; @Service
公共类OllamaEmbeddingsGenerator {私有最终EmbeddingClient embeddingClient ;公共OllamaEmbeddingsGenerator ( EmbeddingClient embeddingClient) { this .embeddingClient = embeddingClient;     }公共EmbeddingResponse getEmbeddingsWithModelOverride (Payload payload) {返回此.embeddingClient.call(新EmbeddingRequest (                 List.of(payload.strings()),                 OllamaOptions.create().withModel( "mistral" )));     }公共Map<String, EmbeddingResponse> getEmbeddingsWithDefaultModel (Payload payload) { EmbeddingResponse embeddingResponse =此.embeddingClient.embedForResponse(                 List.of(payload.strings()));返回Map.of( "embedding" , embeddingResponse);     } }





  
     

     
        


    
          




    
           

        

上述OllamaEmbeddingsGenerator类在 Spring 应用程序的包中定义org.vaslabs.springai2.service,用作生成文本嵌入的服务组件。它利用 Spring AI 框架EmbeddingClient将文本数据转换为嵌入,即在自然语言处理任务中有用的矢量表示。该服务配备了两种主要方法:getEmbeddingsWithModelOverride和getEmbeddingsWithDefaultModel。前一种方法允许指定用于嵌入生成的模型(例如“mistral”),从而允许每个请求自定义行为。后一种方法使用客户端的默认模型设置生成嵌入。这两种方法都通过获取封装要Payload嵌入的字符串的对象来操作,并以不同的格式返回嵌入结果——EmbeddingResponse在的情况下直接返回,在的情况下返回getEmbeddingsWithModelOverride包含的映射。这种设计封装了与嵌入生成技术交互的复杂性,并为应用程序内的各种嵌入生成要求提供了灵活的 API。EmbeddingResponse``getEmbeddingsWithDefaultModel

让我们研究另一项有助于创建聊天一代的服务。

包org.vaslabs.springai2.service;

导入org.springframework.ai.ollama.OllamaChatClient;
导入org.springframework.stereotype.Service;

导入java.util.Map;

@Service
公共 类 OllamaChatGenerator {

    私有 最终OllamaChatClient ollamaChatClient;

    公共 OllamaChatGenerator (OllamaChatClient ollamaChatClient) {
        此.ollamaChatClient = ollamaChatClient;
    }

    公共Map生成(字符串消息) {
        返回Map.of( “generation”,此.ollamaChatClient.call(message)); 
    } 
}

上述 Java 类OllamaChatGenerator在包中定义org.vaslabs.springai2.service,旨在通过利用OllamaChatClientSpring AI 框架的来促进聊天交互,从而实现 Spring 服务。此服务标有@ServiceSpring 组件扫描的注释,封装了一种简单而有效的聊天响应生成方法。通过其构造函数实例化后,它会接收一个OllamaChatClient对象,从而建立依赖关系,使其能够与底层聊天模型或服务进行通信。此服务的主要功能通过方法公开generate,该方法接受字符串消息作为输入并返回一个包含聊天生成结果的映射,该映射由“generation”键控。此设置抽象了与 AI 驱动的聊天功能交互的复杂性,为 Spring 应用程序的其他组件提供了一种直接的方法来根据用户输入生成动态的对话响应。

现在是时候为上述两个服务编写控制器,分别处理最终用户的请求。这些控制器将帮助我们选择用户所需的功能。

包org.vaslabs.springai2.controller;

导入org.springframework.ai.embedding.Embedding;
导入org.springframework.ai.embedding.EmbeddingResponse;
导入org.springframework.http.MediaType;
导入org.springframework.http.ResponseEntity;
导入org.springframework.web.bind .注释.PostMapping;
导入org.springframework.web.bind.注释.RequestBody;
导入org.springframework.web.bind.注释.RequestMapping;
导入org.springframework.web.bind.注释.RestController;
导入org.vaslabs.springai2.records.Payload;
导入org.vaslabs.springai2.records.Response;
导入org.vaslabs.springai2.service.OllamaEmbeddingsGenerator;

导入java.util.Map;

@RestController 
@RequestMapping( "/api/v1" )
公共 类 OllamaEmbeddingController {

    私有 最终OllamaEmbeddingsGenerator ollamaEmbeddingsGenerator;

    公共OllamaEmbeddingController(OllamaEmbeddingsGenerator ollamaEmbeddingsGenerator) {
        此.ollamaEmbeddingsGenerator = ollamaEmbeddingsGenerator; 
    } 
    @PostMapping(value = "/embedding1",产生 = MediaType.APPLICATION_JSON_VALUE)
    公共ResponseEntity<Response> fetchEmbeddings1( @RequestBody Payload payload){ 
        Embedding embedding =此.ollamaEmbeddingsGenerator.getEmbeddingsWithModelOverride(payload).getResult();
        返回ResponseEntity.ok(新 Response(embedding.getOutput())); 
    } 

    @PostMapping(value = "/embedding2" , produce = MediaType.APPLICATION_JSON_VALUE) 
    public ResponseEntity<Map<String, EmbeddingResponse>> fetchEmbeddings2( @RequestBody Payload payload){ 
        Map<String, EmbeddingResponse> embedding = this .ollamaEmbeddingsGenerator.getEmbeddingsWithDefaultModel(payload);
        返回ResponseEntity.ok(embedding); 
    } 
}
包org.vaslabs.springai2.controller;

导入 o rg.springframework.http.MediaType;
导入 o rg.springframework.web.bind.注释.PostMapping;
导入org.springframework.web.bind .注释.RequestBody;
导入org.springframework.web.bind.注释.RequestMapping;
导入 o rg.springframework.web.bind.注释.RestController;
导入org.vaslabs.springai2.records.Payload;
导入o rg.vaslabs.springai2.service.OllamaChatGenerator;

导入java.util.Map;

@RestController 
@RequestMapping(“/api/v1”)
公共 类 OllamaChatController {

    私有 最终OllamaChatGenerator ollamaChatGenerator;

    公共OllamaChatController(OllamaChatGenerator ollamaChatGenerator){
        此.ollamaChatGenerator = ollamaChatGenerator; 
    } 

    @PostMapping(value = “/chat”,产生= MediaType.APPLICATION_JSON_VALUE)
    公共Map chat(@RequestBody Payload payload){
        返回 此.ollamaChatGenerator.generate(payload.strings()); 
    } 
}

如果以上所有代码和配置都很好,那么我们就可以运行项目了(请注意,请确保您在本地运行 ollama)。

查看OllamaEmbeddingController路线/embedding1,/embedding2非常有趣,第一条路线通过在服务中以编程方式覆盖模型的配置来使用 Mistral 模型。后面的路线使用来自的默认配置application.yaml.

img

通过调用 /embedding1 路由嵌入

img

通过调用 /embedding2 路由嵌入

img

调用 ollama 聊天

结论:

置application.yaml.

[外链图片转存中…(img-DzIasZfh-1722244199805)]

通过调用 /embedding1 路由嵌入

[外链图片转存中…(img-SH2RxS6B-1722244199805)]

通过调用 /embedding2 路由嵌入

[外链图片转存中…(img-eONGEPGr-1722244199805)]

调用 ollama 聊天

结论:

总之,将 Ollama 与 Spring AI 结合使用,可以提供一种引人注目的解决方案,将高级大型语言模型 (LLM) 直接集成到您的应用程序中,同时提供嵌入和文本生成功能。借助 Ollama 在本地运行 LLM 的能力,开发人员可以对其 AI 驱动的功能获得前所未有的控制和灵活性,从而确保数据隐私并减少延迟。Spring AI 通过对 Ollama 的支持OllamaEmbeddingClient简化OllamaChatClient了集成过程,在 Spring 生态系统中实现了无缝嵌入生成和对话式 AI 功能。这种组合不仅使人们能够民主化地访问最先进的 AI 技术,而且还增强了应用程序的可扩展性和响应能力,使其成为希望整合智能、上下文感知交互和数据处理功能的开发人员的理想选择。
博客原文:专业人工智能技术社区

更多推荐