047-LangChain内存管理:VectorStoreRetrieverMemory

案例概述

本案例展示了如何使用LangChain的VectorStoreRetrieverMemory来存储和检索对话历史。与其他内存类型不同,VectorStoreRetrieverMemory将对话存储在向量数据库中,并通过语义相似度检索最相关的对话片段,而不是按时间顺序检索。这种基于语义的检索方式特别适合需要根据上下文相关性而非时间顺序来获取历史信息的场景,如智能客服、教育助手等应用。

核心价值:通过向量嵌入和语义检索技术,实现基于内容相关性的智能记忆系统,使AI能够根据语义关联而非时间顺序来检索历史对话,大大提高了上下文感知能力。

案例目标

  • 理解VectorStoreRetrieverMemory的工作原理和使用场景
  • 掌握如何使用FAISS构建向量存储系统
  • 学习如何通过语义相似度检索相关对话
  • 实现基于向量检索的对话记忆系统
  • 探索语义检索在AI应用中的实际应用价值

技术栈与核心依赖

核心技术
  • LangChain Memory模块 - 内存管理框架
  • FAISS - 高效相似度搜索库
  • OpenAI Embeddings - 文本向量化
  • 向量相似度检索 - 语义匹配技术
依赖包
  • langchain - LangChain核心库
  • langchain_openai - OpenAI集成
  • langchain_community - 社区扩展
  • langchain_core - 核心功能
  • faiss-cpu - 向量相似度搜索
  • langchain-opentutorial - 教程辅助工具

环境配置

1. 安装依赖
pip install langchain-opentutorial
pip install langchain_community langchain_openai langchain_core faiss-cpu
2. 环境变量设置
from langchain_opentutorial import set_env

set_env(
    {
        "OPENAI_API_KEY": "your-openai-api-key",
        "LANGCHAIN_API_KEY": "your-langchain-api-key",
        "LANGCHAIN_TRACING_V2": "true",
        "LANGCHAIN_ENDPOINT": "https://api.smith.langchain.com",
        "LANGCHAIN_PROJECT": "VectorStoreRetrieverMemory",
    }
)
3. 加载环境变量
from dotenv import load_dotenv
load_dotenv(override=True)

注意:确保已正确设置OpenAI API密钥,这是使用文本嵌入功能的前提条件。

案例实现

1初始化向量存储

import faiss
from langchain_openai.embeddings import OpenAIEmbeddings
from langchain_community.docstore.in_memory import InMemoryDocstore
from langchain_community.vectorstores.faiss import FAISS

# 初始化OpenAI嵌入模型
embeddings_model = OpenAIEmbeddings()

# 创建FAISS索引
embedding_size = 1536  # OpenAI嵌入的维度大小
index = faiss.IndexFlatL2(embedding_size)
vectorstore = FAISS(embeddings_model, index, InMemoryDocstore({}), {})

这段代码创建了一个基于FAISS的内存向量存储,用于存储和检索对话嵌入向量,实现快速的相似度搜索。

2创建VectorStoreRetrieverMemory

from langchain.memory import VectorStoreRetrieverMemory

# 设置k=1以确保只返回单个最相关的对话
retriever = vectorstore.as_retriever(search_kwargs={"k": 1})
memory = VectorStoreRetrieverMemory(retriever=retriever)

通过设置k=1,我们确保每次查询只返回最相关的一个对话片段。在实际应用中,可以根据需要增加这个值以提供更多上下文。

3保存面试对话

# 保存面试对话
memory.save_context(
    inputs={
        "human": "Hello, thank you for coming to the interview today. Please introduce yourself."
    },
    outputs={
        "ai": "Hello. I'm a junior developer who majored in Computer Science. In college, I mainly used Java and Python, and recently, I participated in a web development project where I gained experience developing services for real users."
    },
)
memory.save_context(
    inputs={"human": "What was your role in the project?"},
    outputs={
        "ai": "My role was as a backend developer. I was responsible for processing user data and developing server logic, implementing RESTful APIs for communication with the frontend. I also participated in database design."
    },
)
memory.save_context(
    inputs={
        "human": "If you faced any difficulties in team projects, how did you resolve them?"
    },
    outputs={
        "ai": "We had some communication issues at the beginning of the project. To resolve this, our team held regular meetings to share each person's progress. Also, when problems arose, we actively shared opinions and worked to find reasonable solutions."
    },
)
memory.save_context(
    inputs={"human": "What do you consider your strengths as a developer?"},
    outputs={
        "ai": "My strengths are quick learning ability and problem-solving skills. I can quickly acquire new technologies and tools, and when faced with complex problems, I can propose creative solutions. Also, I value teamwork and consider collaboration with colleagues important."
    },
)

这些代码模拟了一个面试场景,保存了多轮面试对话。每段对话都会被转换为向量并存储在向量数据库中。

4检索相关对话

# 查询教育背景
print("Query: What was the interviewee's major?")
print(
    memory.load_memory_variables({"prompt": "What was the interviewee's major?"})[
        "history"
    ]
)

# 查询项目经验
print("Query: What was the interviewee's role in the project?")
print(
    memory.load_memory_variables(
        {"human": "What was the interviewee's role in the project?"}
    )["history"]
)

通过语义相似度检索,系统可以根据查询内容找到最相关的历史对话,即使查询与原始对话的表述方式不同。

案例效果

检索效果示例

查询1:面试者的专业

查询:"What was the interviewee's major?"

检索结果:

human: Hello, thank you for coming to the interview today. Please introduce yourself.
ai: Hello. I'm a junior developer who majored in Computer Science. In college, I mainly used Java and Python, and recently, I participated in a web development project where I gained experience developing services for real users.

系统检索到包含"Computer Science"的对话,准确回答了关于专业的问题。

查询2:项目中的角色

查询:"What was the interviewee's role in the project?"

检索结果:

human: What was your role in the project?
ai: My role was as a backend developer. I was responsible for processing user data and developing server logic, implementing RESTful APIs for communication with the frontend. I also participated in database design.

系统准确检索到关于项目角色的对话,提供了详细的后端开发职责描述。

核心优势:即使查询表述与原始对话不同,系统也能通过语义相似度找到最相关的对话片段,实现了基于内容相关性的智能检索。

案例实现思路

VectorStoreRetrieverMemory工作原理
  1. 向量化处理:将对话内容转换为高维向量表示
  2. 向量存储:使用FAISS等向量数据库存储对话向量
  3. 相似度计算:计算查询向量与存储向量的相似度
  4. 语义检索:根据相似度排序返回最相关的对话
  5. 上下文注入:将检索到的对话作为上下文提供给LLM
与传统内存的区别

传统内存

  • 按时间顺序存储对话
  • 基于时间窗口检索
  • 保留完整对话历史
  • 适合短对话场景

VectorStoreRetrieverMemory

  • 按语义相关性存储对话
  • 基于相似度检索
  • 保留语义相关的对话片段
  • 适合长对话和复杂场景

用户查询

向量化查询

相似度计算

检索相关对话

上下文注入

LLM响应

对话历史

向量化存储

向量数据库

扩展建议

功能扩展
  • 实现混合检索策略,结合关键词和语义检索
  • 添加多语言支持,适应不同语言的对话检索
  • 集成时间权重,平衡相关性和时效性
  • 实现检索结果重排序,提高检索精度
  • 添加对话重要性评分,优先检索关键对话
性能优化
  • 使用更高效的向量数据库,如Milvus或Pinecone
  • 实现向量索引优化,提高检索速度
  • 添加向量缓存机制,减少重复计算
  • 实现增量向量化,避免重复处理
  • 优化嵌入模型,提高向量表示质量
应用场景扩展
  • 智能客服系统:根据问题语义检索相关历史对话
  • 教育平台:根据学习内容检索相关知识片段
  • 医疗助手:根据症状描述检索相关病史
  • 法律咨询:根据案例描述检索相关法律条文
  • 个人助理:根据需求检索相关历史记录

总结

VectorStoreRetrieverMemory是LangChain提供的一种基于向量检索的内存管理方案,通过将对话内容向量化并存储在向量数据库中,实现了基于语义相关性的智能检索。这种方案具有以下优势:

🔍

语义检索

基于内容相关性而非时间顺序检索对话,提供更精准的上下文信息

高效检索

利用FAISS等高效向量数据库,实现快速的相似度搜索

🎯

精准匹配

即使查询表述不同,也能准确找到最相关的对话片段

核心价值:VectorStoreRetrieverMemory通过向量嵌入和语义检索技术,为AI应用提供了更加智能和灵活的内存管理方案。它使AI能够根据语义关联而非时间顺序来检索历史对话,大大提高了上下文感知能力,特别适合需要处理复杂对话场景的应用,如智能客服、教育助手等。

在解决 Maven 依赖冲突时,核心目标是确保构建系统正确选择所需的依赖版本,并排除不兼容或错误的依赖。针对问题中提到的 `'dev.langchain4j:langchain4j-open-ai:jar:unknown'` 错误,这通常表示 Maven 无法解析依赖的版本,或者依赖未在仓库中找到。以下是解决该问题的步骤和策略: ### 1. 检查依赖声明 确保 `pom.xml` 中的依赖声明正确无误。例如: ```xml <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-open-ai</artifactId> <version>0.16.0</version> <!-- 确保版本号正确 --> </dependency> ``` 如果版本号为 `unknown`,可能是版本被错误地设置为变量,但未在 `pom.xml` 中定义,或者项目未正确加载依赖信息。 ### 2. 使用 `exclusion` 排除冲突依赖 当多个依赖引入了相同库的不同版本时,Maven 会根据依赖调解规则选择一个版本。如果该版本不兼容,可以通过 `exclusion` 排除不需要的依赖版本,强制使用指定版本。例如: ```xml <dependency> <groupId>some.group</groupId> <artifactId>some-artifact</artifactId> <version>1.0.0</version> <exclusions> <exclusion> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-open-ai</artifactId> </exclusion> </exclusions> </dependency> ``` ### 3. 显式声明依赖版本 在 `pom.xml` 的 `dependencyManagement` 部分显式定义依赖版本,以确保所有子模块使用统一版本,避免冲突: ```xml <dependencyManagement> <dependencies> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-open-ai</artifactId> <version>0.16.0</version> </dependency> </dependencies> </dependencyManagement> ``` ### 4. 使用 `mvn dependency:tree` 分析依赖树 运行以下命令查看当前项目的依赖树,定位冲突来源: ```bash mvn dependency:tree ``` 通过分析输出,可以找到哪些依赖引入了冲突版本,并据此调整依赖声明或添加排除项。 ### 5. 发布依赖到本地或私有仓库 如果 `langchain4j-open-ai` 未发布到公共仓库,或者版本信息缺失,可手动将 JAR 包安装到本地仓库或私有仓库: ```bash mvn install:install-file -Dfile=langchain4j-open-ai.jar -DgroupId=dev.langchain4j -DartifactId=langchain4j-open-ai -Dversion=0.16.0 -Dpackaging=jar ``` 如果使用私有仓库,需配置 `distributionManagement` 并部署到远程仓库: ```xml <distributionManagement> <repository> <url>https://your-repo.com/repository/maven-releases/</url> </repository> </distributionManagement> ``` ### 6. 使用 `spring-boot-maven-plugin` 包含系统依赖 如果项目使用 Spring Boot 并需要包含系统作用域依赖,确保 `spring-boot-maven-plugin` 配置中包含 `includeSystemScope` 选项: ```xml <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <includeSystemScope>true</includeSystemScope> </configuration> </plugin> ``` ### 7. 清理和重新下载依赖 有时本地仓库中的依赖可能损坏或不完整,执行以下命令清理并重新下载依赖: ```bash mvn clean install -U ``` 其中 `-U` 参数会强制更新快照依赖。 ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值