springAI + DeepSeek 版 RAG 来啦!!!

 上篇文章我们了解了springAI+zhipu+pgvector实现RAG,从环境搭建到代码编写再到效果演示的完整过程。考虑到近期DeepSeek大火,很多开发者需要对接DeepSeek,所以,这篇文章,将带大家使用springAI+DeepSeek+zhipuEmbedding+pgvector实现RAG,希望能够帮到有需要的开发者。

如需获取完整代码,移步公众号【智界跬步】,给他发消息:DEEPSEEKRAG。

RAG的实现过程

RAG:检索增强生成的缩写,结合了检索和生成两种技术,用于提升生成模型的效果,特别适用于需要外部知识的场景。

为什么需要RAG

1、减少幻觉:依赖检索结果生成,降低模型编造信息的风险。

2、动态知识库:支持实时更新知识库,无需重新训练模型。

3、领域适配:通过定制知识库快速适配垂直场景。

RAG的实现过程

1、文档分割:可按页、段落、token等方式进行分割。

2、文档向量化:使用嵌入模型将文本转为向量表示。

3、向量存储:将文档的向量表示存储到向量数据库中。

4、问题向量化:用户提出问题,嵌入模型生成问题对应的向量。

5、向量检索:通过向量数据库对问题进行相似性搜索,找到相关文档。

6、增强提示:将检索到的相关上下文信息添加到用户的问题提示中。

7、生成答案:基础模型基于增强后的提示生成最终回答。

代码实现

环境说明:    

操作系统:Windows 10

PostgreSQL版本:PostgreSQL16

PGVector版本:
vector-0.7.3(如需安装过程,请看上篇文章)

嵌入模型:智谱Embedding(https://open.bigmodel.cn/api/paas)

基础模型:deepseek-ai/DeepSeek-R1-Distill-Qwen-14B(硅基流动:https://api.siliconflow.cn)

springAI版本:1.0.0-SNAPSHOT

springboot版本:3.4.2

Java版本:17

模型说明:

访问spring官网可以看到spring框架是通过OpenAI API的方式与DeepSeek集成。

图片

在Chat Models下可以找到对DeepSeek的支持,但在Embedding Modes下是没有DeepSeek的,所以本文中对文档的向量化处理还是使用智谱的嵌入模型。

图片

maven依赖配置:


<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-zhipuai-spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-pgvector-store-spring-boot-starter</artifactId>
        <version>${spring-ai.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-markdown-document-reader</artifactId>
        <version>${spring-ai.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-pdf-document-reader</artifactId>
        <version>${spring-ai.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-bom</artifactId>
            <version>${spring-ai.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

代码示例

application.yml配置:

server:
  port: 8180
spring:
  application:
    name: springAI-DeepSeek
  ai:
    openai:
      api-key: 填自己的
      base-url: https://api.siliconflow.cn
      chat:
        options:
          model: DeepSeek-R1-Distill-Qwen-14B
    vectorstore:
      pgvector:
        index-type:
        initialize-schema: true
    zhipuai:
      api-key: 填自己的


  datasource:
    username: postgres
    password: 123456
    url: jdbc:postgresql://localhost:5432/vcs

DsConfiguration.java: 

定义embeddingModel、chatModel,并指定主bean,需要手动指定OpenAiApi和ZhiPuAiApi的baseUrl和apiKey,本文中使用的模型是硅基流动官网的DeepSeek-R1-Distill-Qwen-14B模型。此外,还需定义向量存储相关bean。


@Bean
@Primary
public EmbeddingModel embeddingModel() {
    return new ZhiPuAiEmbeddingModel(new ZhiPuAiApi("填写自己的key"));
}

@Bean
@Primary
public ChatModel chatModel() {
    OpenAiApi openAiApi = new OpenAiApi("https://api.siliconflow.cn", "填写自己的key");
    OpenAiChatOptions options = OpenAiChatOptions.builder()
            .model("deepseek-ai/DeepSeek-R1-Distill-Qwen-14B")
            .build();
    return new OpenAiChatModel(openAiApi, options);
}

FileController.java: 

提供上传文档接口,并负责将文档转为向量表示,存储到向量数据库中。


@RequestMapping("/upload/pdf")
public void uploadPdf(MultipartFile file) {
    fileService.saveSource(file);
}

@RequestMapping("/upload/md")
public void uploadMd(MultipartFile file) throws IOException {
    fileService.saveResourceMarkDown(file);
}

ChatController.java: 提供RAG文档对话接口。


@RequestMapping("/rag/chat")
public String ragChat(String message) {
    return ragService.chatByVectorStore(message);
}

RagService.java: 实现向量检索、系统提示词设置、基础模型调用。


private final static String SYSTEM_PROMPT = """
        你需要使用文档内容对用户提出的问题进行回复,这点非常重要。

        当用户提出的问题无法根据文档内容进行回复时,回复不知道即可。请明确说明,你的答案是否是从文档中获取的。

        文档内容如下:
        {documents}

        """;

@Autowired
private ChatModel chatModel;
@Autowired
private VectorStore vectorStore;

public String chatByVectorStore(String message) {
    List<Document> listOfSimilarDocuments = vectorStore.similaritySearch(message);
    assert listOfSimilarDocuments != null;
    String documents = listOfSimilarDocuments.stream().map(Document::getText).collect(Collectors.joining());
    Message systemMessage = new SystemPromptTemplate(SYSTEM_PROMPT).createMessage(Map.of("documents", documents));
    UserMessage userMessage = new UserMessage(message);
    ChatResponse rsp = chatModel.call(new Prompt(List.of(systemMessage, userMessage)));
    return rsp.getResult().getOutput().getText();
}

运行效果

首先,调用FileController接口,上传一个介绍交通规则的markdown文档。

然后,调用ChatController接口,进行文档内容相关提问。

问题1:什么是交通规则。可以看到从文档中找到了答案,并给出了DeepSeek的思考过程。

图片

问题2:什么是公积金规则。由于我们知识库中没有公积金相关的文档,所以可以看到DeepSeek无法回答,并可以看到它的思考过程。

图片

### 使用SpringAIDeepSeek和Ollama进行数据投喂 #### 准备工作 为了实现使用SpringAIDeepSeek以及Ollama来构建并训练本地大模型的知识库,需先完成环境搭建。这包括但不限于安装必要的软件包和服务框架。 对于SpringAI而言,作为一款用于简化机器学习应用开发的企业级平台工具集,其主要作用在于提供API接口支持与微服务治理能力[^1]。 针对DeepSeek的大规模语言模型,则可通过指定链接下载预训练本,并按照官方文档指导完成初步配置[^2]。 至于Ollama,该组件负责优化模型推理性能及资源调度管理,在此之前同样要确保已正确设置运行环境。 #### 数据准备阶段 收集待处理的数据源文件,这些资料可以是文本形式或其他结构化/非结构化的电子档。接着利用脚本程序批量转换成适合输入给定算法解析的标准格式。例如JSON或CSV等通用交换媒介。 ```json [ {"id": "0", "content": "这是第一条记录"}, {"id": "1", "content": "第二条内容"} ] ``` #### 集成流程说明 通过RESTful API调用方式接入SpringAI所提供的各项功能模块,比如自然语言理解(NLU),对话管理系统(CMS)等等。与此同时,借助于HTTP请求向位于服务器端口监听下的DeepSeek实例发送指令序列以启动新一轮迭代更新过程;期间可能涉及到参数调整、超参寻优等工作环节。 当上述两部分协同作业完毕之后,再经由gRPC协议桥接至Ollama执行最终一轮评估验证操作——即把新获取到的信息注入现有体系之中形成闭环控制机制。如此这般循环往复直至满足预期目标为止。 #### 示例代码片段 下面给出一段Python伪代码用来展示整个交互逻辑: ```python import requests from grpc import insecure_channel def feed_data_to_model(data_path, model_endpoint='http://localhost:8080'): with open(data_path,'r') as f: data = json.load(f) response = requests.post( url=f"{model_endpoint}/api/v1/train", headers={'Content-Type': 'application/json'}, json=data ) channel = insecure_channel('localhost:9090') stub = ollama_pb2_grpc.OllamaStub(channel) request = ollama_pb2.FeedRequest(model_id=response.json()['model_id']) result = stub.Feed(request) print(result.message) if __name__ == '__main__': feed_data_to_model('./data/input.json') ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值