为了账号安全,请及时绑定邮箱和手机立即绑定

利用大型语言模型构建知识图谱:LLM Graph Transformer详解

探索LangChain用大语言模型构建图的方法

构建知识图谱,这张图由 ChatGPT 生成。

从文本生成图表真的非常激动人心,但同时也极具挑战性。本质上,这是将非结构化文本转换成结构化数据。虽然这种方法已经存在了一段时间,但随着大型语言模型(LLMs)的出现,它开始受到更多关注,并逐渐成为主流。

从文本中提取实体及其之间的关系以构建知识图。插图由作者提供。

在上述图片里,你可以看到信息提取是如何将原始文本转换为知识图谱的。左边,多个文档展示了关于个人及其与公司之间关系的无结构的句子。右边,同样的信息被表示为实体和它们之间的连接图谱,展示了哪些人曾在或创立了哪些公司。

但你为什么要从文本中提取结构化信息并将其表示为图呢?一个关键原因是为检索增强生成(RAG)应用程序提供支持。虽然在无结构化的文本上使用文本嵌入模型是一种有用的方法,但它在回答需要理解多个实体之间联系的复杂、多跳问题时可能会力不从心,或者在需要进行结构化操作如过滤、排序和聚合的问题上也是如此。通过从文本中提取结构化信息并构建知识图,你不仅可以更有效地组织数据,还能创建一个理解实体之间复杂关系的强大框架。结构化的做法使得检索和利用特定信息变得更加容易,扩展了你能回答的问题类型,同时提供更高的准确性。

大约一年前,我开始尝试用LLM构建图谱(https://medium.com/@bratanic-tomaz/constructing-knowledge-graphs-from-text-using-openai-functions-096a6d010c17),随着兴趣的增长,我们决定将此功能集成到LangChain中,并将其命名为[LLM图谱生成器](https://python.langchain.com/docs/how_to/graph_constructing/)。在过去的一年中,我们不仅获得了宝贵的观点,还引入了一些新功能,这些内容将在本文中展示

代码可以在GitHub上找到。

配置 Neo4j 环境:

我们将使用Neo4j作为底层图存储,它自带开箱即用的图可视化工具。最简单的入门方式是使用Neo4j Aura提供的免费版,该服务提供Neo4j数据库的云版本。或者,您也可以通过下载Neo4j Desktop并在本地创建数据库实例来设置本地环境。

    导入 langchain_community.graphs 中的 Neo4jGraph  

    # 创建 Neo4j 图形对象,连接到指定的 Neo4j 数据库实例
    graph = Neo4jGraph(  
        url="bolt://54.87.130.140:7687",  
        username="neo4j",  
        password="cables-anchors-directories",  
        refresh_schema=False  
    )
LLM 图变换器

LLM 图形变换器旨在为使用任何大型语言模型构建图形提供一个灵活的框架。由于有这么多不同的供应商和模型可供选择,这个任务远非简单。幸运的是,LangChain 处理了大量的标准化工作。至于 LLM 图形变换器本身,则像一个多功能工具包,具有在两种完全独立的模式下运作的能力。

LLM图模型包含两种从文本中提取图的独立模式。

LLM 图形变换器有两种不同的运行模式,每种模式都旨在利用 LLM 根据不同场景生成文档图。

  1. 基于工具的模式(默认): 当大语言模型支持结构化输出或函数调用功能时,此模式利用大语言模型自带的功能[with_structured_output](https://python.langchain.com/docs/how_to/structured_output/)来使用工具。工具规范定义了输出格式,确保实体和关系以结构化、预定义的方式提取。这在图像的左侧部分有所展示,展示了Node和Relationship类的代码片段。

  2. 基于提示的模式(备用): 当大语言模型不支持工具或函数调用功能时,大语言模型图变换器会退回到完全基于提示的方法。此模式使用少量样本提示来定义输出格式,引导大语言模型以文本方式提取实体和关系。结果将通过自定义函数进行解析,将大语言模型的输出转换为JSON格式。这个JSON用于填充节点和关系,就像在基于工具的模式中一样,但在这里大语言模型完全由提示而不是结构化工具引导。这在图像的右侧部分有所展示,提供了示例提示和生成的JSON输出。

确保LLM Graph Transformer能够适应不同的LLM,使它能够既使用工具直接构建图,也可以通过解析文本提示的输出来构建图。

请注意,即使模型支持工具或功能,你也可以通过设置属性ignore_tools_usage=True来使用提示式的提取。

工具辅助提取

我们最初选择了基于工具的方法来进行提取,因为它减少了对提示工程和自定义解析的需求。在LangChain中,with_structured_output 方法允许你使用工具或函数来提取信息,输出可以定义为JSON结构或Pydantic对象。我个人更喜欢Pydantic对象,因为它们更清晰,所以我们选择了这种方案。

我们先定义 Node 类。

    class Node(BaseNode):  
        id: str = Field(..., description='名称或易于人类识别的唯一标识符')  
        label: str = Field(..., description=f"可选标签为 {enum_values}")  
        properties: Optional[List[Property]]

每个节点都有一个 id,一个 label,以及可选的 properties。这里没有包含完整的描述,为了简洁,将 id 描述为人类可读的唯一标识符这一点很重要,因为一些大型语言模型倾向于将 ID 属性理解为传统方式,如随机字符串或增量整数。相反,我们希望使用实体名称作为 id 属性值。我们还通过在 label 描述中列出可用的标签类型来限制可用的标签。此外,像 OpenAI 这样的语言模型支持一个 enum 参数,我们也使用了这个参数。

接下来,我们来看看这个 Relationship

    class Relationship(BaseRelationship):  
        source_node_id: str  
        source_node_label: str = Field(..., description=f"可选值为 {enum_values}")  
        target_node_id: str  
        target_node_label: str = Field(..., description=f"可选值为 {enum_values}")  
        type: str = Field(..., description=f"可选值为 {enum_values}")  
        properties: Optional[List[Property]]

这是Relationship类的第二次迭代。最初,我们使用了嵌套的Node对象来表示源节点和目标节点,但嵌套的对象降低了提取过程的准确性和质量,使我们很快发现了这一点。因此,我们决定将源节点和目标节点拆分为单独的字段,例如,我们定义了source_node_idsource_node_label,还有target_node_idtarget_node_label这些字段。此外,我们还定义了节点标签和关系类型描述中允许的值,以确保LLMs遵循指定的图模式要求。

工具驱动的提取方法使我们能够为这些节点和关系定义属性。下面是我们用来定义它们的类。

    class Property(BaseModel):  
        """这是一个包含键和值的属性"""  
        key: str = Field(..., description=f"可用选项包括 {枚举值}")  
        value: str

每个 Property 都被定义为键值对。虽然这种方法很灵活,但也有一些局限性。例如,我们无法为每个属性提供独特的描述,也无法指定某些属性为必填,而其他为可选,因此所有属性都被设为可选。此外,属性不是为每个节点或关系类型单独定义的,而是跨所有节点和关系类型共享的。

我们也实现了一个详细的系统提示来帮助提取过程。不过,根据我的经验,函数和参数描述的影响通常比系统消息要大得多。

很遗憾,目前还没有简单的办法来设置LLM Graph Transformer中的函数或参数。

基于提示的抽取

由于只有少数商业大语言模型和LLaMA 3支持内置工具,我们实现了一个备用方案以应对没有工具支持的模型。你也可以设置 ignore_tool_usage=True 以切换到基于提示的模式,即使该模型支持工具也一样。

大部分基于提示的方法的例子和设计,都是由Geraldus Wilsen贡献的。

采用基于提示的方法,我们得直接在提示中定义输出结构。您可以在这里看到整个提示。在这篇博客文章里,我们将做高层次的概述。我们从定义系统提示入手。

你是一个顶尖算法,设计用于从给定文本中提取结构化格式的信息以构建知识图谱。你的任务是识别用户提示中指定的实体和关系,并从给定文本中提取,生成的输出应采用JSON格式。该输出应为包含以下键的JSON对象列表:

- **"head"**:提取的实体文本,必须与用户提示中指定的类型之一匹配。
- **"head_type"**:提取的头实体类型,从指定的类型列表中选取。
- **"relation"**:头实体与尾实体之间的关系类型,从允许的关系列表中选取。
- **"tail"**:尾实体文本,代表关系的尾部。
- **"tail_type"**:尾实体文本类型,从提供的类型列表中选取。

尽可能多地提取实体和关系。

**实体一致性**:确保实体表示的一致性。如果一个实体,例如“John Doe”,在文本中以不同的名字或代词(例如“Joe”,“他”)出现多次,使用最完整的标识符保持一致。这种一致性对于创建一个连贯且易于理解的知识图谱至关重要。

**注意**:
- 不要添加任何额外的解释或文本。

在提示驱动的方法中,一个关键的区别是我们要求LLM只抽取关系,而不抽取单独的节点。这意味着我们不会有孤立的节点,这一点不同于工具驱动的方法。此外,由于缺乏原生工具支持的模型通常表现不佳,我们不允许抽取任何属性,无论是节点还是关系,来简化提取的输出。

然后,我们再给模型加入几个少量样本。

    examples = [  
        {  
            "text": (  
                "亚当自2009年起就在微软做软件工程师,去年他还获得了最佳人才奖"  
            ),  
            "head": "亚当",  
            "head_type": "Person",  
            "relation": "就职于",  
            "tail": "微软",  
            "tail_type": "Company",  
        },  
        {  
            "text": (  
                "亚当自2009年起就在微软做软件工程师,去年他还获得了最佳人才奖"  
            ),  
            "head": "亚当",  
            "head_type": "Person",  
            "relation": "获得",  
            "tail": "最佳人才奖",  
            "tail_type": "奖项",  
        },  
    ...  
    ]

在这个方法里,目前还不支持添加自定义的少量样本或额外说明。唯一的自定义方法是通过编辑prompt属性来修改整个提示。我们正考虑增加更多的自定义选项。

接下来,我们将看看如何定义图模式定义。

定义图结构

当使用LLM Graph Transformer进行信息抽取时,定义一个图模式(schema)对于指导模型构建有意义且结构化的知识表示形式至关重要。一个定义良好的图模式指定了要抽取的节点类型和关系,以及与每个节点和关系相关的任何属性。此模式充当蓝图,确保LLM能够一致地抽取与预期知识图结构相匹配的相关信息。

在这篇文章中,我们将使用玛丽·居里的维基百科页面的开头段作为测试,并在结尾加上一句关于罗宾·威廉姆斯的内容。

    from langchain_core.documents import Document  

    text = """  
    玛丽·居里,1867年11月7日-1934年7月4日,是一位波兰和后来成为法国公民的物理学家和化学家,她在放射性研究方面取得了开创性的贡献。  
    她是历史上第一位获得诺贝尔奖的女性,是历史上第一个两次获得诺贝尔奖的人,也是唯一在两个科学领域都获得诺贝尔奖的人。  
    她的丈夫皮埃尔·居里是她第一次获得诺贝尔奖的共同得主,使他们成为有史以来第一对获得诺贝尔奖的夫妇,并开启了居里家族获得五次诺贝尔奖的传奇。  
    1906年,她成为巴黎大学首位女性教授。  
    还有,比如罗宾·威廉姆斯。  
    """  
    documents = [Document(page_content=text)]

我们还会在所有示例里使用GPT-4o。

from langchain_openai 导入 ChatOpenAI  
导入 getpass  
导入 os  

os.environ["OPENAI_API_KEY"] = getpass.getpass("OpenAI API 密钥")  

llm = ChatOpenAI(model='gpt-4o')

首先,让我们先来看看没有定义任何图模式的情况下,提取过程是怎么运作的。

from langchain_experimental.graph_transformers import LLMGraphTransformer  

no_schema = LLMGraphTransformer(llm=llm)

现在我们可以用异步函数 aconvert_to_graph_documents 来处理这些文档。推荐用异步方式结合 LLM 提取,这样可以同时处理多个文档,从而大大减少等待时间,并提升处理效率,尤其是在处理大量文档时。

data = 异步等待 no_schema.aconvert_to_graph_documents(文档)
# 将文档转换为图文档

LLM Graph Transformer的响应将是一个图文档,该文档的结构如下:

    [  
        GraphDocument(  
            nodes=[  
                Node(id="Marie Curie", type="Person", properties={}),  
                Node(id="Pierre Curie", type="Person", properties={}),  
                Node(id="Nobel Prize", type="Award", properties={}),  
                Node(id="巴黎大学", type="Organization", properties={}),  
                Node(id="Robin Williams", type="Person", properties={}),  
            ],  
            relationships=[  
                Relationship(  
                    source=Node(id="Marie Curie", type="Person", properties={}),  
                    target=Node(id="Nobel Prize", type="Award", properties={}),  
                    type="获得",  
                    properties={},  
                ),  
                Relationship(  
                    source=Node(id="Marie Curie", type="Person", properties={}),  
                    target=Node(id="巴黎大学", type="Organization", properties={}),  
                    type="担任教授",  
                    properties={},  
                ),  
                Relationship(  
                    source=Node(id="Pierre Curie", type="Person", properties={}),  
                    target=Node(id="Nobel Prize", type="Award", properties={}),  
                    type="获得",  
                    properties={},  
                ),  
            ],  
            source=Document(  
                metadata={"id": "de3c93515e135ac0e47ca82a4f9b82d8"},  
                page_content="\n玛丽·居里,1867年11月7日-1934年7月4日,是一位波兰和法国物理学家及化学家,她对放射性进行了开创性的研究。\n她是第一位获得诺贝尔奖的女性,并且也是第一位两次获得诺贝尔奖的人,而且是唯一在两个科学领域获得诺贝尔奖的人。\n她的丈夫皮埃尔·居里是她第一次获得诺贝尔奖的共同获奖者,使他们成为历史上第一对获得诺贝尔奖的夫妇,并开启了居里家族五项诺贝尔奖的传奇。\n1906年,她成为巴黎大学第一位女教授。\n还有罗宾·威廉姆斯!\n",  
            ),  
        )  
    ]

图形文档描述了提取的节点关系。此外,在提取时,源文档会在source键下添加。

我们可以使用这个工具Neo4j浏览器来可视化结果,使理解更加清晰和直观。

在同一个数据集上进行两次提取而没有定义图形模式的可视化。图片由作者提供。

上述图像展示了对同一段关于玛丽·居里的段落进行的两次提取操作。在这种情况下,我们使用了带工具提取功能的GPT-4,这也允许孤立节点,如图中所示。由于没有定义图模式,大型语言模型在运行时确定要提取的信息,这可能导致从同一段落提取的信息存在差异。因此,有些提取的信息比其他详细,结构上也有所不同,即使是同一信息也是如此。例如,在左边,玛丽被表示为“诺贝尔奖的WINNER”,而在右边,她“赢得了诺贝尔奖”。

现在,我们来用基于提示的方法试一下同样的提取。对于那些支持工具的模型,只需设置ignore_tool_usage参数即可开启基于提示的提取。

    no_schema_prompt = LLMGraphTransformer(llm=llm, ignore_tool_usage=True)  
    data = await no_schema.aconvert_to_graph_documents(documents)

再次,我们可以在 Neo4j 浏览器中看到两个不同的执行。

这是作者制作的,在同一个数据集上使用提示方法进行两次提取而不需要定义图模式的可视化图像。

采用基于提示的方法时,我们不会看到任何孤立的点。不过,与之前的提取一样,在不同的运行中模式可能会有所不同,导致相同的输入产生不同的输出。

接下来,让我们来看看定义图模式是如何帮助我们得到更一致的输出结果的。

允许的节点类型定义

限制提取的图结构可以非常有益,因为它引导模型专注于特定的和相关的实体和关系。通过定义清晰的模式,你可以提高提取的一致性,从而使输出更加可预测。这使输出更可预测,更符合实际需求,并减少不同运行之间的差异。确保提取的数据遵循标准化结构,捕捉预期信息。有了一个明确定义的模式,模型就不会轻易忽略关键细节或引入意外元素,从而生成更干净、更实用的图结构。

我们首先将通过设置allowed_nodes参数来定义要提取的节点类型。

    allowed_nodes = ["Person", "Organization", "Location", "Award", "ResearchField"]  # 允许的节点列表
    nodes_defined = LLMGraphTransformer(llm=llm, allowed_nodes=allowed_nodes)  # 定义节点
    data = await allowed_nodes.aconvert_to_graph_documents(documents)  # 等待将文档转换为图文档

在这里,我们定义了LLM应该提取如 PersonOrganizationLocation 等五种类型的实体。我们通过Neo4j浏览器可视化并对比了两次不同的执行结果。

具有预定义节点类型的两次抽取步骤的可视化。图片由作者提供。

通过指定预期的节点类型,我们能够实现更一致的节点提取结果。但是,可能仍然会出现一些差异。例如,第一次运行中,“放射性研究”被提取为一个研究领域,而在第二次运行中则没有被提取出来。

因为我们还没有定义这些关系,所以它们的类型可能在不同的运行中会有所变化。此外,有些提取包含的信息可能更多。例如,Marie 和 Pierre 的 MARRIED_TO 关系并未在所有提取中都出现。

现在,让我们看看如何通过定义不同类型的关系来进一步提高一致性。

规定允许的关系类型

正如我们所观察到的,仅定义节点类型仍然允许关系抽取发生变化。为了应对这一情况,我们可以尝试定义关系。首先,我们可以通过列出允许的类型来定义关系。

    allowed_nodes = ["Person", "Organization", "Location", "Award", "ResearchField"]  
    allowed_relationships = ["SPOUSE", "AWARD", "FIELD_OF_RESEARCH", "WORKS_AT", "IN_LOCATION"]  
    rels_defined = LLMGraphTransformer(  
      llm=llm,   
      allowed_nodes=allowed_nodes,  
      allowed_relationships=allowed_relationships  
    )  
    # 将文档转换为图文档的过程
    data = await rels_defined.aconvert_to_graph_documents(documents)

我们再来看看两个不同的提取。

图片作者提供的图片,展示了使用预设的节点和关系类型的两个抽取步骤的可视化。

定义了节点和关系后,我们的输出变得更加一致和可预测。例如,Marie 总是被显示为获奖、是 Pierre 的配偶,并且在巴黎大学工作。然而,由于关系被定义为一个通用列表,没有对它们可以连接的节点做限制,因此仍可能存在变化。例如,FIELD_OF_RESEARCH 关系可能出现在 PersonResearchField 之间,但也有可能将 AwardResearchField 相关联。此外,由于没有定义关系的方向,可能会出现方向上的一致性问题。

为了解决无法指定关系可以连接哪些节点和强制执行关系方向的问题,我们最近推出了一种新的关系定义选项,如下所示。

    allowed_nodes = ["Person", "Organization", "Location", "Award", "ResearchField"]  
    allowed_relationships = [  
        ("Person", "SPOUSE", "Person"),  
        ("Person", "AWARD", "Award"),  
        ("Person", "WORKS_AT", "Organization"),  
        ("Organization", "IN_LOCATION", "Location"),  
        ("Person", "FIELD_OF_RESEARCH", "ResearchField")  
    ]  
    rels_defined = LLMGraphTransformer(  
      llm=llm,   
      allowed_nodes=allowed_nodes,  
      allowed_relationships=allowed_relationships  
    )  
    data = await rels_defined.aconvert_to_graph_documents(documents)

我们不再将关系定义为简单的字符串条目。取而代之的是,我们使用一个包含三个元素的组合,这些元素分别代表来源节点、关系类型以及目标节点。

我们再看看这些结果的可视化。

两次提取过程的可视化,展示了预设的节点和高级的关系类型。图片由作者提供。

使用三元组方法为跨多次执行提取的图提供了一个更加一致的框架。然而,鉴于大型语言模型的性质,提取的细节可能会有所不同。例如,在右边可以看到皮埃尔获得了诺贝尔奖,而在左边则没有提到这一信息。

定义的特性

图模式的最后一点, 我们可以做的增强是为节点和关系定义属性。这里有两件事可以选择。第一种是将node_propertiesrelationship_properties设为true,这会让LLM自己决定提取哪些属性。

    allowed_nodes = ["Person", "Organization", "Location", "Award", "ResearchField"]  
    allowed_relationships = [  
        ("Person", "SPOUSE", "Person"),  
        ("Person", "AWARD", "Award"),  
        ("Person", "WORKS_AT", "Organization"),  
        ("Organization", "IN_LOCATION", "Location"),  
        ("Person", "FIELD_OF_RESEARCH", "ResearchField")  
    ]  
    node_properties=True  
    relationship_properties=True  
    props_defined = LLMGraphTransformer(  
      llm=llm,   
      allowed_nodes=allowed_nodes,  
      allowed_relationships=allowed_relationships,  
      node_properties=node_properties,  
      relationship_properties=relationship_properties  
    )  
    data = await props_defined.aconvert_to_graph_documents(documents)  
    graph.add_graph_documents(data)

我们来看看结果吧。

提取了节点和关系的属性,图片由作者提供。

我们让LLM能够添加它认为相关的任何节点或关系属性。例如,它选择包括玛丽·居里的出生和死亡日期,她在巴黎大学担任教授,以及她两次获得诺贝尔奖。这些额外信息显著丰富了提取的内容。

我们的第二个选择是定义我们想要提取的节点和关系的属性。

    allowed_nodes = ["Person", "Organization", "Location", "Award", "ResearchField"]  
    allowed_relationships = [  
        ("Person", "SPOUSE", "Person"),  
        ("Person", "AWARD", "Award"),  
        ("Person", "WORKS_AT", "Organization"),  
        ("Organization", "IN_LOCATION", "Location"),  
        ("Person", "FIELD_OF_RESEARCH", "ResearchField")  
    ]  
    node_properties=["birth_date", "death_date"]  
    relationship_properties=["start_date"]  
    props_defined = LLMGraphTransformer(  
      llm=llm,   
      allowed_nodes=allowed_nodes,  
      allowed_relationships=allowed_relationships,  
      node_properties=node_properties,  
      relationship_properties=relationship_properties  
    )  
    data = await props_defined.aconvert_to_graph_documents(documents)  
    graph.add_graph_documents(data)  

属性只是被定义为两个列表。我们来看看LLM提取了哪些内容。

提取了预设的节点和关系属性。这张图片是由作者提供的。

出生和死亡日期仍然与之前的提取保持一致。这一次,LLM还提取了玛丽在巴黎大学里开始担任教授的日期。

属性确实为提取的信息增添了宝贵的深度,但目前实现中仍有一些限制:

  • 属性只能通过工具方法来提取。
  • 所有属性都是以字符串形式提取的。
  • 属性只能全局定义,不能为每个节点标签或关系类型单独定义。
  • 没有选项自定义属性描述以引导LLM更准确提取。
严格模式(Strict Mode)

如果你认为我们已经找到了让大模型完美遵循定义模式的方法,那么我必须纠正这个观点。尽管我们在提示工程方面投入了大量精力,但让大语言模型,尤其是表现较差的模型,完全准确地遵循指令仍然具有挑战性。为解决这个问题,我们引入了一个后处理步骤,称为 strict_mode,它会移除任何不符合定义图模式的信息,从而确保结果更干净、更一致。

默认值为 True,但你可以使用以下代码关闭它,例如:

# 代码示例
    LLMGraphTransformer(  
      llm=llm,   
      allowed_nodes=allowed_nodes,  
      allowed_relationships=allowed_relationships,  
      strict_mode=False # 禁用严格模式 (jìn yòng yán jùe mó shì)  
    )

在严格模式关闭的情况下,你得到的节点或关系类型可能超出定义的图模式,因为大模型有时会根据自己的理解改变输出结构。

将图文档导入图数据库

从LLM Graph Transformer提取的图形文档可以使用add_graph_documents方法导入到例如Neo4j这样的图数据库中,以进一步分析和应用为目的。我们将探讨不同的导入方式,来满足不同的应用场景。

默认引入

您可以通过以下代码将节点以及它们之间的关系导入Neo4j。

将文档添加到图形中。

这种方法直接导入了所有提供的图文档中的节点和关系。我们在整篇博客文章中用这种方法来回顾不同LLM和模式配置下的结果。

默认导入设置:图片来自作者。

基础实体标签定义

大多数图数据库都支持索引以优化数据的导入和检索。在Neo4j中,索引只能为特定的节点标签设定。因为我们可能无法提前了解所有的节点标签,我们可以通过给每个节点添加一个baseEntityLabel参数来处理这种情况,以添加次级基础标签。这样,我们仍然可以通过索引实现高效的数据导入和检索,而无需为图中每个可能的节点标签都创建索引。

graph.add_graph_documents(graph_documents, baseEntityLabel=True)(将图文档添加到图中,设置基础实体标签为真)

正如之前提到的,使用 baseEntityLabel 参数会使每个节点带有额外的 __Entity__ 标签。

每个节点都通过 baseEntityLabel 参数获取一个次要标签。图片由作者提供。

包含原始文件

最后一个选项是导入用于提取节点和关系的原始文档。这样我们就可以追踪每个实体出现在哪些文档中。你可以通过设置 include_source 参数来导入原始文档。

graph.add_graph_documents(graph_docs, include_source=True)

检查导入的图表时,我们就能看到类似的结果,例如。

导入的源文件,作者的图片。

在这项可视化中,源文档用蓝色突出显示,所有从源文档中提取的实体通过MENTIONS关系相互连接。这种模式让你能够构建能够利用结构化和非结构化搜索方法的检索器

总结

在这篇文章中,我们探讨了LangChain的LLM图变换器及其构建知识图谱的两种模式。工具模式是我们主要采用的方法,它利用了结构化输出和函数调用,这减少了提示工程的工作量,并允许属性提取。而提示模式在工具不可用时非常有用,它依赖于少量示例来指导LLM。提示模式不支持属性提取,同时不会生成孤立节点。

我们观察到,定义一个清晰的图模式,包括允许的节点和关系类型,有助于提高数据提取的一致性和性能。一个受限模式使得输出更加符合预期结构,使其更加可预测、可靠,并且更易于应用。不论是使用工具还是提示,LLM Graph Transformer 可以更有序、结构化地表示非结构化数据,从而更好地支持 RAG 应用和处理多跳查询。

代码可在Github上找到。您也可以使用Neo4j提供的LLM 图变换器应用在无需编码环境中尝试LLM 图变换器。

Neo4j 图创建工具
点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消