跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
JavaAIjava

SpringAI 基于 Ollama 本地部署 Deepseek 模型实现对话机器人

基于 Ollama 本地部署 Deepseek 模型,通过 Spring AI 框架实现对话机器人。涵盖模型下载、Java 调用、向量数据库(pgvector)构建、RAG 增强检索、PDF 文档读取、Function Call 自定义函数调用及多模态能力。展示 Spring Boot 与 pgvector 集成配置及 ChatClient 使用方法。

不羁发布于 2026/4/7更新于 2026/5/2314 浏览
SpringAI 基于 Ollama 本地部署 Deepseek 模型实现对话机器人

SpringAI 基于 Ollama 本地部署 Deepseek 模型实现对话机器人

Java 调用 Deepseek

本地没有安装 Ollama、Docker,openwebUI,可以先学习相关部署教程。

下载 Deepseek 模型

打开命令行窗口,拉取一下 Deepseek 模型:

ollama run deepseek-r1:7b

本地测试

运行 Open WebUI 后选择 Deepseek-r1 模型进行测试。

Java 调用模型

先把以前的 moonshot 依赖注释掉,然后将 moonshot 相关的删除,不然会报错。

引入 ollama 依赖:

<!-- 引入 Ollama 依赖-->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-ollama-spring-boot-starter</artifactId>
</dependency>

修改配置类:

package com.yan.springai;
import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.InMemoryChatMemory;
import org.springframework.ai.ollama.OllamaChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@RequiredArgsConstructor
public class Init {
    //要使用的模型
    final OllamaChatModel model2;

    @Bean
    public ChatClient chatClient(ChatMemory chatMemory){
        return ChatClient.builder(model2)
                .defaultSystem("假如你是特朗普,接下来的对话你必须以特朗普的语气来进行?")
                .defaultAdvisors(new MessageChatMemoryAdvisor(chatMemory))//这里主要负责拼接
                .build();
    }

    @Bean
    public ChatMemory chatMemory(){
        //负责存和读
        return new InMemoryChatMemory();
    }
}

修改配置文件:

spring:
  ai:
    ollama:
      chat:
        options:
          model: deepseek-r1:7b
          base-url: http://localhost:11434

然后运行文件,查看输出。

构建数据库

增强检索 RAG

Embedding 是一种将对象(如词语、物品、用户等)表示为数值向量的方法。这种方法在深度学习和推荐系统中非常重要,因为它能够捕捉对象之间的相似性和关系。

先用 ollama 拉取一个 embedding 模型(选择的这个模型比较小,适合小项目,不适合企业级项目):

ollama pull all-minilm

向量数据库

这里使用 pgvector(也可以用 redis)。

pgvector 是一个强大的 PostgreSQL 扩展,它为 PostgreSQL 数据库添加了向量相似性搜索功能。这使得我们可以在关系型数据库中执行语义搜索,将结构化数据查询与非结构化数据的语义理解相结合。

先使用命令拉取一下 pgvector:

docker run -d --name pgvector -p 5433:5432 -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres pgvector/pgvector:pg16

Springboot 集成 pgvector

首先引入依赖:

<!-- 引入 pgvector-->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-pgvector-store-spring-boot-starter</artifactId>
</dependency>

然后对他进行配置:

spring:
  ai:
    vectorstore:
      pgvector:
        index-type: HNSW
        distance-type: COSINE_DISTANCE
        # 维度,根据选的 embedding 模型所定
        dimensions: 384
        batching-strategy: TOKEN_COUNT
        max-document-batch-size: 1000
    ollama:
      chat:
        options:
          model: deepseek-r1:7b
          embedding:
            enabled: true
            model: all-minilm
          base-url: http://localhost:11434
    datasource:
      url: jdbc:postgresql://localhost:5433/springai
      username: postgres
      password: postgres

然后使用 springboot 连一下数据库。

接着执行语句建表:

create extension if not exists vector;
create extension if not exists hstore;
create extension if not exists "uuid-ossp";
create TABLE if not exists vector_store(
    id uuid DEFAULT uuid_generate_v4() PRIMARY KEY,
    content text,
    metadata json,
    embedding vector(384)
);
create index on vector_store using HNSW(embedding vector_cosine_ops);

然后在 resources 中新建一个 txt 文件。

然后建一个 vector 文件夹,创建一个 VectorAPI 类。

编写文件:

package com.yan.springai.vector;
import lombok.RequiredArgsConstructor;
import org.springframework.ai.document.Document;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;

@RestController
@RequiredArgsConstructor
public class VectorAPI {
    final VectorStore store;

    //导入方法
    @GetMapping("/vec/write")
    public String write() throws IOException {
        StringBuffer text = new StringBuffer();//用来存储文件
        ClassLoader classLoader=getClass().getClassLoader();//因为打包后,resource 的文件就放在 class:path 下,我们使用这个获取
        InputStream inputStream=classLoader.getResourceAsStream("ncode.txt");//获取文件
        //把文件一行一行读取出来,放在 text 中去
        try(BufferedReader reader=new BufferedReader(new InputStreamReader(inputStream))){
            String line;
            while ((line=reader.readLine())!=null){
                text.append(line);
            }
        }
        //按照句号,将文本分割成一行一行的
        store.write(Arrays.stream(text.toString().split("。")).map(Document::new).toList());
        return "success";
    }
}

然后运行一下,控制台上打印出结果表示已经导入完毕,查看数据库内容。

这时候你会得到,一个和普通模型差不多的答案。

其实我们 RAG 的能力也是通过 advisor 实现的,所以我们需要修改一下 Init 代码:

package com.yan.springai;
import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.QuestionAnswerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.InMemoryChatMemory;
import org.springframework.ai.ollama.OllamaChatModel;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@RequiredArgsConstructor
public class Init {
    //要使用的模型
    final OllamaChatModel model2;
    final VectorStore vectorStore;

    @Bean
    public ChatClient chatClient(ChatMemory chatMemory){
        return ChatClient.builder(model2)
                .defaultSystem("假如你是特朗普,接下来的对话你必须以特朗普的语气来进行?")
                .defaultAdvisors(new MessageChatMemoryAdvisor(chatMemory), new QuestionAnswerAdvisor(vectorStore) )//这里主要负责拼接
                .build();
    }

    @Bean
    public ChatMemory chatMemory(){
        //负责存和读
        return new InMemoryChatMemory();
    }
}

然后我们在测试一下,测试成功。

chatpdf

引入依赖:

<!-- 将 pdf 引入向量数据库-->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-pdf-document-reader</artifactId>
</dependency>

然后再编写代码:

package com.yan.springai.Pdf;
import lombok.RequiredArgsConstructor;
import org.springframework.ai.reader.ExtractedTextFormatter;
import org.springframework.ai.reader.pdf.PagePdfDocumentReader;
import org.springframework.ai.reader.pdf.config.PdfDocumentReaderConfig;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
public class Pdf {
    final VectorStore store;

    @GetMapping("/pdf/read")
    public String getDocsFromPdf() {
        PagePdfDocumentReader pdfReader=new PagePdfDocumentReader("classpath:/baogao.pdf", PdfDocumentReaderConfig.builder()
                .withPageTopMargin(0)
                .withPageExtractedTextFormatter(ExtractedTextFormatter.builder()
                        .withNumberOfTopTextLinesToDelete(0)
                        .build())
                .withPagesPerDocument(1)
                .build() );
        store.write(pdfReader.read());
        return "success";
    }
}

然后运行测试一下,发现可以正常读入向量数据库。

function call 调用自定义函数

注意:部分 AI 模型可能不支持此功能,例如 Deepseek,而 Moonshot、OpenAI、Gimini 等支持。

首先创建一个逻辑函数,实现 Function 函数:

package com.yan.springai.func;
import java.util.function.Function;

public class OaService implements Function<OaService.Rquest, OaService.Response> {
    public Response apply(Rquest rquest) {
        //实现逻辑,这里是请假逻辑
        System.err.printf("%s is token off%n",rquest.who);
        return new Response(10);
    }

    public record Rquest(String who) { }
    public record Response(int days) { }
}

然后再将 Function 注册到 spring 容器中:

package com.yan.springai.func;
import org.springframework.ai.model.function.FunctionCallback;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

//将 function 注册到 spring 容器中
@Configuration
public class FunctionRegistry {
    @Bean
    public FunctionCallback askForLeaveCallBack(){
        return FunctionCallback.builder()
                .function("askForLeave",new OaService())//注册的名字和函数
                .description("当有人请假时,返回请假天数")//描述功能
                .build();
    }
}

然后再进行调用:

package com.yan.springai.func;
//使用刚刚定义的函数
import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
public class FuncAPI {
    final ChatClient chatClient;

    @GetMapping("/ai/func")
    public String funcCall(@RequestParam(value = "message")String message){
        return chatClient.prompt(message)
                .functions("askForLeave")//调用名称
                .call().content();
    }
}

然后运行一下,就可以看到输出了。

多模态能力

多模态大语言模型(Multimodal Large Language Models,简称 Multimodal LLMs)是一种能够理解和生成多种类型数据的模型,包括文本、图片、音频和视频等。这些模型可以跨越不同的数据形式,进行信息的交互与生成。例如,传统语言模型只能处理文字,但多模态模型不仅能'读'文字,还能'看'图片、'听'声音,甚至'看'视频,并用文字或其他形式将它们的理解表达出来。

这里拿图片转文字作为例子给大家介绍一下。

提示:Deepseek、Moonshot 等是不支持的,可以下载 llava。

打开命令行窗口:

ollama run llava

然后进行下载。

然后可以在 resources 传入一张图片。

编写代码:

package com.yan.springai.model;
import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.model.Media;
import org.springframework.ai.ollama.OllamaChatModel;
import org.springframework.ai.ollama.api.OllamaModel;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.MimeTypeUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;

@RestController
@RequiredArgsConstructor
public class ImageAPI {
    final OllamaChatModel model;

    @GetMapping("/ai/chatWithPic")
    public String chatWithPic() {
        ClassPathResource imageData=new ClassPathResource("cat.png");
        Message userMessage=new UserMessage("请用中文描述一下这张图片是什么东西?", List.of(new Media(MimeTypeUtils.IMAGE_PNG,imageData)));
        return model.call(new Prompt(
                List.of(userMessage),
                ChatOptions.builder()
                        .model(OllamaModel.LLAVA.getName()).build()))
                .getResult().getOutput().getText();
    }
}

然后你就可以看到他的结果了。

目录

  1. SpringAI 基于 Ollama 本地部署 Deepseek 模型实现对话机器人
  2. Java 调用 Deepseek
  3. 下载 Deepseek 模型
  4. 本地测试
  5. Java 调用模型
  6. 构建数据库
  7. 增强检索 RAG
  8. 向量数据库
  9. Springboot 集成 pgvector
  10. chatpdf
  11. function call 调用自定义函数
  12. 多模态能力
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 80 元低成本无人机系统设计与实现
  • C++ IO 流体系详解
  • SpringAI 结合 Ollama 本地部署 Deepseek 模型实现对话机器人
  • Xiaozhi-ESP32 开源 AI 语音机器人:低成本构建个人智能助理
  • 基于 JSP 的志愿者管理系统设计与实现
  • cxx-qt 底层机制:实现 C++ 与 Rust 无缝通信及开发效率提升
  • 阿里云发布通义听悟:音视频内容 AI 处理新工具评测
  • 微信小程序 AR 开发:5 步实现增强现实应用
  • 前端面试高频场景题汇总
  • 前缀和算法详解:连续数组与矩阵区域和
  • AIGC 时代技术创作者如何守护数字作品价值
  • IsaacLab 快速搭建机器人训练环境入门指南
  • 数据结构——图:遍历、最小生成树与最短路径
  • Flash Attention 导入报错 undefined symbol 解决方案
  • Llama 3:Meta 新一代开源大语言模型详解
  • Tactical RMM 开源远程监控管理工具使用指南
  • AI 问答知识库本地化部署指南:基于 FastGPT
  • SpringBoot 整合 Langchain4j 对接主流大模型实战
  • OpenClaw 在 Manjaro 系统上的部署与使用指南
  • 基于 Python 和 AI 的智能害虫识别助手搭建

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online