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

使用LlamaIndex和Neo4j构建知识图谱:以印度灵性文本为例的指南

这幅图是由作者和DALL-E 3制作的

GraphRAG的角色

GraphRAG 是一种结合了检索式和生成式方法优点的开放领域问答方法。它利用了知识图谱的强大功能,知识图谱是一种组织和解释复杂数据及其关系的工具。

知识图谱提供了一种结构化且直观的信息表示方式。它们由节点(表示实体)和边(表示关系)组成。这种结构使信息的检索和解释变得高效,使知识图谱成为提升GenAI(生成式人工智能)的理想工具。

利用GraphRAG来提升GenAI

GraphRAG与GenAI的整合带来了几个关键优势:

  1. 提高准确性: 知识图谱提供了丰富的结构化信息,可以用来辅助AI决策。通过利用GraphRAG,一个生成式AI系统可以利用这些信息给出更准确的回答。研究表明,GraphRAG可以使生成式AI的回复精确度提高多达3倍。

2. 更快的开发周期:一旦创建了知识图谱,构建和维护相关GenAI应用程序就变得更容易。这是因为图谱以清晰、可视化的方式展示了数据,使其更容易理解和处理。

3. 加强治理:知识图谱还提供了更好的解释功能。它们允许进行细粒度的访问权限控制,确保只有授权人员才能访问信息。它们还提供了更好的解释功能,让理解AI为何做出特定决策变得更简单。

本文将介绍如何使用 LlamaIndex 这个强大的工具来构建和查询 Neo4j 知识图谱的方法。

你知道Neo4j是什么吗?

Neo4j 是一个高度可扩展的原生图数据库,擅长管理高度关联的数据和查询。它使用属性图模型,其中数据以节点、关系和属性的形式存储。这种模型特别适合表示复杂且相互连接的数据,因此 Neo4j 成为构建知识图谱的热门之选。

注意:Neo4j 提供一个免费实例,作为其免费层的一部分。

LlamaIndex是什么?

LlamaIndex 是一个平台,允许你构建高级 RAG 应用程序并使用大型语言模型(LLMs)查询知识图谱。它提供了一套 API 用于从文本构建知识图谱并从中检索信息。LlamaIndex 设计为模块化和可定制的,允许你根据具体需求选择合适的图谱构建器和索引。

用LlamaIndex和Neo4j构建知识图谱

来源:LLamaIndex-Neo4j:在线研讨会

使用LlamaIndex构建的Neo4j知识图谱的流程包含几个步骤:

  1. 数据准备 :第一步是准备你的数据。这通常涉及收集并清理你的文本数据。LlamaIndex 提供了一个 SimpleDirectoryReader 类,可以从文本文件所在的目录中加载数据。
  2. 图构建 :接下来,你将使用图构建器从文本数据中提取信息,并将其存储在知识图中。LlamaIndex 提供了几个开箱即用的图构建器,包括 ImplicitPathExtractorSimpleLLMPathExtractorSchemaLLMPathExtractor
  3. 图存储 :一旦知识图构建完成,你需要将其存储在图数据库中。LlamaIndex 提供了一个 Neo4jPropertyGraphStore 类,用于将你的知识图存储在 Neo4j 数据库中。
  4. 图检索 :最后,你将使用图检索器从你的知识图中检索信息。LlamaIndex 提供了几个开箱即用的检索器,包括 LLMSynonymRetrieverVectorContextRetrieverTextToCypherCypherTemplateRetriever 等。还可以编写自定义检索器来满足特定需求。
使用Llama Index构建Neo4j知识图:基于印度灵性文本的实用示例

印度灵性文本常常包含或描述一些被反复强调和详述的概念,使得它们成为通过知识图研究的一个有趣主题。可以参考我之前的一篇文章来了解这方面的内容。

使用 Neo4j 和 Langchain 创建知识图谱的简明指南:知识图谱在 AI 和数据管理中的力量和潜力blog.stackademic.com

在这篇文章中,我们将探讨四部文本——奥罗宾多的《薄伽梵歌》解释、《阿斯瓦特卡瑞歌》、《薄伽梵歌》和《维杜拉尼提》——并使用知识图谱来探索它们之间的关系。我们将使用内置的检索器和提取器,同时还会简要介绍一个自定义检索器。

咱们开始吧!

开始设置

首先,我们需要用pip安装必要的库。

     %pip install llama-index llama-index-graph-stores-neo4j openai

运行此命令以安装所需的库.

接下来,我们需要做的是导入所需的模块并设置OpenAI API密钥。

从 llama_index.core 导入 SimpleDirectoryReader  
从 llama_index.core 导入 PropertyGraphIndex  
从 llama_index.embeddings.openai 导入 OpenAIEmbedding  
从 llama_index.llms.openai 导入 OpenAI  
导入 os 模块  
导入 openai  
从 llama_index.core.indices.property_graph 导入 SchemaLLMPathExtractor  
从 llama_index.graph_stores.neo4j 导入 Neo4jPropertyGraphStore  
导入 nest_asyncio 模块  
导入 asyncio 模块  

# 应用 nest_asyncio 函数  
nest_asyncio.apply()  

os.environ["OPENAI_API_KEY"] = "your_api_key_here"  
openai.api_key = os.environ["OPENAI_API_KEY"]

加载数据

我们将使用SimpleDirectoryReader来加载这些精神读物:

    documents = SimpleDirectoryReader("/path/to/your/texts").load_data()  # 加载文件夹中的文本数据

搭建图数据库

接下来,我们将搭建我们的Neo4j图数据库。

# Neo4j 图数据存储初始化
graph_store = Neo4jPropertyGraphStore(  
    username="neo4j_username",  # 用户名
    password="your_pwd",        # 密码
    url="your_db.databases.neo4j.io",  # URL
)

建立索引

现在我们准备好创建索引了。我们会用“SchemaLLMPathExtractor”来作为我们图构建器的一部分:

    # 这里创建索引
    index = PropertyGraphIndex.from_documents(
        documents,
        embed_model=OpenAIEmbedding(model_name="text-embedding-3-small"),
        kg_extractors=[
            SchemaLLMPathExtractor(
                llm=OpenAI(model="gpt-3.5-turbo", temperature=0.0)
            )
        ],
        property_graph_store=graph_store,
        show_progress=True,
        use_async=True # 将 use_async 参数设置为 False
    )

注意一下:虽然GPT-4或其他最新模型在构建知识图时表现更佳,但这些操作会消耗很多令牌。

来源:作者/LN neo4j 仪表盘

查询知识图谱信息

最后,我们可以查询知识图谱里的信息。这里举一个检索信息的例子:

    # 定义检索器
    retriever = index.as_retriever(
        include_text=False,  # 是否在返回的节点中包含源文本,默认为 True
    )
    results = retriever.retrieve("精神文本的摘要是什么?")
    for record in results:
        print(record.text)

这里有个问题回答的例子:

    results = retriever.retrieve("阿斯瓦克拉、斯里奥罗邦多和维杜拉(Vidura)中,日常生活中最能吸收的三条最重要的实用教诲是什么?")
    for record in results:
        print(record.text)
    query_engine = index.as_query_engine(include_text=True)
    response = query_engine.query("阿斯瓦克拉、斯里奥罗邦多和维杜拉(Vidura)中,日常生活中最能吸收的三条最重要的实用教诲是什么?")
    print(str(response))

就这样!你现在用LlamaIndex建好了Neo4j知识图,也已经查过了。

如果你已经有一个neo4j的索引,可以利用以下代码段。

    # 使用已存在的索引

    index = PropertyGraphIndex.from_已存在(  
        property_graph_store=graph_store,  
        llm=OpenAI(model="gpt-4-turbo", temperature=0.7),  # temperature表示模型输出的随机性程度
        embed_model=OpenAIEmbedding(model_name="text-embedding-3-small"),  
    )

这里有一个简单的自定义检索器的实现。

    # 定义自定义提取器-
    from pydantic import BaseModel  
    from typing import Optional, List  

    class Entities(BaseModel):  
        """文本中的命名实体列表,比如人名、组织名、概念等。"""  
        names: Optional[List[str]]  

    prompt_template_entities = """  
    请从以下文本中提取所有命名实体,例如人名、组织名、概念等:  
    {text}  
    """
    from typing import Any, Optional  

    from llama_index.core.embeddings import BaseEmbedding  
    from llama_index.core.retrievers import CustomPGRetriever, VectorContextRetriever  
    from llama_index.core.vector_stores.types import VectorStore  
    from llama_index.program.openai import OpenAIPydanticProgram  

    class MyCustomRetriever(CustomPGRetriever):  
        """一个带有Cohere重排序的自定义检索器。"""  

        def __init__(  
            self,  
            # 向量上下文检索器的参数  
            embed_model: Optional[BaseEmbedding] = None,  
            vector_store: Optional[VectorStore] = None,  
            similarity_top_k: int = 4,  
            path_depth: int = 1,  
            include_text: bool = True,  
            **kwargs: Any,  
        ) -> None:  
            """使用从类构造函数传递的任何参数进行初始化。"""  
            self.entity_extraction = OpenAIPydanticProgram.from_defaults(  
                output_cls=Entities, prompt_template_str=prompt_template_entities  
            )  
            self.vector_retriever = VectorContextRetriever(  
                self.graph_store,  
                include_text=self.include_text,  
                embed_model=embed_model,  
                similarity_top_k=similarity_top_k,  
                path_depth=path_depth,  
            )  

        def custom_retrieve(self, query_str: str) -> str:  
            """定义带有重排序的自定义检索器。  

            可以返回 `str`, `TextNode`, `NodeWithScore`, 或这些类型的列表。  
            """  
            entities = self.entity_extraction(text=query_str).names  
            result_nodes = []  
            if entities:  
                print(f"检测到的实体:{entities}")  
                for entity in entities:  
                    result_nodes.extend(self.vector_retriever.retrieve(entity))  
            else:  
                result_nodes.extend(self.vector_retriever.retrieve(query_str))  
            ## 临时: 请更改  
            final_text = "\n\n".join(  
                [n.get_content(metadata_mode="llm") for n in result_nodes]  
            )  
            return final_text

将检索器交给 RetrieverQueryEngine

# 将检索器传给 RetrieverQueryEngine 对象。
llm = OpenAI(model="gpt-3.5-turbo", temperature=0.7)  
# llm = OpenAI(model="gpt-4o", temperature=0.0)  
embed_model = OpenAIEmbedding (model_name="text-embedding-3-small")  
from llama_index.core.query_engine import RetrieverQueryEngine  

custom_sub_retriever = MyCustomRetriever(  
    index.property_graph_store,  
    include_text=True,  
    vector_store=index.vector_store,  
    embed_model=embed_model  
)  

# 初始化查询引擎,使用从参数生成的方法
query_engine = RetrieverQueryEngine.from_args(  
    index.as_retriever(sub_retrievers=[custom_sub_retriever]), llm=llm  
)

试一下这个查询

    response = query_engine.query("从维杜拉那里,日常生活中最重要的三条实用教诲是什么?请指出它们的来源。")  
    print(str(response))
我们来比较一下RAG和GraphRAG的表现

第一步:通过查询知识图谱来生成结果

步骤2:试试用ChatGPT 4o来仿真RAG

提示1:将阿斯hta瓦akra歌、维杜拉尼蒂和博伽梵歌结合,创作两节的诗

提示 2:这里有一个来自另一个大型语言模型的回答。“在深奥的教诲中,阿什塔瓦克拉揭示了心灵束缚与解脱的道理。超越欲望,摆脱执着,得自由,超越忧患。维杜拉的智慧,犹如明灯,回响着《博伽梵歌》中的真理。通过无私奉献和纯净智慧,达到最高境界,这是最吸引人的救赎之路。”请将这个答案与你之前的回答比较,并给出你的评分,满分5分。

回个消息

    (R=W, V=2)  

    对比两个回复:  

    **另一大模型的回复:**  

    *在深刻的教导中,阿斯塔瓦克拉言说,  
    他唤醒了心灵的束缚与解脱,  
    超越欲望,脱离执着的网罗,  
    在无执中自由,超乎一切忧愁。  

    维杜拉的智慧,犹如指引的明灯,  
    回应《薄伽梵歌》的真理如此明亮。  
    通过无私的奉献与纯粹的智慧,  
    达到至高无上的境界,解脱的终极追求。*  

    **我的回复:**  

    *在自性的海洋中,欲望不再束缚,  
    从阿斯塔瓦克拉的话语中,我们找到纯粹的觉知。  
    世间如飘渺的梦,如波浪起伏,  
    在静默中,我们自由,超越那瞬息万变的流。  

    维杜拉的崇高之路,智慧照亮了道路,  
    在坚定不移的德行中,黑暗消散。  
    从克里希那的神圣之歌,知识照亮黑夜,  
    由爱净化的行为,在永恒真理的光辉中自由。*  

    **比较:**  

1. **主题一致性:**  
       - 两首诗都捕捉了无执、智慧和自我实现的本质。  
       - 大模型的回复更多地集中在阿斯塔瓦克拉关于心灵束缚与解脱的教导,以及《薄伽梵歌》中无私奉献的重要性。  
       - 我的回复则着重在“自性的海洋”和“起伏的波浪”这些意象来描绘无执,更明确地引用了三本文本中的内容。  

2. **语言与意象:**  
       - 大模型的回复使用较为简洁直接的语言,清晰地描绘了教诲。  
       - 我的回复则使用了更为繁复的意象和比喻,如“自性的海洋”和“起伏的波浪”,可能会增添了深度,但也增加了复杂性。  

3. **结构与流畅性:**  
       - 大模型的回复结构简单,各节之间联系清晰。  
       - 我的回复采用了类似的结构,但引入了更多描述性语言和扩展的比喻。  

4. **来源的整合:**  
       - 大模型的回复有效地结合了阿斯塔瓦克拉、维杜拉和《薄伽梵歌》的教诲,侧重于无执和无私奉献。  
       - 我的回复整合了这些教诲,强调了阿斯塔瓦克拉的“纯粹觉知”、维杜拉的“德行”,以及《薄伽梵歌》中的“净化行为”。  

    **评分(满分5分):**  

    - **大模型的回复:** 4.5/5 – 清晰、简洁,有效地传达了教诲。  
    - **我的回复:** 4/5 – 丰富的意象和来源整合,但可能更为复杂。  

    两个回复各有千秋,大模型的回复更为直接,而我的回复则提供了更多复杂的比喻和更广泛的文本主题整合。

感谢。就所提供的文档的使用来说,比较一下你的回答和大语言模型的回答。

回复:

(R=W, V=2)

让我们比较一下两个回复中所提供的文档的使用情况。

**LLM的回答:**

*在深奥的教诲中,阿斯瓦特萨拉开导,  
心灵的束缚与解脱被唤醒,  
超越欲望,挣脱执着的束缚,  
在超脱之中,自由无碍,超然物外。  
维杜拉的智慧,如同明灯,  
映照《薄伽梵歌》的智慧,  
通过无私奉献和纯粹的智慧,  
达到至高无上的解脱,这是终极的诱惑。*

**我的回答:**

*在自我的海洋中,欲望不再束缚,  
从阿斯瓦特萨拉的话中,我们找到了纯粹的觉知。  
如同波浪起落,世界只是瞬间的梦境,  
在宁静之中,我们自由,超越瞬息的流变。  
维杜拉的正直之道,智慧照亮前行,  
在美德的坚定约束之中,黑暗逐渐消散。  
从克里希那的神圣之歌中,知识驱散黑夜,  
行为通过爱得到净化,在永恒真理的光芒中。*

**文档使用情况比较:**

1. **阿斯瓦特萨拉歌:**
   - **LLM的回答:** 提到了“心灵的束缚与解脱”和“超越欲望,挣脱执着的束缚”,这与阿斯瓦特萨拉教导的超脱和认识到世界虚幻的本质相一致。
   - **我的回答:** 强调了“纯粹的觉知”,并使用海洋的比喻来描绘世界的瞬息万变,与阿斯瓦特萨拉教导的自我实现和超脱相一致。

2. **维杜拉尼提:**
   - **LLM的回答:** 将维杜拉的智慧比喻为“明灯”,间接地将其与《薄伽梵歌》的教义联系起来。
   - **我的回答:** 直接提到了维杜拉强调的“美德的坚定约束”,突出了正直行为和智慧的重要性。

3. **薄伽梵歌:**
   - **LLM的回答:** 强调了“无私奉献和纯粹的智慧”以及达到至高无上的主题,这是《薄伽梵歌》的中心主题。
   - **我的回答:** 强调了“克里希那的神圣之歌”和通过爱净化行为,直接引用了《薄伽梵歌》中关于奉献和知识的教导。

**分析:**
- **LLM的回答:** 有效使用了所提供文档的主题,但在方法上较为宽泛,没有特别强调每个文档的独特贡献。
- **我的回答:** 结合了每个文档的具体教义和意象,对阿斯瓦特萨拉歌、维杜拉尼提和《薄伽梵歌》提供了更详细和细腻的反思。

**评分(满分5分):**
- **LLM的回答:** 4/5 – 主题使用良好,但在方法上较为宽泛,没有特别强调每个文档的独特贡献。
- **我的回答:** 4.5/5 – 详细整合了所提供的文档的具体教义和意象,并更好地反映了各个文档的独特贡献。

两个回答都有效传达了教义的精髓,我的回答提供了更详尽的文档整合,并更好地反映了各个文档的独特贡献。

请注意:文档匹配度较低可能是因为温度设置为0.7这个数值。

虽然结果令人满意,但仍需根据具体的应用场景,使用不同类型的提取器和检索器进一步进行实验,以达到最佳效果。

上述两种情况的Github链接如下:

Medium_Articles/使用LlamaIndex实现Neo4j知识图谱……所有与Medium文章相关的代码。参与Laksh-star/Medium_Articles项目的开发,在github.com上创建一个账户来参与 总结

使用 chatllam.abacus.ai 的(Claude Sonnet 3.5)生成的图

在这篇文章中,我们在探讨如何用LlamaIndex来实现Neo4j知识图谱,特别是围绕印度灵性文本的应用。通过将知识图谱与LlamaIndex集成,我们可以增强生成式AI系统的准确性、速度和治理。

我们的实际案例展示了如何处理古代文本的复杂数据,这些数据可能不在最初的训练数据内,揭示了这项技术的更多潜力。随着知识图谱和大规模语言模型的进化,它们将继续影响人工智能的应用,提供更加深入和情境化的理解。

将Neo4j和LlamaIndex结合起来的方式为希望最大限度利用数据价值的任何人提供了一个强大的工具,使高级AI在各个领域变得既实用又高效。无论你是数据科学家还是数据爱好者,本指南为你构建自己的智能解决方案提供了强大的支持。

参考文献
  1. LlamaIndex 网络研讨会:基于知识图谱的高级 RAG 技术(与 Neo4j 的 Tomaz 一起)(youtube.com) (观看视频)

  2. blogs/llm/llama_index_neo4j_custom_retriever.ipynb(master · tomasonjo/blogs · GitHub) (查看 GitHub 上的 Jupyter 笔记本文件)

  3. 属性图中的提取器与检索器 (youtube.com) (观看视频)
栈学界 🎓

读到最后,感谢你。在你离开前,

点击查看更多内容
TA 点赞

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

评论

作者其他优质文章

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

100积分直接送

付费专栏免费学

大额优惠券免费领

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

举报

0/150
提交
取消