掘金 人工智能 前天 15:46
4-RAG-快速增进AI助手对我的了解
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文介绍了如何利用RAG(检索增强生成)技术,让AI助手更好地理解用户。通过Spring AI框架,结合pgvector向量数据库和m3e向量化模型,实现了从准备工作到代码修改的完整RAG流程。最终,AI助手能够根据用户提供的个人信息,更准确地回答问题,提升了交互体验。

💡 **准备工作:** 搭建pgvector向量数据库和m3e中英文向量化模型,为后续的向量存储和检索奠定基础。

📦 **添加依赖:** 在项目的pom.xml文件中添加Spring AI相关的依赖,包括pgvector向量存储和RAG向量Advisor,为RAG的实现提供必要的支持。

⚙️ **配置向量存储:** 在application.yaml文件中配置向量存储的相关参数,包括数据库连接信息、向量模型地址、API密钥以及向量索引类型等,确保系统能够正确地进行向量的存储和检索。

💻 **代码修改:** 新建VectorStoreController,实现资料库的初始化和搜索功能;修改MyChatController,引入RAG Advisor,改写用户请求,结合向量搜索结果,实现更智能的问答。

✅ **验证效果:** 通过初始化资料库和聊天测试,验证RAG技术的有效性,AI助手能够根据RAG提供的信息更准确地回答问题,展现RAG的强大能力。

1-背景故事

上一篇AI助手学会了使用工具,终于能帮我做很多事情了呢。

但是继续聊天的过程中,发现她对我完全不了解,总感觉像个陌生人:

# 发送消息:我毕业几年了curl http://localhost:8080/ai/chat?message=%E6%88%91%E6%AF%95%E4%B8%9A%E5%87%A0%E5%B9%B4%E4%BA%86# AI助手回复:你的毕业时间取决于你的具体情况,比如你是哪一年毕业的?如果你能告诉我具体的毕业年份,我可以帮你计算毕业多少年了。

有没有办法让她快速了解我呢?这就到RAG(检索增强生成)出马了。

2-动手实践

Spring AI又一次为RAG的实现提供了捷径。

不过即使这样,实现RAG需要的物料和步骤还是略显复杂。

不过别担心,跟着我的节奏一定能实现RAG,等实现之后,再去思考其中的道理。

为了让大家快速理解我们要做什么,我画了一张RAG缩略图供大家参考:

2.1 准备工作

完成本次实践,你需要额外准备:

    pgvector向量数据库;m3e中英文向量化模型;

💡以上两样你十有八九没有现成的,只要你安装了Docker或Podman,使用以下命令即可快速搭建:

# 1.启动pgvector数据库,如果《让AI助手拥有记忆》那一次你用的就是pgvector,可以复用docker run -d \    --name ai-assistant-pgvector \    -p 5432:5432 \    -e POSTGRES_DB=ai-assistant-db \    -e POSTGRES_USER=ai-assistant \    -e POSTGRES_PASSWORD=123456 \    pgvector/pgvector:pg17# 2.启动m3e中英文向量化模型docker run -d \    --name=ai-assistant-m3e \    -p 6008:6008 \    registry.cn-hangzhou.aliyuncs.com/fastgpt_docker/m3e-large-api:latest

2.2 添加组件依赖

在pom.xml中添加向量存储和RAG的依赖

       <!-- ... -->       <!-- pgvector向量检索 -->       <dependency>          <groupId>org.springframework.ai</groupId>          <artifactId>spring-ai-starter-vector-store-pgvector</artifactId>       </dependency>       <!-- RAG向量Advisor -->       <dependency>          <groupId>org.springframework.ai</groupId>          <artifactId>spring-ai-advisors-vector-store</artifactId>       </dependency>       <!-- ... -->

2.3 添加向量存储配置

在application.yaml中添加以下内容:

spring:  #...  # 数据库连接配置,之前配置过的可以省略  datasource:    driver-class-name: org.postgresql.Driver    url: jdbc:postgresql://localhost:5432/ai-assistant-db    username: ai-assistant    password: 123456  ai:    openai:      # 向量模型客户端配置      embedding:        # m3e服务地址,本地用前述docker命令启动就是下面这个        base-url: "http://localhost:6008"        # m3e的密钥,本地用前述docker命令启动默认就是下面这个        api-key: "sk-aaabbbcccdddeeefffggghhhiiijjjkkk"        options:          model: m3e    # 向量检索客户端配置    vectorstore:      pgvector:        # 自动创建向量检索表        initialize-schema: true        # 对向量使用HNSW索引        index-type: HNSW        # 向量索引和检索时,使用余弦距离(适用于文本搜索)        distance-type: COSINE_DISTANCE        # 向量维度,与向量化模型匹配,m3e-large模型默认就是1536        dimensions: 1536

2.4 代码修改

为了职责分离,我们新建一个向量控制器VectorStoreController

@RestControllerpublic class VectorStoreController {    private final VectorStore vectorStore;    // 注入向理存储实例    public VectorStoreController(VectorStore vectorStore) {        this.vectorStore = vectorStore;    }        // 初始化资料库    @GetMapping("vector/init")    public String init() {        List<Document> documents = List.of(                new Document("我叫张三,出生于2000年1月1日,于2022年大学毕业于五道口职业技术学院,现工作于深圳南山科技园开心科技有限公司", Map.of("user", "zhangsan","category","resume")),                new Document("我爸叫李雷,出生于1975年2月2日", Map.of("user", "lilei","category","resume")),                new Document("我妈叫韩梅梅,出生于1975年3月3日", Map.of("user", "hanmeimei","category","resume")));        vectorStore.add(documents);        return "ok";    }    @GetMapping("vector/search")    public List<Document> search(@RequestParam String query) {        // Retrieve documents similar to a query        return this.vectorStore.similaritySearch(SearchRequest.builder().query(query).topK(5).similarityThreshold(0.3).build());    }}

下面是将RAG正式引入聊天中的代码:

@RestControllerpublic class MyChatController {    private final ChatClient chatClient;    public MyChatController(ChatClient.Builder chatClientBuilder, ChatMemoryRepository chatMemoryRepository, VectorStore vectorStore) {        ChatMemory chatMemory = MessageWindowChatMemory.builder()                .chatMemoryRepository(chatMemoryRepository) // 消息记录到数据库                .maxMessages(10) // 最多记住10条聊天记录                .build();        this.chatClient = chatClientBuilder                .defaultAdvisors(new SimpleLoggerAdvisor())                .defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build())                // ++++++添加RAG Advisor++++++++++                .defaultAdvisors(                        QuestionAnswerAdvisor.builder(vectorStore)                                // 改写用户请求,拼装用户{query}与向量搜索结果{question_answer_context}                                .promptTemplate(new PromptTemplate("""                                         {query}                                                                                 ** 参考以下从资料库搜索到的信息:                                         {question_answer_context}                                        """))                                // 设置向量库的请求参数,相似度阈值与返回的最大记录数,请根据实际效果调优                                .searchRequest(SearchRequest.builder().similarityThreshold(0.3d).topK(5).build())                                .build())                // ================================                .defaultTools(new DateTimeTools())                .build();    }    //...}

2.5 验证效果

# 第一步:初始化资料库curl http://localhost:8080/vector/init# 第二步:开始聊天# 发送消息:我毕业几年了curl http://localhost:8080/ai/chat?message=%E6%88%91%E6%AF%95%E4%B8%9A%E5%87%A0%E5%B9%B4%E4%BA%86# AI助手回复(似乎忘了调用工具):你的毕业时间是 **2020年6月15日**。今天是 **2023年11月9日**,因此你已经毕业了 **3年4个月24天**。# 发送消息提醒她:今天的日期curl http://localhost:8080/ai/chat?message=%E4%BB%8A%E5%A4%A9%E7%9A%84%E6%97%A5%E6%9C%9F今天的日期是 **2025年6月6日**。# 再次提问:我毕业几年了curl http://localhost:8080/ai/chat?message=%E6%88%91%E6%AF%95%E4%B8%9A%E5%87%A0%E5%B9%B4%E4%BA%86# AI助手回复(终于答对了):根据你的毕业时间 **2022年6月30日**,今天是 **2025年6月6日**,你已经毕业了 **3年**。

现在她终于对我有所了解了🎉

3-课外扩展

    看一下控制台日志或调试代码,整个调用过程、提示词是什么样的;去深入了解一下RAG是什么;实际文档入库的过程,对搜索结果及问题回答结果影响非常大,去了解一下RAG的完整流程和向量检索的优化过程;你能用RAG做什么?试着完善文档入库过程、并录入更多文档。

4-参考资料

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

RAG Spring AI 向量数据库 AI助手
相关文章