集成:Neo4j
将 Neo4j 数据库与 Haystack 一起使用
目录
概述
这是一个集成 Neo4j 图数据库与 Haystack v2.0 由 deepset 开发。在 Neo4j 中,向量搜索索引用于存储文档嵌入和进行稠密检索。
该库允许使用 Neo4j 作为 DocumentStore,并实现了必需的 协议 方法。你可以通过从 neo4j_haystack 包导入来开始使用该实现。
from neo4j_haystack import Neo4jDocumentStore
除了 Neo4jDocumentStore,该库还包含以下 Haystack 组件,它们可以在管道中使用。
-
Neo4jEmbeddingRetriever - 一个典型的 检索器组件,可用于查询向量存储索引并查找相关文档。该组件使用
Neo4jDocumentStore来查询嵌入。 -
Neo4jDynamicDocumentRetriever 也是一个检索器组件,因为它可用于查询 Neo4j 中的文档。然而,它与
Neo4jDocumentStore解耦,并允许运行任意 Cypher 查询 来提取文档。实际上,可以像Neo4jDocumentStore一样查询 Neo4j,包括向量搜索。
neo4j-haystack 库使用 Python 驱动程序 和 Cypher 查询 来与 Neo4j 数据库交互,并将所有复杂性隐藏在底层。
Neo4jDocumentStore 将文档存储为 Neo4j 中的图节点。嵌入作为节点的一部分存储,但使用 ANN 进行向量嵌入的索引和查询由专门的 向量索引 管理。
+-----------------------------+
| Neo4j Database |
+-----------------------------+
| |
| +----------------+ |
| | Document | |
write_documents | +----------------+ |
+------------------------+----->| properties | |
| | | | |
+---------+----------+ | | embedding | |
| | | +--------+-------+ |
| Neo4jDocumentStore | | | |
| | | |index/query |
+---------+----------+ | | |
| | +--------+--------+ |
| | | Vector Index | |
+----------------------->| | | |
query_embeddings | | (for embedding) | |
| +-----------------+ |
| |
+-----------------------------+
在上图中
Document是一个 Neo4j 节点(带有“Document”标签)。properties是作为节点一部分存储的文档 属性。embedding也是文档节点的属性(在图中为了清晰而单独显示),它是一个类型为LIST[FLOAT]的向量。Vector Index是 Neo4j 在文档节点更新后对其进行索引的地方。
安装
neo4j-haystack 可以像其他 Python 库一样使用 pip 安装。
pip install --upgrade pip # optional
pip install sentence-transformers # required in order to run pipeline examples given below
pip install neo4j-haystack
使用
安装后,你可以像使用其他支持嵌入的文档存储一样开始使用 Neo4jDocumentStore。
from neo4j_haystack import Neo4jDocumentStore
document_store = Neo4jDocumentStore(
url="bolt://:7687",
username="neo4j",
password="passw0rd",
database="neo4j",
embedding_dim=384,
embedding_field="embedding",
index="document-embeddings", # The name of the Vector Index in Neo4j
node_label="Document", # Providing a label to Neo4j nodes which store Documents
)
假设有一系列文档可用,你可以将它们写入/索引到 Neo4j,例如:
documents: List[Document] = ...
document_store.write_documents(documents)
Neo4jDocumentStore 接受的参数的完整列表可以在 API 文档 中找到。
请注意,你需要有一个正在运行的 Neo4j 数据库实例(不支持内存版 Neo4j)。有几种选项可用:
- Docker,在同一操作手册中还有其他选项。
- AuraDB - Neo4j 的完全托管云实例。
- Neo4j Desktop 客户端应用程序。
最简单的在本地启动数据库的方法是使用 Docker 容器。
docker run \
--restart always \
--publish=7474:7474 --publish=7687:7687 \
--env NEO4J_AUTH=neo4j/passw0rd \
neo4j:5.15.0
检索文档
Neo4jEmbeddingRetriever 组件可用于通过查询嵌入来从 Neo4j 检索文档。下面是一个管道,它使用查询嵌入和 元数据过滤 来查找文档。
from typing import List
from haystack import Document, Pipeline
from haystack.components.embedders import SentenceTransformersTextEmbedder, SentenceTransformersDocumentEmbedder
from neo4j_haystack import Neo4jEmbeddingRetriever, Neo4jDocumentStore
document_store = Neo4jDocumentStore(
url="bolt://:7687",
username="neo4j",
password="passw0rd",
database="neo4j",
embedding_dim=384,
index="document-embeddings",
)
documents = [
Document(content="My name is Morgan and I live in Paris.", meta={"release_date": "2018-12-09"})]
document_embedder = SentenceTransformersDocumentEmbedder(model="sentence-transformers/all-MiniLM-L6-v2")
document_embedder.warm_up()
documents_with_embeddings = document_embedder.run(documents)
document_store.write_documents(documents_with_embeddings.get("documents"))
print(document_store.count_documents())
pipeline = Pipeline()
pipeline.add_component("text_embedder", SentenceTransformersTextEmbedder(model="sentence-transformers/all-MiniLM-L6-v2"))
pipeline.add_component("retriever", Neo4jEmbeddingRetriever(document_store=document_store))
pipeline.connect("text_embedder.embedding", "retriever.query_embedding")
result = pipeline.run(
data={
"text_embedder": {"text": "What cities do people live in?"},
"retriever": {
"top_k": 5,
"filters": {"field": "release_date", "operator": "==", "value": "2018-12-09"},
},
}
)
documents: List[Document] = result["retriever"]["documents"]
>>> output:
`[Document(id=e765764ab700b231db1eeae208d6a59047b4b93712d1a9e379ae9599128ffdbd, content: 'My name is Morgan and I live in Paris.', meta: {'release_date': '2018-12-09'}, score: 0.8416308164596558)]`
使用 Cypher 检索文档
Neo4jDynamicDocumentRetriever 是一个灵活的检索器组件,它可以运行 Cypher 查询来获取文档。上面 Neo4jEmbeddingRetriever 的示例可以在不使用 Neo4jDocumentStore 的情况下重写。
from haystack import Document, Pipeline
from haystack.components.embedders import SentenceTransformersTextEmbedder
from neo4j_haystack import Neo4jClientConfig, Neo4jDynamicDocumentRetriever
client_config = Neo4jClientConfig(
url="bolt://:7687",
username="neo4j",
password="passw0rd",
database="neo4j",
)
cypher_query = """
CALL db.index.vector.queryNodes($index, $top_k, $query_embedding)
YIELD node as doc, score
MATCH (doc) WHERE doc.release_date = $release_date
RETURN doc{.*, score}, score
ORDER BY score DESC LIMIT $top_k
"""
embedder = SentenceTransformersTextEmbedder(model="sentence-transformers/all-MiniLM-L6-v2")
retriever = Neo4jDynamicDocumentRetriever(
client_config=client_config, runtime_parameters=["query_embedding"], doc_node_name="doc"
)
pipeline = Pipeline()
pipeline.add_component("text_embedder", embedder)
pipeline.add_component("retriever", retriever)
pipeline.connect("text_embedder.embedding", "retriever.query_embedding")
result = pipeline.run(
data={
"text_embedder": {"text": "What cities do people live in?"},
"retriever": {
"query": cypher_query,
"parameters": {"index": "document-embeddings", "top_k": 5, "release_date": "2018-12-09"},
},
}
)
documents: List[Document] = result["retriever"]["documents"]
请注意,查询参数如何在 cypher_query 中使用。
runtime_parameters是参数名称的列表,在管道中连接组件时,它们将成为输入槽。在我们的例子中,query_embedding输入连接到text_embedder.embedding输出。pipeline.run指定了retriever组件的其他参数,这些参数可以在cypher_query中引用,例如top_k。
更多示例
你可以在实现 存储库 中找到更多示例。
- indexing_pipeline.py - 索引来自远程 http 位置的文本文件(文档)。
-
rag_pipeline.py - 生成式问答 RAG 管道,使用
Neo4jEmbeddingRetriever从 Neo4j 文档存储中获取文档,并使用 HuggingFaceTGIGenerator 回答问题。 -
rag_pipeline_cypher.py - 与
rag_pipeline.py相同,但使用Neo4jDynamicDocumentRetriever。
你可能在 代码参考 文档中找到更多技术细节。例如,在实际场景中,可能需要调整到 Neo4j 数据库的连接设置(例如,请求超时)。Neo4jDocumentStore 使用 Neo4jClientConfig 类接受扩展的客户端配置。
许可证
neo4j-haystack 在 MIT 许可证下分发。
