RAG知识库集成

RAG的基本概念

什么是RAG?

RAG(Retrieval-Augmented Generation,检索增强生成)是一种结合信息检索技术和Al内容生成的混合架构,
可以解决大模型的知识时效性限制和幻觉问题。

从技术角度看,R八G在大语言模型生成回答之前,会先从外部知识库中检索相关信息,然后将这些检索到的内容
作为额外上下文提供给模型,引导其生成更准确、更相关的回答。

RAG工作流程

1.文档收集与切割

文档收集:从各种来源(网页、PDF、数据库等)收集原始文档

文档预处理:清洗、标准化文本格式

文档切割:将长文档分割成适当大小的片段(俗称chunks)

  • 基于固定大小(如512个token)
  • 基于语义边界(如段落、章节)
  • 基于递归分割策略(如递归字符n-gram切割)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2. 向量转换与存储

向量转换:使用Embedding模型将文本块转换为高维向量表示,可以捕获到文本的语义特征

向量存储:将生成的向量和对应文本存入向量数据库,支持高效的相似性搜索

向量转换.drawio

3. 文档过滤与存储

查询处理:将用户问题也转换为向量表示

过滤机制:基于元数据、关键词或自定义规则进行过滤

相似度搜索:在向量数据库中查找与问题向量最相似的文档块,常用的相似度搜索算法有余弦相似度、欧氏距离
等

上下文组装:将检索到的多个文档块组装成连贯上下文

屏幕截图 2025-10-08 192858

4.查询增强与关联

提示词组装:将检索到的相关文档与用户问题组合成增强提示词

上下文融合:大模型基于增强提示生成回答

源引用:在回答中添加信息来源引用

后处理:格式化、摘要或其他处理以优化最终输出

image-20251008193818193

完整工作流程

image-20251008194146479

SpringAI + 本地知识库

Spring Al框架为我们实现RAG提供了全流程的支持,参考Spring Al和Spring Al Alibaba的官方文档。

由于是第一个RAG程序,我们参考标准的RAG开发步骤并进行一定的简化,来实现基于本地知识库的AI厨师智能体的问答应用。

标准的RAG开发步骤:

  1. 文档收集和切割
  2. 向量转换和存储
  3. 切片过滤和检索
  4. 查询增强和关联

简化后的RAG开发步骤:

  1. 文档准备
  2. 文档读取
  3. 向量转换和存储
  4. 查询增强

1.文档准备

Anduin2017/HowToCook: 程序员在家做饭方法指南

Gar-b-age/CookLikeHOC: 🥢像老乡鸡🐔那样做饭

2. 文档读取

首先,我们要对自己准备好的知识库文档进行处理,然后保存到向量数据库中。这个过程俗称TL(抽取、转
换、加载),Spring Al提供了对ETL的支持,参考官方文档。

ETL的3大核心组件,按照顺序执行:

  • DocumentReader:读取文档,得到文档列表
  • DocumentTransformer:转换文档,得到处理后的文档列表
  • DocumentWriter:将文档列表保存到存储中(可以是向量数据库,也可以是其他存储)

image-20251008195037202

引入依赖

Spring Al提供了很多种DocumentReaders,用于加载不同类型的文件。

image-20251008195129030

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-pdf-document-reader</artifactId>
</dependency>
编写文档加载器

在根目录下新建rag包,编写文档加载器类CookerAppDocumentLoader,负责读取所有PDF文档并转
换为Document列表。代码如下:

/**
 * 知识库文件加载
 *
 * @author: cheng fu
 **/
@Component
@Slf4j
public class CookerAppDocumentLoader {
    public final ResourcePatternResolver resourcePatternResolver;

    CookerAppDocumentLoader(ResourcePatternResolver resourcePatternResolver) {
        this.resourcePatternResolver = resourcePatternResolver;
    }

    public List<Document> loadPDFs() {
        List<Document> allDocuments = new ArrayList<>();

        try {
            Resource[] resources = resourcePatternResolver.getResources("classpath:document/*pdf");
            for (Resource resource : resources) {
                String filename = resource.getFilename();
                PdfDocumentReaderConfig config = PdfDocumentReaderConfig.builder()
                        .withPageTopMargin(0)
                        .withPageExtractedTextFormatter(ExtractedTextFormatter.builder()
                                .withNumberOfTopTextLinesToDelete(0)
                                .build())
                        .withPagesPerDocument(1)
                        .build();
                PagePdfDocumentReader reader = new PagePdfDocumentReader(resource, config);
                allDocuments.addAll(reader.get());
            }
        } catch (IOException e) {
            log.error("Document loader filed",e);
        }
        return allDocuments;
    }
}

3. 向量转换与存储

为了实现方便,我们先使用Spring Al内置的、基于内存读写的向量数据库SimpleVectorStore来保存文档。

SimpleVectorStore实现了VectorStore接口,而VectorStore接口集成了DocumentWriter,.所以具备文档写入能
力。如图:

image-20251009110626083
@Configuration
@Slf4j
public class CookerAppVectorStoreConfig {

    @Resource
    public CookerAppDocumentLoader cookerAppDocumentLoader;

    @Bean
    VectorStore cookerAppVectorStore(EmbeddingModel dashscopeEmbeddingModel) {
        SimpleVectorStore simpleVectorStore = SimpleVectorStore.builder(dashscopeEmbeddingModel)
                .build();

        //加载文档
        List<Document> documents = cookerAppDocumentLoader.loadPDFs();
        simpleVectorStore.add(documents);
        
        return simpleVectorStore;
    }
}

4. 查询增强

Spring Al通过Advisor特性提供了开箱即用的RAG功能。主要是QuestionAnswerAdvisor问答拦截器和Retrieva
lAugmentationAdvisor检索增强拦截器,前者更简单易用、后者更灵活强大。

查询增强的原理其实很简单。向量数据库存储着A!模型本身不知道的数据,当用户问题发送给A!模型时,Quest
ionAnswerAdvisor会查询向量数据库,获取与用户问题相关的文档。然后从向量数据库返回的响应会被附加到用
户文本中,为AI模型提供上下文,帮助其生成回答。

此处我们就选用更简单易用的QuestionAnswerAdvisor问答拦截器,在CookerApp中新增和RAG知识库进行对话
的方法。代码如下:

    public String doChatWithRag(String message,String chatId){
        ChatResponse chatResponse = chatClient
                .prompt()
                .user(message)
                .advisors(advisorSpec -> advisorSpec.param(ChatMemory.CONVERSATION_ID,chatId))
                .advisors(QuestionAnswerAdvisor.builder(cookerAppVectorStore).build())
                .call().chatResponse();

        String content = chatResponse.getResult().getOutput().getText();
        log.info("content: {}",content);
        return content;
    }

image-20251009162118954

结果显示RAG能正常实现,接下来进行RAG的一些高级用法。


基于PGVector实现向量存储

PGVector是经典数据库PostgreSQL的扩展,为 PostgreSQL 提供了存储和检索高维向量数据的能力。

为什么选择它来实现向量存储呢?因为很多传统业务都会把数据存储在这种关系型数据库中,直接给原有的数据
库安装扩展就能实现向量相似度搜索、而不需要额外搞一套向量数据库,人力物力成本都很低,所以这种方案很
受企业青睐,也是目前实现RAG的主流方案之一。

首先我们准备PostgreSQL数据库,并为其添加扩展。有2种方式,第一种是在自己的本地或服务器安装,可以参
考下列文章实现:

1.引入依赖

参考Spring Al官方文档整合PGVector,先引入依赖,版本号可以在 Maven 中央仓库查找:

<!-- https://mvnrepository.com/artifact/org.springframework.ai/spring-ai-starter-vector-store-pgvector -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-vector-store-pgvector</artifactId>
    <version>1.0.3</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <scope>runtime</scope>
</dependency>

编写配置,建立数据库连接:

spring:
  datasource:
    url: jdbc:postgresql://改为你的公网地址/yu_ai_agent
    username: 改为你的用户名
    password: 改为你的密码
  ai:
    vectorstore:
      pgvector:
        index-type: HNSW
        dimensions: 1536
        distance-type: COSINE_DISTANCE
        max-document-batch-size: 10000 # Optional: Maximum number of documents per batch

2. 编写向量数据库配置类

@Configuration
public class PgVectorVectorStoreConfig {

    @Resource
    private CookerAppDocumentLoader cookerAppDocumentLoader;

    @Bean
    public VectorStore pgVectorVectorStore(JdbcTemplate jdbcTemplate, EmbeddingModel dashscopeEmbeddingModel) {
        VectorStore vectorStore = PgVectorStore.builder(jdbcTemplate, dashscopeEmbeddingModel)
                .dimensions(1536)                    // Optional: defaults to model dimensions or 1536
                .distanceType(COSINE_DISTANCE)       // Optional: defaults to COSINE_DISTANCE
                .indexType(HNSW)                     // Optional: defaults to HNSW
                .initializeSchema(true)              // Optional: defaults to false
                .schemaName("public")                // Optional: defaults to "public"
                .vectorTableName("vector_store")     // Optional: defaults to "vector_store"
                .maxDocumentBatchSize(10000)         // Optional: defaults to 10000
                .build();
        // 加载文档
        List<Document> documents = cookerAppDocumentLoader.loadPDFs();
        vectorStore.add(documents);
        return vectorStore;
    }
}

3.启动类排除配置类

@SpringBootApplication(exclude = PgVectorStoreAutoConfiguration.class)
public class AiCookerApplication {

	public static void main(String[] args) {
		SpringApplication.run(AiCookerApplication.class, args);
	}

}

4. 实现RAG

    public String doChatWithRag(String message,String chatId){
        ChatResponse chatResponse = chatClient
                .prompt()
                .user(message)
                .advisors(advisorSpec -> advisorSpec.param(ChatMemory.CONVERSATION_ID,chatId))
               .advisors(QuestionAnswerAdvisor.builder(pgVectorVectorStore).build())
                .call().chatResponse();

        String content = chatResponse.getResult().getOutput().getText();
        log.info("content: {}",content);
        return content;
    }

advisorSpec.param(ChatMemory.CONVERSATION_ID,chatId))
.advisors(QuestionAnswerAdvisor.builder(pgVectorVectorStore).build())
.call().chatResponse();

    String content = chatResponse.getResult().getOutput().getText();
    log.info("content: {}",content);
    return content;
}

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐