使用 Ollama 本地模型与 Spring AI Alibaba 的强强结合,打造下一代 RAG 应用

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
MSE Nacos/ZooKeeper 企业版试用,1600元额度,限量50份
云原生网关 MSE Higress,422元/月
简介: 使用 Ollama 本地模型与 Spring AI Alibaba 的强强结合,打造下一代 RAG 应用

Spring AI Alibaba RAG Example 示例项目源码地址:

https://github.com/springaialibaba/spring-ai-alibaba-examples/tree/main/spring-ai-alibaba-rag-example

01

RAG 应用架构概述


1.1 核心组件


  • Spring AI:Spring 生态的 Java AI 开发框架,提供统一 API 接入大模型、向量数据库等 AI 基础设施。
  • Ollama:本地大模型运行引擎,大模型时代的 Docker,支持快速体验部署大模型。
  • Spring AI Alibaba:Spring AI 增强,集成 DashScope 模型平台,快速构建大模型应用。
  • Elasticsearch:向量数据库,存储文本向量化数据,支撑语义检索。


1.2 模型选型


  1. Embedding 模型:nomic-embed-text:latest,用于将文本数据向量化。
  2. Ollama Chat 模型:deepseek-r1:8b,生成最终答案。


02

环境准备


2.1 启动 Ollama 服务


Docker Compose 启动 Ollama:(同时启动一个模型前端系统,和 Ollama 模型交互。


services:

   ollama:
     container_name: ollama
     image: ollama/ollama:latest
     ports:
       - 11434:11434

   open-webui:
     image:  ghcr.io/open-webui/open-webui:main
     container_name: open-webui
     ports:
       - 3005:8080
     environment:
       - 'OLLAMA_BASE_URL=http://host.docker.internal:11434'
     # 允许容器访问宿主机网络
     extra_hosts:
       - host.docker.internal:host-gateway


2.2 下载模型


执行以下命令:


docker exec -it ollama ollama pull deepseek-r1:8b
docker exec -it ollama ollama pull nomic-embed-text:latest


在 open-webui 中调用 deepseek-r1:8b 模型:


image.png


2.3 部署 Elasticsearch


services:

  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.16.1
    container_name: elasticsearch
    privileged: true
    environment:
      - "cluster.name=elasticsearch"
      - "discovery.type=single-node"
      - "ES_JAVA_OPTS=-Xms512m -Xmx1096m"
      - bootstrap.memory_lock=true
    volumes:
      - ./config/es.yaml:/usr/share/elasticsearch/config/elasticsearch.yml
    ports:
      - "9200:9200"
      - "9300:9300"
    deploy:
      resources:
        limits:
          cpus: "2"
          memory: 1000M
        reservations:
          memory: 200M


准备 es 启动的配置文件:


cluster.name: docker-es
node.name: es-node-1
network.host: 0.0.0.0
network.publish_host: 0.0.0.0
http.port: 9200
http.cors.enabled: true
http.cors.allow-origin: "*"
bootstrap.memory_lock: true

# 关闭认证授权 es 8.x 默认开启
xpack.security.enabled: false


至此,便完成搭建一个简单 RAG 应用的所有环境准备步骤。下面开始搭建项目。

03

项目配置


3.1 依赖引入


<!-- Spring Boot Web Starter -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
  <version>3.3.4</version>
</dependency>

<!-- Spring AI Ollama Starter -->
<dependency>
  <groupId>org.springframework.ai</groupId>
  <artifactId>spring-ai-ollama-spring-boot-starter</artifactId>
  <version>1.0.0-M5</version>
</dependency>

<!-- 向量存储 -->
<dependency>
  <groupId>org.springframework.ai</groupId>
  <artifactId>spring-ai-elasticsearch-store</artifactId>
  <version>1.0.0-M5</version>
</dependency>

<!-- PDF 解析 -->
<dependency>
  <groupId>org.springframework.ai</groupId>
  <artifactId>spring-ai-pdf-document-reader</artifactId>
  <version>1.0.0-M5</version>
</dependency>


3.2 核心配置


spring:

  ai:
    # ollama 配置
    ollama:
      base-url: http://127.0.0.1:11434
      chat:
        model: deepseek-r1:8b
      embedding:
        model: nomic-embed-text:latest
  
    # 向量数据库配置
    vectorstore:
      elasticsearch:
        index-name: ollama-rag-embedding-index
        similarity: cosine
        dimensions: 768

  elasticsearch:
    uris: http://127.0.0.1:9200


其中:


  • index-name 为 es 向量索引名;
  • dimensions 为向量模型生成的向量维度(需要和向量模型生成的向量维度一致,默认值为 1576);
  • similarity 定义了用于衡量向量之间相似度的算法或度量方式,这里使用余弦相似度,使用高维稀疏向量。


如果您想自定义 es 的实例化配置,需要引入 spring-ai-elasticsearch-store


<dependency>
  <groupId>org.springframework.ai</groupId>
  <artifactId>spring-ai-elasticsearch-store</artifactId>
  <version>1.0.0-M5</version>
</dependency>


在项目中通过自定义配置 bean 实现。


3.3 Prompt Template


你是一个MacOS专家,请基于以下上下文回答:

---------------------
{question_answer_context}
---------------------

请结合给定上下文和提供的历史信息,用中文 Markdown 格式回答,若答案不在上下文中请明确告知。


04

核心实现


4.1 文本向量化


在 Spring AI 和 Spring AI Alibaba 中,几乎可以将任意数据源作为知识库来源。此例中使用 PDF 作为知识库文档。


Spring AI Alibaba 提供了 40+ 的 document-reader 和 parser 插件。用来将数据加载到 RAG 应用中。


public class KnowledgeInitializer implements ApplicationRunner {

    // 注入 VectorStore 实例,负责向量化数据的增查操作
    private final VectorStore vectorStore;

    // 向量数据库客户端,此处使用 es
    private final ElasticsearchClient elasticsearchClient;

    // .....

    @Override
    public void run(ApplicationArguments args) {

        // 1. load pdf resources.
        List<Resource> pdfResources = loadPdfResources();

        // 2. parse pdf resources to Documents.
        List<Document> documents = parsePdfResource(pdfResources);

        // 3. import to ES.
        importToES(documents);
    }

    private List<Document> parsePdfResource(List<Resource> pdfResources) {

        // 按照指定策略切分文本并转为 Document 资源对象
        for (Resource springAiResource : pdfResources) {

            // 1. parse document
            DocumentReader reader = new PagePdfDocumentReader(springAiResource);
            List<Document> documents = reader.get();
            logger.info("{} documents loaded", documents.size());

            // 2. split trunks
            List<Document> splitDocuments = new TokenTextSplitter().apply(documents);
            logger.info("{} documents split", splitDocuments.size());

            // 3. add res list
            resList.addAll(splitDocuments);
        }
    }

    // ......
}


至此,便完成了将文本数据转为向量数据的过程。


4.2 RAG 服务层


接下来,将使用 Spring AI 中的 Ollama Starter 来完成和模型交互。构建 RAG 应用。


AIRagService.java


@Service
public class AIRagService {

    // 引入 system prompt tmpl
    @Value("classpath:/prompts/system-qa.st")
    private Resource systemResource;

    // 注入相关 bean 实例
    private final ChatModel ragChatModel;

    private final VectorStore vectorStore;

    // 文本过滤,增强向量检索精度
    private static final String textField = "content";

    // ......

    public Flux<String> retrieve(String prompt) {

        // 加载 prompt tmpl
        String promptTemplate = getPromptTemplate(systemResource);

        // 启用混合搜索,包括嵌入和全文搜索
        SearchRequest searchRequest = SearchRequest.builder().
            topK(4)
            .similarityThresholdAll()
            .build();

        // build chatClient,发起大模型服务调用。
        return ChatClient.builder(ragChatModel)
            .build().prompt()
            .advisors(new QuestionAnswerAdvisor(
                vectorStore, 
                searchRequest, 
                promptTemplate)
            ).user(prompt)
            .stream()
            .content();
    }
}


4.3 RAG 服务接口层


编写用户请求接口,处理用户请求,调用 service 获得大模型响应:


@RestController
@RequestMapping("/rag/ai")
public class AIRagController {

    @Resource
    public AIRagService aiRagService;

    @GetMapping("/chat/{prompt}")
    public Flux<String> chat(
        @PathVariable("prompt") String prompt,
        HttpServletResponse response
    ) {

        // 解决 stream 模式下响应乱码问题。
        response.setCharacterEncoding("UTF-8");

        if (!StringUtils.hasText(prompt)) {
            return Flux.just("prompt is null.");
        }

        return aiRagService.retrieve(prompt);
    }
}

05


请求演示


这里以 我现在是一个mac新手,我想配置下 mac 的触控板,让他变得更好用,你有什么建议吗?问题为例,可以看到直接调用模型的回答是比较官方,实用性不高。


5.1 从 open-webui 直接调用


image.png


5.2 调用 RAG 应用接口


image.png


可以看到 RAG 应用的输出更加准确且符合用户需求。

06

RAG 优化


6.1 使用 DashScope 平台模型


使用本地 Ollama 部署模型服务时,模型运行速度收到本地资源限制,思考过程会花费大量时间。因此我们可以通过一些云平台上的模型来增强使用体验。


修改 application.yaml 改为:


spring:
  application:
    name: ollama-rag

  ai:
   dashscope:
     api-key: ${AI_DASHSCOPE_API_KEY}
     chat:
       options:
         model: deepseek-r1
     embedding:
       enabled: false

    ollama:
      base-url: http://127.0.0.1:11434
      chat:
        model: deepseek-r1:8b
        enabled: false
      embedding:
        model: nomic-embed-text:latest

    vectorstore:
      elasticsearch:
        index-name: ollama-rag-embedding-index
        similarity: cosine
        dimensions: 768

  elasticsearch:
    uris: http://127.0.0.1:9200


此处关闭 Ollama 的 Chat 功能,通过 Spring AI Alibaba Starter 依赖使用 DashScope 平台上的 DeepSeekR1 模型。


添加依赖:


<!-- Spring AI Alibaba DashScope -->
<dependency>
  <groupId>com.alibaba.cloud.ai</groupId>
  <artifactId>spring-ai-alibaba-starter</artifactId>
  <version>1.0.0-M6.1</version>
</dependency>


修改 AIRAGService.java


public Flux<String> retrieve(String prompt) {

    // Get the vector store prompt tmpl.
    String promptTemplate = getPromptTemplate(systemResource);

    // Enable hybrid search, both embedding and full text search
    SearchRequest searchRequest = SearchRequest.builder().
            topK(4)
            .similarityThresholdAll()
            .build();

     // Build ChatClient with retrieval rerank advisor:
     ChatClient runtimeChatClient = ChatClient.builder(chatModel)
            .defaultAdvisors(new RetrievalRerankAdvisor(
                vectorStore, 
                rerankModel, 
                searchRequest, 
                promptTemplate, 
                0.1)
            ).build();

     // Spring AI RetrievalAugmentationAdvisor
     Advisor retrievalAugmentationAdvisor = RetrievalAugmentationAdvisor.builder()
            .queryTransformers(RewriteQueryTransformer.builder()
                    .chatClientBuilder(ChatClient.builder(ragChatModel).build().mutate())
                    .build())
            .documentRetriever(VectorStoreDocumentRetriever.builder()
                    .similarityThreshold(0.50)
                    .vectorStore(vectorStore)
                    .build())
            .build();

     // Retrieve and llm generate
     return ragClient.prompt()
            .advisors(retrievalAugmentationAdvisor)
            .user(prompt)
            .stream()
            .content();
}


6.2 检索优化


Spring AI Alibaba RAG 文档:

https://java2ai.com/docs/1.0.0-M5.1/tutorials/rag/


在使用 Spring AI 搭建 RAG 应用时,我们可以在构建 QuestionAnswerAdvisor 时,通过设置一些个性化参数,来让我们的 RAG 应用在检索向量数据时达到最佳状态。


6.3 数据预处理优化


在数据预处理过程中,可以通过:


  1. 删除不相关的文档。噪音数据,特殊字符等来清理数据文本;
  2. 添加一些元数据信息,提高索引数据的质量;
  3. 优化索引结构等。

07

问题排查


Q:向量入库失败

A:检查 ES 索引维度是否匹配模型输出


Q:检索结果不相关

A:检查 Embedding 模型是否与文本类型匹配


Q:响应速度慢

A:调整 Ollama 的计算资源配置


Q:spring-ai-alibaba-starter依赖拉取失败

A:需要配置 mvn 仓库


<repositories>
  <repository>
    <id>spring-milestones</id>
    <name>Spring Milestones</name>
    <url>https://repo.spring.io/milestone</url>
    <snapshots>
      <enabled>false</enabled>
    </snapshots>
  </repository>
  <repository>
    <id>spring-snapshots</id>
    <name>Spring Snapshots</name>
    <url>https://repo.spring.io/snapshot</url>
    <releases>
      <enabled>false</enabled>
    </releases>
  </repository>
</repositories>


08

总结


构建 RAG 应用的全过程分为以下三步:


  1. 数据加载与清洗:从外部知识库加载数据,向量化后存储到 Elasticsearch。
  2. 模型调用优化:通过检索增强技术(RAG),为大模型提供上下文信息。
  3. 交互服务搭建:构建 REST API,实现应用与用户的高效交互。


通过 RAG 的检索增强,模型回答可以更具上下文关联性,最终提升用户体验。

相关文章
|
2月前
|
JSON 人工智能 Java
基于Spring AI构建智能Text-to-SQL转换器:一个完整的MCP
Spring AI 更新结构化输出转换器,弃用旧版 Parser 类,引入与 Spring 框架对齐的 Converter 体系,提升命名规范与功能兼容性。新版本支持 JSON、XML 及 Java 对象转换,确保 LLM 输出结构化,便于下游应用处理。
|
16天前
|
人工智能 Java API
构建基于Java的AI智能体:使用LangChain4j与Spring AI实现RAG应用
当大模型需要处理私有、实时的数据时,检索增强生成(RAG)技术成为了核心解决方案。本文深入探讨如何在Java生态中构建具备RAG能力的AI智能体。我们将介绍新兴的Spring AI项目与成熟的LangChain4j框架,详细演示如何从零开始构建一个能够查询私有知识库的智能问答系统。内容涵盖文档加载与分块、向量数据库集成、语义检索以及与大模型的最终合成,并提供完整的代码实现,为Java开发者开启构建复杂AI智能体的大门。
490 58
|
2天前
|
人工智能 监控 Java
零代码改造 + 全链路追踪!Spring AI 最新可观测性详细解读
Spring AI Alibaba 通过集成 OpenTelemetry 实现可观测性,支持框架原生和无侵入探针两种方式。原生方案依赖 Micrometer 自动埋点,适用于快速接入;无侵入探针基于 LoongSuite 商业版,无需修改代码即可采集标准 OTLP 数据,解决了原生方案扩展性差、调用链易断链等问题。未来将开源无侵入探针方案,整合至 AgentScope Studio,并进一步增强多 Agent 场景下的观测能力。
|
25天前
|
人工智能 Java 机器人
基于Spring AI Alibaba + Spring Boot + Ollama搭建本地AI对话机器人API
Spring AI Alibaba集成Ollama,基于Java构建本地大模型应用,支持流式对话、knife4j接口可视化,实现高隐私、免API密钥的离线AI服务。
464 1
基于Spring AI Alibaba + Spring Boot + Ollama搭建本地AI对话机器人API
|
25天前
|
人工智能 Java 数据库
Spring AI
Spring AI 为 Java 生态注入智能,提供统一抽象接口,简化大模型集成,助力开发者高效构建 AI 应用,推动企业智能化转型。
|
2月前
|
人工智能 自然语言处理 Java
从青铜到王者,DeepSeek+Spring AI 搭建 RAG 知识库
本文介绍了基于RAG(检索增强生成)技术构建知识库的原理与实现方法。RAG通过结合检索与生成模型,提升大语言模型在问答任务中的准确性与相关性,有效缓解“幻觉”问题。文章还详细讲解了如何利用DeepSeek与SpringAI搭建高效RAG系统,并提供了完整的Java代码示例,帮助开发者快速实现文档处理、向量存储与智能问答功能。适用于智能客服、内容生成、辅助决策等多个场景。
504 2
|
2月前
|
人工智能 Java 开发者
邀您参与 “直通乌镇” Spring AI Alibaba 开源竞技挑战赛!
邀您参与 “直通乌镇” Spring AI Alibaba 开源竞技挑战赛!

热门文章

最新文章

下一篇
日志分析软件