大家好,我是锋哥。最近连载更新《基于LangChain的RAG与Agent智能体》技术专题。
本课程主要介绍和讲解RAG,LangChain简介,接入通义千万大模型,Ollama简介以及安装和使用,OpenAI库介绍和使用,以及最重要的基于LangChain实现RAG与Agent智能体开发技术。同时也配套视频教程 《2027版 基于LangChain的RAG与Agent智能体开发视频教程》
今天我们使用LangChain实现向量存储和相似性检索,为下一个RAG与Agent企业知识库项目实战做一些知识准备。
上图展示了基于 LangChain 实现的向量存储与相似性检索工作流,核心分为 *索引阶段(存储)和查询阶段(检索) 两部分:
- 索引阶段(存储):把文档变成向量并存库 输入:原始的 文档(Documents) 文本数据。 处理:通过嵌入模型(Embedding model),将文档文本转换为嵌入向量(Embedding vectors)—— 这是一种高维数值向量,用来编码文本的语义信息。 存储:生成的嵌入向量会被存入向量数据库(Vector stores),完成数据的索引与持久化。
- 查询阶段(检索):用问题去匹配最相似的文档 输入:用户的查询文本(Query text),也就是问题或检索需求。 处理:同样通过嵌入模型(Embedding model),将查询文本转换为查询向量(Query vector),保证和文档向量的编码规则一致。 匹配:执行相似性搜索(Similarity Search),将查询向量与向量数据库中所有文档向量做语义相似度计算。 输出:返回Top-k 结果(Top-k results),即与查询语义最相似的 k 条文档片段。 整体逻辑 这是 检索增强生成(RAG)的核心流程:先把知识库文档向量化存储,再在用户提问时将问题向量化,通过相似度匹配找到最相关的文档片段,为后续生成准确回答提供依据。
基于LangChain实现向量存储与检索
Chroma 是一个轻量级的开源向量数据库,专门用于存储和检索嵌入向量。它易于本地部署,支持内存模式和持久化存储,非常适合与 LangChain 结合构建基于检索的应用程序(如 RAG、语义搜索等)。
LangChain 提供了对 Chroma 的封装,通过 langchain_chroma 包可以方便地将 Chroma 作为向量存储(VectorStore)使用。本文将介绍其基本用法并给出完整的示例代码。
我们在LangChain中调用Chroma的话,要安装下依赖库 langchain_chroma
pip install langchain_chroma -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn
我们看一个langchain实现向量存储,删除,查询以及相似性搜索的实例:
from langchain_chroma import Chroma
from langchain_community.document_loaders import CSVLoader
from langchain_community.embeddings import DashScopeEmbeddings
# 创建 Chroma 向量数据库
chromadb = Chroma(
persist_directory="./chroma_db", # 持久化目录
embedding_function=DashScopeEmbeddings(), # 嵌入模型
collection_name="langchain_docs", # 指定集合名称,类似以前数据库的表名
)
# 创建CSV加载器
loader = CSVLoader(
file_path="../data/知识库.csv", # 文件路径
encoding="utf-8", # 文件编码
)
# 加载数据
documents = loader.load()
print(documents)
print(["id_" + str(doc.metadata["row"] + 1) for doc in documents])
# 添加文档到向量数据库
chromadb.add_documents(
documents=documents, # 文档列表
ids=["id_" + str(doc.metadata["row"] + 1) for doc in documents]
)
# # 查询所有文档
# docs = chromadb.get()
# print(docs)
#
# # 删除文档
# chromadb.delete(["id_1", "id_2"])
#
# # 查询所有文档
# docs = chromadb.get()
# print(docs)
# 查询
query = "什么是向量数据库?"
# 相似性搜索
result = chromadb.similarity_search(
query=query, # 查询内容
k=2, # 返回结果数量
filter={"source": "../data/知识库.csv"},
)
print(result)
运行结果:
[Document(metadata={'source': '../data/知识库.csv', 'row': 0}, page_content='知识信息: LangChain 是一个用于开发 LLM 应用的框架。'), Document(metadata={'source': '../data/知识库.csv', 'row': 1}, page_content='知识信息: Chroma 是一个开源的向量数据库。'), Document(metadata={'source': '../data/知识库.csv', 'row': 2}, page_content='知识信息: 向量存储可以将文本转换为向量并快速检索相似内容。')]
['id_1', 'id_2', 'id_3']
[Document(id='id_3', metadata={'row': 2, 'source': '../data/知识库.csv'}, page_content='知识信息: 向量存储可以将文本转换为向量并快速检索相似内容。'), Document(id='id_2', metadata={'row': 1, 'source': '../data/知识库.csv'}, page_content='知识信息: Chroma 是一个开源的向量数据库。')]
基于LangChain的RetrievalQA实现RAG增强检索
RAG(检索增强生成) 是一种将信息检索与语言生成相结合的技术架构。它的核心思想是:在让大语言模型(LLM)回答问题之前,先从外部知识库中检索与问题相关的信息,然后将这些信息作为“上下文”连同问题一起交给模型,从而生成更准确、更符合事实的答案。
RAG工作流程(三个核心步骤) :
- 检索(Retrieve) :将用户问题转换为向量,从向量数据库中检索最相似的文档片段
- 增强(Augment) :将检索到的文档片段与原始问题组合成一个增强的提示词
- 生成(Generate) :将增强后的提示词交给LLM,生成最终答案
我们使用RetrievalQA来实现RAG
RetrievalQA 是 LangChain 中专门用于构建检索增强生成(RAG) 问答系统的链。它通过将信息检索与大语言模型生成相结合,使模型能够基于外部知识库回答事实性问题,有效解决模型知识滞后和幻觉问题。
核心功能
-
输入:用户问题(
query) -
工作流程:
- 使用检索器从向量数据库或文档索引中获取与问题最相关的文档片段
- 将这些文档片段作为上下文,与原始问题一起组合成提示
- 将提示交给大语言模型,生成最终答案
-
输出:答案(
result),并可选择返回检索到的源文档(source_documents)
核心组件
| 组件 | 说明 |
|---|---|
| 检索器(Retriever) | 负责从文档存储中检索相关片段,如 VectorStoreRetriever |
| 大语言模型(LLM) | 负责生成答案,如 ChatOpenAI、ChatAnthropic 等 |
| 提示模板(Prompt) | 定义如何将上下文和问题组合成模型输入(可选,可使用默认模板) |
我们看下一个具体示例:
from langchain_chroma import Chroma
from langchain_classic.chains.retrieval_qa.base import RetrievalQA
from langchain_community.document_loaders import CSVLoader
from langchain_community.embeddings import DashScopeEmbeddings
from langchain_community.llms.tongyi import Tongyi
from langchain_core.prompts import PromptTemplate
# 创建 Chroma 向量数据库
chromadb = Chroma(
persist_directory="./chroma_db2", # 持久化目录
embedding_function=DashScopeEmbeddings(), # 嵌入模型
collection_name="langchain_rag", # 指定集合名称,类似以前数据库的表名
)
# 创建CSV加载器
loader = CSVLoader(
file_path="../data/知识库.csv", # 文件路径
encoding="utf-8", # 文件编码
)
# 加载数据
documents = loader.load()
print(documents)
print(["id_" + str(doc.metadata["row"] + 1) for doc in documents])
# 添加文档到向量数据库
chromadb.add_documents(
documents=documents, # 文档列表
ids=["id_" + str(doc.metadata["row"] + 1) for doc in documents]
)
# 设置检索器
retriever = chromadb.as_retriever(
search_kwargs={"k": 2} # 检索最相关的3个文档块
)
# 定义提示词模板
prompt_template = """基于以下已知信息,请回答用户的问题。
如果无法从已知信息中找到答案,请说"根据现有资料无法回答这个问题",不要编造。
已知信息:
{context}
问题:{question}
请回答:"""
prompt = PromptTemplate(
template=prompt_template,
input_variables=["context", "question"]
)
# 创建模型
model = Tongyi(model="qwen-plus")
# 创建检索式问答链
qa_chain = RetrievalQA.from_chain_type(
llm=model, # 模型
chain_type="stuff", # 将所有检索到的文档一次性放入上下文
retriever=retriever, # 检索器
chain_type_kwargs={"prompt": prompt},
return_source_documents=True # 返回来源文档,便于追溯
)
# 提问
def ask_question(query):
print(f"\n问题:{query}")
result = qa_chain.invoke({"query": query})
print(f"答案:{result['result']}")
print("参考来源:")
for doc in result['source_documents']:
print(f" - {doc.page_content[:50]}...")
return result
ask_question("什么是向量数据库?")
ask_question("什么是RAG?")
运行结果:
问题:什么是向量数据库?
答案:向量数据库是一种专门用于存储、索引和检索高维向量(如嵌入向量)的数据库系统。它支持基于向量相似度的高效语义搜索,例如查找与给定向量在语义上最接近的其他向量。Chroma 就是一个典型的向量数据库,用于存储和检索文本的嵌入向量。
参考来源:
- 知识信息: 嵌入向量是将文本转换为数字向量表示,用于语义搜索。...
- 知识信息: Chroma 是一个向量数据库,用于存储和检索文本向量。...
问题:什么是RAG?
答案:RAG 是一种结合检索和生成的技术,用于增强问答的准确性。
参考来源:
- 知识信息: RAG 是一种结合检索和生成的技术,用于增强问答的准确性。...
- 知识信息: LangChain 是一个框架,可以帮助你快速构建 LLM 应用。...