langchain_community.vectorstores.docarray.in_memory.DocArrayInMemorySearch
(以下简称 DocArrayInMemorySearch
)是 LangChain 框架中基于 DocArray 库实现的内存向量存储类,专为小型数据集和快速原型开发设计。它支持将文本文档转换为嵌入向量并存储在内存中,提供高效的相似性搜索功能,广泛应用于语义搜索、检索增强生成(RAG)和对话系统等场景。本文将从定义、核心功能、创建方法、应用场景、示例代码和注意事项等方面,系统讲解 DocArrayInMemorySearch
的功能与使用方法。
DocArrayInMemorySearch
?DocArrayInMemorySearch
是 LangChain 社区模块中的一个向量存储实现,基于 DocArray 库的内存索引功能。它通过在 RAM 中存储嵌入向量,支持快速的精确最近邻搜索(exact nearest-neighbor search)。与需要数据库服务器的持久化向量存储(如 Chroma、Pinecone)不同,DocArrayInMemorySearch
完全运行在内存中,适合临时或小型数据处理。
核心功能:
VectorStore
接口的实现,与框架的其他组件无缝集成。设计目标:
DocArrayInMemorySearch
?在 LLM 应用中,向量存储用于将文本转换为嵌入向量并进行相似性搜索,以支持语义检索和上下文增强。DocArrayInMemorySearch
的优势在于:
从官方文档来看,它特别适合处理数百到数千条记录的小型数据集,例如在开发初期测试 RAG 系统或语义搜索功能。
DocArrayInMemorySearch
提供了一系列功能,使其成为小型向量存储的理想选择。以下是其核心特性和方法的详细说明:
Embeddings
接口的嵌入模型,用于将文本转换为向量。OpenAIEmbeddings
:基于 OpenAI 的文本嵌入模型。HuggingFaceEmbeddings
:基于 Hugging Face 的开源模型。SentenceTransformerEmbeddings
:用于生成高质量句子嵌入。langchain_core.documents.Document
对象,包含文本内容(page_content
)和元数据(metadata
)。similarity_search
)和异步方法(如 asimilarity_search
),支持并发操作。as_retriever()
方法转换为 LangChain 的 VectorStoreRetriever
,用于链式操作或代理系统。以下是 DocArrayInMemorySearch
的主要方法及其功能:
方法 | 描述 | 参数示例 | 返回值 | 备注 |
---|---|---|---|---|
from_documents(documents, embeddings) |
从文档和嵌入模型初始化向量存储 | documents : List[Document], embeddings : Embeddings |
DocArrayInMemorySearch 实例 |
常用于初始化文档集合 |
from_texts(texts, embeddings, metadatas) |
从文本列表和嵌入模型初始化向量存储 | texts : List[str], embeddings : Embeddings, metadatas : List[dict] |
DocArrayInMemorySearch 实例 |
适合快速测试文本数据 |
add_documents(documents) |
添加新文档到存储 | documents : List[Document] |
List[str](文档 ID) | 支持动态扩展存储 |
add_texts(texts, metadatas) |
添加新文本到存储 | texts : List[str], metadatas : List[dict] |
List[str](文本 ID) | - |
similarity_search(query, k=4) |
根据查询字符串搜索最相似的 k 个文档 |
query : str, k : int |
List[Document] | 默认返回 4 个结果 |
similarity_search_with_score(query, k=4) |
搜索并返回文档及相似性分数 | query : str, k : int |
List[Tuple[Document, float]] | 分数范围通常为 0-1(余弦相似性) |
max_marginal_relevance_search(query, k=4, lambda_mult=0.5) |
MMR 搜索,优化相关性和多样性 | query : str, k : int, lambda_mult : float |
List[Document] | lambda_mult 控制相关性与多样性平衡 |
get_by_ids(ids) |
根据 ID 获取文档 | ids : List[str] |
List[Document] | 从版本 0.2.11 起支持,ID 不存在时不抛异常 |
delete(ids) |
根据 ID 删除文档 | ids : List[str] |
bool/None | 删除后内存可能需要手动释放 |
as_retriever() |
将向量存储转换为检索器 | - | VectorStoreRetriever 实例 |
用于链式操作或代理系统 |
创建和使用 DocArrayInMemorySearch
的典型流程包括以下步骤:
准备数据:
TextLoader
)加载原始数据。CharacterTextSplitter
)将长文档分割为小块,生成 Document
对象列表。选择嵌入模型:
OpenAIEmbeddings
),用于将文本转换为向量。初始化向量存储:
from_documents
或 from_texts
方法创建 DocArrayInMemorySearch
实例。执行搜索:
similarity_search
或 max_marginal_relevance_search
方法检索相关文档。以下是一个完整的示例,展示如何加载文档、初始化向量存储并进行相似性搜索:
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import CharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import DocArrayInMemorySearch
from langchain_core.documents import Document
# 1. 准备文档(示例使用手动创建的 Document)
documents = [
Document(page_content="巴黎是法国的首都,位于塞纳河畔。", metadata={"source": "wiki_paris"}),
Document(page_content="伦敦是英国的首都,以大本钟闻名。", metadata={"source": "wiki_london"}),
Document(page_content="东京是日本的首都,人口众多。", metadata={"source": "wiki_tokyo"})
]
# 2. 初始化嵌入模型
embeddings = OpenAIEmbeddings()
# 3. 创建向量存储
db = DocArrayInMemorySearch.from_documents(documents, embeddings)
# 4. 执行相似性搜索
query = "法国的首都是哪里?"
results = db.similarity_search(query, k=2)
# 5. 输出结果
for doc in results:
print(f"内容: {doc.page_content}")
print(f"元数据: {doc.metadata}")
输出示例:
内容: 巴黎是法国的首都,位于塞纳河畔。
元数据: {'source': 'wiki_paris'}
内容: 伦敦是英国的首都,以大本钟闻名。
元数据: {'source': 'wiki_london'}
如果没有 Document
对象,可以直接使用文本列表:
texts = [
"Python 是一种简单易学的编程语言。",
"LangChain 是一个用于构建 LLM 应用的框架。",
"DocArray 是一个多模态数据处理库。"
]
metadatas = [
{"category": "programming"},
{"category": "AI"},
{"category": "library"}
]
db = DocArrayInMemorySearch.from_texts(texts, embeddings, metadatas=metadatas)
results = db.similarity_search("LLM 框架是什么?", k=1)
print(results[0].page_content)
输出:
LangChain 是一个用于构建 LLM 应用的框架。
DocArrayInMemorySearch
在 LangChain 的多种场景中表现出色,以下是其主要应用场景:
以下是一个结合 RAG 的完整示例,展示 DocArrayInMemorySearch
在问答系统中的应用:
from langchain_core.documents import Document
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_community.vectorstores import DocArrayInMemorySearch
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
# 1. 准备文档
documents = [
Document(page_content="巴黎是法国的首都,人口约220万,位于塞纳河畔。", metadata={"source": "wiki"}),
Document(page_content="伦敦是英国的首都,拥有大本钟和伦敦眼。", metadata={"source": "wiki"}),
]
# 2. 初始化嵌入和向量存储
embeddings = OpenAIEmbeddings()
db = DocArrayInMemorySearch.from_documents(documents, embeddings)
# 3. 创建检索器
retriever = db.as_retriever(search_kwargs={"k": 1})
# 4. 定义提示模板
template = ChatPromptTemplate.from_messages([
("system", "根据以下上下文回答问题:\n{context}"),
("human", "{question}")
])
# 5. 创建 RAG 链
model = ChatOpenAI(model="gpt-4o")
chain = (
{"context": retriever, "question": RunnablePassthrough()}
| template
| model
)
# 6. 执行查询
response = chain.invoke("巴黎有多少人口?")
print(response.content)
输出示例:
巴黎的人口大约为220万。
数据规模:
嵌入模型选择:
搜索优化:
max_marginal_relevance_search
提高结果多样性,适合需要多角度信息的场景。k
参数,控制返回结果数量,避免过多无关文档。元数据管理:
source
、category
),便于后续过滤和分析。持久化需求:
版本兼容性:
pip install docarray
。错误处理:
langchain_community.vectorstores.docarray.in_memory.DocArrayInMemorySearch
是 LangChain 框架中一个轻量级的内存向量存储实现,基于 DocArray 库,提供快速的嵌入存储和相似性搜索功能。它适合小型数据集、快速原型开发和学习场景,通过简单的 API 支持文档管理、动态更新和多种搜索方式。尽管受内存限制和非持久化的约束,它在开发初期或临时任务中表现出色,与 LangChain 的链、代理和检索器无缝集成。
通过理解其功能、创建方法和应用场景,开发者可以高效利用 DocArrayInMemorySearch
构建语义搜索、RAG 系统和对话应用。对于需要扩展到大规模数据的场景,建议迁移到持久化向量存储。
参考资源: