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

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

相关推荐
code2cat33 分钟前
【随笔】从聊天到调用工具:理解MCP在AI应用中的位置
java·人工智能
东离与糖宝37 分钟前
元数据知识库
人工智能
我是小邵1 小时前
长对话先收口:用“工作记忆 vs 长期记忆“管理 AI 上下文
人工智能·ai·llm·长期记忆·中间迷失·上下文收口
广州宏帝箱包1 小时前
出口背包的包装有没有防潮、防摔的加固处理
大数据·人工智能
jimmyleeee1 小时前
大模型安全之二十八:Agent 权限与策略控制:从最小权限到多层监督
人工智能·安全
Web3&Basketball1 小时前
Agent外传审计实战:3类失准事故拦截脚本
python·大模型·agent·性能调优·推理优化
仙魁XAN1 小时前
【WorkBuddy·基础入门】第 8 篇 :从材料到汇报:用 WorkBuddy 制作第一份 PPT
人工智能·workbuddy·workbuddy 基础入门·ppt 自动生成
船厂电气自动化ai大模型1 小时前
AI大模型与数学|第81天 课程:正交向量、正交基、格拉姆‑施密特(Gram‑Schmidt)正交化
开发语言·数据结构·人工智能·线性代数·机器学习
罗狮粉 991 小时前
AI-Gateway — 面向 AI Agent 的本地 Runtime Gateway
人工智能·python·inscode·ai编程
FL16238631291 小时前
电力场景变电站设备识别关键部件识别分割数据集labelme格式1660张15类别
人工智能·机器学习