> ## Documentation Index
> Fetch the complete documentation index at: https://langchain-docs-zh.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Memgraph 集成

> 使用 LangChain Python 集成 Memgraph。

Memgraph 是一个开源的图数据库，专为动态分析环境设计，并与 Neo4j 兼容。要查询数据库，Memgraph 使用 Cypher——这是最广泛采用、完整定义且开放的属性图数据库查询语言。

本笔记本将向您展示如何 [使用自然语言查询 Memgraph](#自然语言查询) 以及如何 [从您的非结构化数据构建知识图谱](#构建知识图谱)。

首先，确保您已 [完成所有设置](#设置)。

## 设置

要学习本指南，您需要 [安装 Docker](https://www.docker.com/get-started/) 和 [Python 3.x](https://www.python.org/)。

要快速首次运行 **Memgraph 平台**（Memgraph 数据库 + MAGE 库 + Memgraph Lab），请执行以下操作：

在 Linux/MacOS 上：

```
curl https://install.memgraph.com | sh
```

在 Windows 上：

```
iwr https://windows.memgraph.com | iex
```

这两个命令运行一个脚本，将 Docker Compose 文件下载到您的系统，并在两个独立的容器中构建和启动 `memgraph-mage` 和 `memgraph-lab` Docker 服务。现在您已成功运行 Memgraph！有关安装过程的更多信息，请参阅 [Memgraph 文档](https://memgraph.com/docs/getting-started/install-memgraph)。

要使用 LangChain，请安装并导入所有必要的包。我们将使用包管理器 [pip](https://pip.pypa.io/en/stable/installation/)，并结合 `--user` 标志，以确保适当的权限。如果您已安装 Python 3.4 或更高版本，`pip` 会默认包含。您可以使用以下命令安装所有必需的包：

```
pip install langchain langchain-openai langchain-memgraph --user
```

您可以在本笔记本中运行提供的代码块，或使用单独的 Python 文件来实验 Memgraph 和 LangChain。

## 自然语言查询

Memgraph 与 LangChain 的集成包括自然语言查询。要使用它，首先执行所有必要的导入。我们将在代码中讨论它们。

首先，实例化 `MemgraphGraph`。该对象包含对正在运行的 Memgraph 实例的连接。请确保正确设置所有环境变量。

```python theme={null}
import os

from langchain_core.prompts import PromptTemplate
from langchain_memgraph.chains.graph_qa import MemgraphQAChain
from langchain_memgraph.graphs.memgraph import MemgraphLangChain
from langchain_openai import ChatOpenAI

url = os.environ.get("MEMGRAPH_URI", "bolt://localhost:7687")
username = os.environ.get("MEMGRAPH_USERNAME", "")
password = os.environ.get("MEMGRAPH_PASSWORD", "")

graph = MemgraphLangChain(
    url=url, username=username, password=password, refresh_schema=False
)
```

`refresh_schema` 初始设置为 `False`，因为数据库中还没有数据，我们希望避免不必要的数据库调用。

### 填充数据库

要填充数据库，首先确保它是空的。最有效的方法是切换到内存分析存储模式，删除图，然后返回内存事务模式。有关 Memgraph 的 [存储模式](https://memgraph.com/docs/fundamentals/storage-memory-usage#storage-modes) 的更多信息。

我们将添加到数据库的数据是关于不同类型的视频游戏，这些游戏在各种平台上可用，并与发行商相关。

```python theme={null}
# Drop graph
graph.query("STORAGE MODE IN_MEMORY_ANALYTICAL")
graph.query("DROP GRAPH")
graph.query("STORAGE MODE IN_MEMORY_TRANSACTIONAL")

# Creating and executing the seeding query
query = """
    MERGE (g:Game {name: "Baldur's Gate 3"})
    WITH g, ["PlayStation 5", "Mac OS", "Windows", "Xbox Series X/S"] AS platforms,
            ["Adventure", "Role-Playing Game", "Strategy"] AS genres
    FOREACH (platform IN platforms |
        MERGE (p:Platform {name: platform})
        MERGE (g)-[:AVAILABLE_ON]->(p)
    )
    FOREACH (genre IN genres |
        MERGE (gn:Genre {name: genre})
        MERGE (g)-[:HAS_GENRE]->(gn)
    )
    MERGE (p:Publisher {name: "Larian Studios"})
    MERGE (g)-[:PUBLISHED_BY]->(p);
"""

graph.query(query)
```

```text theme={null}
[]
```

注意 `graph` 对象包含 `query` 方法。该方法在 Memgraph 中执行查询，并且也由 `MemgraphQAChain` 使用来查询数据库。

### 刷新图模式

由于新数据是在 Memgraph 中创建的，因此需要刷新模式。生成的模式将用于 `MemgraphQAChain`，以指导 LLM 更好地生成 Cypher 查询。

```python theme={null}
graph.refresh_schema()
```

要熟悉数据并验证更新的图模式，您可以使用以下语句打印它：

```python theme={null}
print(graph.get_schema)
```

```text theme={null}
Node labels and properties (name and type) are:
- labels: (:Platform)
  properties:
    - name: string
- labels: (:Genre)
  properties:
    - name: string
- labels: (:Game)
  properties:
    - name: string
- labels: (:Publisher)
  properties:
    - name: string

Nodes are connected with the following relationships:
(:Game)-[:HAS_GENRE]->(:Genre)
(:Game)-[:PUBLISHED_BY]->(:Publisher)
(:Game)-[:AVAILABLE_ON]->(:Platform)
```

### 查询数据库

要与 OpenAI API 交互，您必须在环境变量中配置您的 API 密钥。这确保了您的请求具有适当的授权。有关获取 API 密钥的更多信息，请参阅 [OpenAI 帮助中心](https://help.openai.com/en/articles/4936850-where-do-i-find-my-secret-api-key)。要配置 API 密钥，您可以使用 Python [os](https://docs.python.org/3/library/os.html) 包：

```
os.environ["OPENAI_API_KEY"] = "your-key-here"
```

如果您在 Jupyter 笔记本中运行代码，请运行上述代码片段。

接下来，创建 `MemgraphQAChain`，它将用于基于您的图数据执行问答过程。`temperature parameter` 设置为零，以确保可预测和一致的答案。您可以将 `verbose` 参数设置为 `True`，以接收有关查询生成的更详细的消息。

```python theme={null}
chain = MemgraphQAChain.from_llm(
    ChatOpenAI(temperature=0, model="gpt-4o"),
    graph=graph,
    allow_dangerous_requests=True,
)
```

现在您可以开始提问了！

```python theme={null}
response = chain.invoke("Which platforms is Baldur's Gate 3 available on?")
print(response["result"])
```

```text theme={null}
MATCH (:Game{name: "Baldur's Gate 3"})-[:AVAILABLE_ON]->(platform:Platform)
RETURN platform.name
Baldur's Gate 3 is available on PlayStation 5, Mac OS, Windows, and Xbox Series X/S.
```

```python theme={null}
response = chain.invoke("Is Baldur's Gate 3 available on Windows?")
print(response["result"])
```

```text theme={null}
MATCH (:Game{name: "Baldur's Gate 3"})-[:AVAILABLE_ON]->(:Platform{name: "Windows"})
RETURN "Yes"
Yes, Baldur's Gate 3 is available on Windows.
```

### 链修饰符

要修改链的行为并获取更多上下文或附加信息，您可以修改链的参数。

#### 返回直接查询结果

`return_direct` 修饰符指定是否返回执行的 Cypher 查询的直接结果或处理的自然语言响应。

```python theme={null}
# Return the result of querying the graph directly
chain = MemgraphQAChain.from_llm(
    ChatOpenAI(temperature=0, model="gpt-4o"),
    graph=graph,
    return_direct=True,
    allow_dangerous_requests=True,
)

response = chain.invoke("Which studio published Baldur's Gate 3?")
print(response["result"])
```

```text theme={null}
MATCH (g:Game {name: "Baldur's Gate 3"})-[:PUBLISHED_BY]->(p:Publisher)
RETURN p.name
[{'p.name': 'Larian Studios'}]
```

#### 返回查询中间步骤

`return_intermediate_steps` 链修饰符通过包含查询的中间步骤来增强返回的响应，除了初始查询结果。

```python theme={null}
# Return all the intermediate steps of query execution
chain = MemgraphQAChain.from_llm(
    ChatOpenAI(temperature=0, model="gpt-4o"),
    graph=graph,
    allow_dangerous_requests=True,
    return_intermediate_steps=True,
)

response = chain.invoke("Is Baldur's Gate 3 an Adventure game?")
print(f"Intermediate steps: {response['intermediate_steps']}")
print(f"Final response: {response['result']}")
```

```text theme={null}
MATCH (:Game {name: "Baldur's Gate 3"})-[:HAS_GENRE]->(:Genre {name: "Adventure"})
RETURN "Yes"
Intermediate steps: [{'query': 'MATCH (:Game {name: "Baldur\'s Gate 3"})-[:HAS_GENRE]->(:Genre {name: "Adventure"})\nRETURN "Yes"'}, {'context': [{'"Yes"': 'Yes'}]}]
Final response: Yes.
```

#### 限制查询结果数量

`top_k` 修饰符可以在您希望限制查询结果最大数量时使用。

```python theme={null}
# Limit the maximum number of results returned by query
chain = MemgraphQAChain.from_llm(
    ChatOpenAI(temperature=0, model="gpt-4o"),
    graph=graph,
    top_k=2,
    allow_dangerous_requests=True,
)

response = chain.invoke("What genres are associated with Baldur's Gate 3?")
print(response["result"])
```

```text theme={null}
MATCH (:Game {name: "Baldur's Gate 3"})-[:HAS_GENRE]->(g:Genre)
RETURN g.name;
Adventure, Role-Playing Game
```

### 高级查询

随着您的解决方案复杂性的增加，您可能会遇到需要仔细处理的不同用例。确保应用程序的可扩展性对于在没有任何问题的情况下保持平滑的用户流程至关重要。

让我们再次实例化我们的链，并尝试提出一些用户可能会提出的问题。

```python theme={null}
chain = MemgraphQAChain.from_llm(
    ChatOpenAI(temperature=0, model="gpt-4o"),
    graph=graph,
    allow_dangerous_requests=True,
)

response = chain.invoke("Is Baldur's Gate 3 available on PS5?")
print(response["result"])
```

```text theme={null}
MATCH (:Game{name: "Baldur's Gate 3"})-[:AVAILABLE_ON]->(:Platform{name: "PS5"})
RETURN "Yes"
I don't know the answer.
```

生成的 Cypher 查询看起来很好，但我们没有收到任何信息。这说明了在使用 LLM 时的一个常见挑战——用户提问方式与数据存储方式之间的不匹配。在这种情况下，用户感知与实际数据存储之间的差异会导致不匹配。提示词优化，即磨练模型的提示词以更好地理解这些差异，是解决此问题的有效方法。通过提示词优化，模型在生成精确和相关的查询方面的能力得到提升，从而成功检索到所需数据。

#### 提示词优化

为此，我们可以调整问答链的初始 Cypher 提示词。这涉及向 LLM 添加指导，说明用户如何引用特定平台，例如我们案例中的 PS5。我们使用 LangChain PromptTemplate 创建修改后的初始提示词，然后将修改后的提示词作为参数传递给优化后的 `MemgraphQAChain` 实例。

```python theme={null}
MEMGRAPH_GENERATION_TEMPLATE = """Your task is to directly translate natural language inquiry into precise and executable Cypher query for Memgraph database.
You will utilize a provided database schema to understand the structure, nodes and relationships within the Memgraph database.
Instructions:
- Use provided node and relationship labels and property names from the
schema which describes the database's structure. Upon receiving a user
question, synthesize the schema to craft a precise Cypher query that
directly corresponds to the user's intent.
- Generate valid executable Cypher queries on top of Memgraph database.
Any explanation, context, or additional information that is not a part
of the Cypher query syntax should be omitted entirely.
- Use Memgraph MAGE procedures instead of Neo4j APOC procedures.
- Do not include any explanations or apologies in your responses.
- Do not include any text except the generated Cypher statement.
- For queries that ask for information or functionalities outside the direct
generation of Cypher queries, use the Cypher query format to communicate
limitations or capabilities. For example: RETURN "I am designed to generate
Cypher queries based on the provided schema only."
Schema:
{schema}

With all the above information and instructions, generate Cypher query for the
user question.
If the user asks about PS5, Play Station 5 or PS 5, that is the platform called PlayStation 5.

The question is:
{question}"""

MEMGRAPH_GENERATION_PROMPT = PromptTemplate(
    input_variables=["schema", "question"], template=MEMGRAPH_GENERATION_TEMPLATE
)

chain = MemgraphQAChain.from_llm(
    ChatOpenAI(temperature=0, model="gpt-4o"),
    cypher_prompt=MEMGRAPH_GENERATION_PROMPT,
    graph=graph,
    allow_dangerous_requests=True,
)

response = chain.invoke("Is Baldur's Gate 3 available on PS5?")
print(response["result"])
```

```text theme={null}
MATCH (:Game{name: "Baldur's Gate 3"})-[:AVAILABLE_ON]->(:Platform{name: "PlayStation 5"})
RETURN "Yes"
Yes, Baldur's Gate 3 is available on PS5.
```

现在，由于初始 Cypher 提示词中包含了关于平台命名的指导，我们正在获得准确且相关的结果，这些结果与用户查询更加一致。

这种方法允许进一步改进您的 QA 链。您可以轻松地将额外的提示词优化数据集成到您的链中，从而提升您应用程序的整体用户体验。

## 构建知识图谱

将非结构化数据转换为结构化数据并非易事或直接的任务。本指南将展示如何利用大型语言模型（LLM）来帮助我们完成这项任务，以及如何在 Memgraph 中构建知识图谱。创建知识图谱后，您可以使用它来构建您的 GraphRAG 应用程序。

从文本构建知识图谱的步骤如下：

* [从文本中提取结构化信息](#从文本中提取结构化信息)：使用 LLM 从文本中以节点和关系的形式提取结构化图信息。
* [存储到 Memgraph](#存储到-memgraph)：将提取的结构化图信息存储到 Memgraph。

### 从文本中提取结构化信息

除了在 [设置部分](#设置)中所有导入的模块，还需要导入 `LLMGraphTransformer` 和 @\[`Document`]，它们将用于从文本中提取结构化信息。

> [!WARNING]
>
> `langchain-experimental` 包已不再维护。从 `langchain_experimental` 导入的示例可能过时或已损坏，请谨慎使用。

```python theme={null}
from langchain_core.documents import Document
from langchain_neo4j import LLMGraphTransformer
```

以下是关于查尔斯·达尔文（[来源](https://en.wikipedia.org/wiki/Charles_Darwin)）的示例文本，知识图谱将基于该文本构建。

```python theme={null}
text = """
    Charles Robert Darwin was an English naturalist, geologist, and biologist,
    widely known for his contributions to evolutionary biology. His proposition that
    all species of life have descended from a common ancestor is now generally
    accepted and considered a fundamental scientific concept. In a joint
    publication with Alfred Russel Wallace, he introduced his scientific theory that
    this branching pattern of evolution resulted from a process he called natural
    selection, in which the struggle for existence has a similar effect to the
    artificial selection involved in selective breeding. Darwin has been
    described as one of the most influential figures in human history and was
    honoured by burial in Westminster Abbey.
"""
```

下一步是从所需的 LLM 初始化 `LLMGraphTransformer`，并将文档转换为图结构。

```python theme={null}
llm = ChatOpenAI(temperature=0, model="gpt-4o")
llm_transformer = LLMGraphTransformer(llm=llm)
documents = [Document(page_content=text)]
graph_documents = llm_transformer.convert_to_graph_documents(documents)
```

在底层，LLM 从文本中提取重要实体，并将它们作为节点和关系的列表返回。它看起来是这样的：

```python theme={null}
print(graph_documents)
```

```text theme={null}
[GraphDocument(nodes=[Node(id='Charles Robert Darwin', type='Person', properties={}), Node(id='English', type='Nationality', properties={}), Node(id='Naturalist', type='Profession', properties={}), Node(id='Geologist', type='Profession', properties={}), Node(id='Biologist', type='Profession', properties={}), Node(id='Evolutionary Biology', type='Field', properties={}), Node(id='Common Ancestor', type='Concept', properties={}), Node(id='Scientific Concept', type='Concept', properties={}), Node(id='Alfred Russel Wallace', type='Person', properties={}), Node(id='Natural Selection', type='Concept', properties={}), Node(id='Selective Breeding', type='Concept', properties={}), Node(id='Westminster Abbey', type='Location', properties={})], relationships=[Relationship(source=Node(id='Charles Robert Darwin', type='Person', properties={}), target=Node(id='English', type='Nationality', properties={}), type='NATIONALITY', properties={}), Relationship(source=Node(id='Charles Robert Darwin', type='Person', properties={}), target=Node(id='Naturalist', type='Profession', properties={}), type='PROFESSION', properties={}), Relationship(source=Node(id='Charles Robert Darwin', type='Person', properties={}), target=Node(id='Geologist', type='Profession', properties={}), type='PROFESSION', properties={}), Relationship(source=Node(id='Charles Robert Darwin', type='Person', properties={}), target=Node(id='Biologist', type='Profession', properties={}), type='PROFESSION', properties={}), Relationship(source=Node(id='Charles Robert Darwin', type='Person', properties={}), target=Node(id='Evolutionary Biology', type='Field', properties={}), type='CONTRIBUTION', properties={}), Relationship(source=Node(id='Common Ancestor', type='Concept', properties={}), target=Node(id='Scientific Concept', type='Concept', properties={}), type='BASIS', properties={}), Relationship(source=Node(id='Charles Robert Darwin', type='Person', properties={}), target=Node(id='Alfred Russel Wallace', type='Person', properties={}), type='COLLABORATION', properties={}), Relationship(source=Node(id='Natural Selection', type='Concept', properties={}), target=Node(id='Selective Breeding', type='Concept', properties={}), type='COMPARISON', properties={}), Relationship(source=Node(id='Charles Robert Darwin', type='Person', properties={}), target=Node(id='Westminster Abbey', type='Location', properties={}), type='BURIAL', properties={})], source=Document(metadata={}, page_content='\n    Charles Robert Darwin was an English naturalist, geologist, and biologist,\n    widely known for his contributions to evolutionary biology. His proposition that\n    all species of life have descended from a common ancestor is now generally\n    accepted and considered a fundamental scientific concept. In a joint\n    publication with Alfred Russel Wallace, he introduced his scientific theory that\n    this branching pattern of evolution resulted from a process he called natural\n    selection, in which the struggle for existence has a similar effect to the\n    artificial selection involved in selective breeding. Darwin has been\n    described as one of the most influential figures in human history and was\n    honoured by burial in Westminster Abbey.\n'))]
```

### 存储到 Memgraph

一旦您将数据准备好，格式为 `GraphDocument`，即节点和关系，您可以使用 `add_graph_documents` 方法将其导入 Memgraph。该方法将 `graph_documents` 的列表转换为 Memgraph 需要执行的适当 Cypher 查询。完成后，知识图谱将存储在 Memgraph 中。

```python theme={null}
# Empty the database
graph.query("STORAGE MODE IN_MEMORY_ANALYTICAL")
graph.query("DROP GRAPH")
graph.query("STORAGE MODE IN_MEMORY_TRANSACTIONAL")

# Create KG
graph.add_graph_documents(graph_documents)
```

> [!NOTE]
>
> 图构建过程是非确定性的，因为用于从非结构化数据生成节点和关系的 LLM 本身是非确定性的。

### 其他选项

此外，您可以根据需求灵活定义要提取的特定类型的节点和关系。

```python theme={null}
llm_transformer_filtered = LLMGraphTransformer(
    llm=llm,
    allowed_nodes=["Person", "Nationality", "Concept"],
    allowed_relationships=["NATIONALITY", "INVOLVED_IN", "COLLABORATES_WITH"],
)
graph_documents_filtered = llm_transformer_filtered.convert_to_graph_documents(
    documents
)

print(f"Nodes:{graph_documents_filtered[0].nodes}")
print(f"Relationships:{graph_documents_filtered[0].relationships}")
```

```text theme={null}
Nodes:[Node(id='Charles Robert Darwin', type='Person', properties={}), Node(id='English', type='Nationality', properties={}), Node(id='Evolutionary Biology', type='Concept', properties={}), Node(id='Natural Selection', type='Concept', properties={}), Node(id='Alfred Russel Wallace', type='Person', properties={})]
Relationships:[Relationship(source=Node(id='Charles Robert Darwin', type='Person', properties={}), target=Node(id='English', type='Nationality', properties={}), type='NATIONALITY', properties={}), Relationship(source=Node(id='Charles Robert Darwin', type='Person', properties={}), target=Node(id='Evolutionary Biology', type='Concept', properties={}), type='INVOLVED_IN', properties={}), Relationship(source=Node(id='Charles Robert Darwin', type='Person', properties={}), target=Node(id='Natural Selection', type='Concept', properties={}), type='INVOLVED_IN', properties={}), Relationship(source=Node(id='Charles Robert Darwin', type='Person', properties={}), target=Node(id='Alfred Russel Wallace', type='Person', properties={}), type='COLLABORATES_WITH', properties={})]
```

您的图中的所有节点也可以具有 `__Entity__` 标签，这些标签将被索引以实现更快的检索。

```python theme={null}
# Drop graph
graph.query("STORAGE MODE IN_MEMORY_ANALYTICAL")
graph.query("DROP GRAPH")
graph.query("STORAGE MODE IN_MEMORY_TRANSACTIONAL")

# Store to Memgraph with Entity label
graph.add_graph_documents(graph_documents, baseEntityLabel=True)
```

还有一个选项可以包含图谱中获取的信息来源。为此，将 `include_source` 设置为 `True`，然后存储源文档，并使用 `MENTIONS` 关系将其链接到图中的节点。

```python theme={null}
# Drop graph
graph.query("STORAGE MODE IN_MEMORY_ANALYTICAL")
graph.query("DROP GRAPH")
graph.query("STORAGE MODE IN_MEMORY_TRANSACTIONAL")

# Store to Memgraph with source included
graph.add_graph_documents(graph_documents, include_source=True)
```

注意源内容是如何被存储的，以及 `id` 属性是如何生成的，因为文档本身没有 `id`。

您可以同时拥有 `__Entity__` 标签和文档来源。但请注意，两者都会占用内存，特别是由于内容为长字符串的源文档。

最后，您可以像前一节解释的那样查询知识图谱：

```python theme={null}
chain = MemgraphQAChain.from_llm(
    ChatOpenAI(temperature=0, model="gpt-4o"),
    graph=graph,
    allow_dangerous_requests=True,
)
print(chain.invoke("Who Charles Robert Darwin collaborated with?")["result"])
```

```text theme={null}
MATCH (:Person {id: "Charles Robert Darwin"})-[:COLLABORATION]->(collaborator)
RETURN collaborator;
Alfred Russel Wallace
```

***

> 官方原文：[src/oss/python/integrations/graphs/memgraph.mdx](https://github.com/langchain-ai/docs/blob/main/src/oss/python/integrations/graphs/memgraph.mdx) · 非官方翻译，译文由 AI 生成，以英文原文为准。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.