第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));
    }
  • 在有知识库的加持下,我们提问的信息,就可以从知识库通过向量方式检索出匹配的信息,之后一起作为问题提问。

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

相关推荐
HackTwoHub4 小时前
AI 挖洞新思路、深度解析两大间接提示词注入漏洞攻防思路,注入也能获得上万美金
人工智能·安全·web安全·网络安全·系统安全·安全架构
EAIReport4 小时前
AI赋能文旅行业:技术重构“诗与远方”,解锁行业数字化新范式
人工智能·重构
郑寿昌4 小时前
B200GPU上SubQ模型7.2倍加速秘诀
人工智能·深度学习
Yeats_Liao4 小时前
BLE Mesh能承载AI推理吗?分布式边缘AI节点部署实战
服务器·人工智能·分布式·架构·边缘计算
AI袋鼠帝4 小时前
我的一人公司AI视频团队,被腾讯收编了
人工智能
AI袋鼠帝4 小时前
还在做传统Office打工人?这9个高频场景,一个千问电脑端全搞定
人工智能
林夕074 小时前
Qt集成AI推理引擎:TensorFlow Lite与ONNX Runtime实战
人工智能·qt·neo4j
团象科技4 小时前
2026出海趋势观察:OpenAI开放云授权重构跨境企业增长逻辑
大数据·人工智能
yuhaiqiang4 小时前
当程序员被ai逼到了悬崖边,还有哪些选择?
前端·人工智能·后端