第5节:RAG知识库上传,解析和验证

第5节:RAG知识库上传,解析和验证

AI Agent 拖拉拽:AI Agent 拖拉拽

上一节:第4节:UI页面对接(流式应答界面)

本节:第5节:RAG知识库上传,解析和验证

下一节:待更新

以大模型向量存储的方式,提交本地文件到知识库。并在 AI 对话中增强检索知识库符合 AI 对话内容的资料,合并提交问题。

技术方案

以 Spring AI 提供的向量模型处理框架,将上传文件以 TikaDocumentReader 方式进行解析,再通过 TokenTextSplitter 拆分文件。完成这些操作后,在遍历文档添加标记。标记的作用是为了可以区分不同的知识库内容。完成这些动作后,把这些拆解并打标的文件存储到 postgresql 向量库中。

方案流程

文件上传与解析

  1. 文件上传 : 用户通过前端界面或 API 上传文件,文件可以是多种格式(如 MD、TXT、SQL 等)。

  2. 文件解析 : 使用 TikaDocumentReader 对上传的文件进行解析,提取出文本内容。TikaDocumentReader 能够处理多种文件格式,并提取出结构化的文本数据。

文本拆分

  1. 文本拆分 : 使用 TokenTextSplitter 将解析后的文本内容拆分为更小的片段。拆分策略可以根据需求进行调整,例如按句子、段落或固定长度的 token 进行拆分。

  2. 拆分后的文本片段 : 每个文本片段将作为后续处理和存储的基本单元。

文本标记

  1. 标记添加 : 在遍历拆分后的文本片段时,为每个片段添加标记。标记的作用是区分不同的知识库内容,例如通过标记标识文件的来源、类别或其他元数据信息。

  2. 标记格式 : 标记可以是简单的字符串标签,也可以是结构化的 JSON 数据,具体格式根据业务需求确定。

向量化与存储

  1. 向量化 : 使用 Spring AI 提供的向量模型将标记后的文本片段转换为向量表示。向量化过程将文本内容映射到高维向量空间,便于后续的相似性搜索和检索。

  2. 存储到PostgreSQL向量库 : 将向量化后的文本片段及其标记存储到 PostgreSQL 向量库中。PostgreSQL 提供了高效的向量索引和搜索功能,能够支持大规模的文本数据存储和检索。

应用场景

  • 知识库管理 : 适用于需要管理多个知识库内容的场景,通过标记区分不同来源的知识库。

  • 文档检索 : 支持基于内容的文档检索,通过向量化实现高效的相似性搜索。

  • 智能问答 : 适用于构建智能问答系统,通过向量化存储和检索实现快速的知识匹配。

  • 代码评审 :结合代码库,评审具体的代码块,会更加准确。

  • 编程开发 :可用于编程开发中需求理解、代码查询、流程图等。

功能实现

引入组件

xml 复制代码
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-tika-document-reader</artifactId>
        </dependency>

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

文件配置

yaml 复制代码
server:
  port: 8090

spring:
  datasource:
    driver-class-name: org.postgresql.Driver
    url: jdbc:postgresql://172.27.213.102:5432/ai-chat-bot
    username: postgres
    password: postgres
    type: com.zaxxer.hikari.HikariDataSource

  ai:
    ollama:
      base-url: http://127.0.0.1:11434
      embedding:
        options:
          num-batch: 768
        model: nomic-embed-text

# Redis
redis:
  sdk:
    config:
      host: 172.27.213.102
      port: 6378
      pool-size: 10
      min-idle-size: 5
      idle-timeout: 30000
      connect-timeout: 5000
      retry-attempts: 3
      retry-interval: 1000
      ping-interval: 60000
      keep-alive: true

logging:
  level:
    root: info
  config: classpath:logback-spring.xml

向量存储

Spring AI 提供了简单 SimpleVectorStore 实现类,把文档信息缓存到内存中。以及 PgVectorStore 实现类,把文档存储到向量库。

java 复制代码
@Configuration
public class RAGEmbeddingConfig {

    @Bean
    public TokenTextSplitter  tokenTextSplitter() {
        return new TokenTextSplitter();
    }

    @Bean
    public OllamaApi ollamaApi(@Value("${spring.ai.ollama.base-url}") String baseUrl) {
        return new OllamaApi(baseUrl);
    }

    @Bean
    public SimpleVectorStore simpleVectorStore( OllamaApi ollamaApi) {
        OllamaEmbeddingClient ollamaEmbeddingClient = new OllamaEmbeddingClient(ollamaApi);
        ollamaEmbeddingClient.withDefaultOptions(OllamaOptions.create().withModel("nomic-embed-text"));
        return new SimpleVectorStore(ollamaEmbeddingClient);
    }

    @Bean
    public PgVectorStore pgVectorStore(OllamaApi ollamaApi, JdbcTemplate jdbcTemplate) {
        OllamaEmbeddingClient embeddingClient = new OllamaEmbeddingClient(ollamaApi);
        embeddingClient.withDefaultOptions(OllamaOptions.create().withModel("nomic-embed-text"));
        return new PgVectorStore(jdbcTemplate, embeddingClient);
    }


}
  • 向量库的指定,也可以通过实例化的时候通过 withModel 指定。

  • SimpleVectorStore,把知识库缓存到内存。

  • PgVectorStore,把知识库通过 JdbcTemplate 也就是 pgsql 操作,存储到向量库。

  • TokenTextSplitter,用于切割文本的操作。

上传知识库

java 复制代码
    @Test
    public void chat() {
        String message = "你好王大锤那年人?";

        String systemPrompt = """
                Use the information from the DOCUMENTS section to provide accurate answers but act as if you knew this information innately.
                If unsure, simply state that you don't know.
                Another thing you need to note is that your reply must be in Chinese!
                DOCUMENTS:
                    {documents}
                """;

        simpleVectorStore.accept(loadKnowledgeDocuments());

        SearchRequest request = SearchRequest.query(message).withTopK(5);

        List<Document> documents = simpleVectorStore.similaritySearch(request);
        String documentsCollectors = documents.stream()
                .map(Document::getContent)
                .collect(Collectors.joining());

        Message ragMessage = new SystemPromptTemplate(systemPrompt)
                .createMessage(Map.of("documents", documentsCollectors));

        ArrayList<Message> messages = new ArrayList<>();
        messages.add(new UserMessage(message));
        messages.add(ragMessage);

        ChatResponse chatResponse = ollamaChatClient.call(
                new Prompt(messages, OllamaOptions.create().withModel("deepseek-r1:1.5b"))
        );

        log.info("test result: {}", JSON.toJSONString(chatResponse));
    }
  • 在有知识库的加持下,我们提问的信息,就可以从知识库通过向量方式检索出匹配的信息,之后一起作为问题提问。

  • 那么,你可以想象下,如果你想做个代码需求的扩展,但你不想梳理你要修改的代码范围,就可以通过知识库检索,来辅助你完成需求的处理。

相关推荐
九酒15 小时前
AI Agent 开发踩坑记:口播功能非得用 APP 原生实现吗?
前端·人工智能·agent
蝎子莱莱爱打怪15 小时前
DSpark 讲透:DeepSeek 不换模型,硬把 V4 提速 85%,是怎么做到的?
人工智能·面试·程序员
巫山老妖17 小时前
置身AI内
人工智能
IT_陈寒18 小时前
JavaScript项目实战经验分享
前端·人工智能·后端
fengliaoai19 小时前
DeepSeek搞了个DSpark,AI直接进入“秒回时代”,你还在傻等?
大模型
vanuan20 小时前
两个AI智能体第一次对话-A2A双Agent协作实战
人工智能
kfaino21 小时前
码农的AI翻身(四)你好,我叫 Attention
人工智能·后端
雨落Re1 天前
如何设计一个高质量Skill
人工智能
Token炼金师1 天前
大模型权重文件全指南:从格式选择到优化实战
人工智能
阿牛哥_GX1 天前
CDP 浏览器操控原理:让脚本接管你的浏览器
人工智能