前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何用知识图谱和Llama-Index来实现RAG?

如何用知识图谱和Llama-Index来实现RAG?

作者头像
山行AI
发布2023-12-19 19:15:59
1.7K0
发布2023-12-19 19:15:59
举报
文章被收录于专栏:山行AI山行AI

幻觉是与大型语言模型(LLM)一起工作时常见的问题。LLM能够生成流畅连贯的文本,但往往会产生不准确或不一致的信息。避免LLM产生幻觉的方法之一是使用外部知识源,如数据库或知识图谱,提供事实信息。

什么是向量数据库?

一个向量数据库是包含表示实体或概念(如单词、短语或文档)的高维向量的集合。基于它们的向量表示,向量数据库可以用来衡量不同实体或概念之间的相似性或相关性。

例如,一个向量数据库可以通过它们的向量距离告诉您“巴黎”和“法国”之间的关联程度高于“巴黎”和“德国”。

什么是知识图谱?

知识图谱是一组表示实体或概念以及它们之间关系(如事实、属性或类别)的节点和边的集合。

可以使用知识图谱基于节点和边的属性来查询或推断有关不同实体或概念的事实信息。

例如,知识图谱可以根据它们的边标签告诉你“巴黎”是“法国”的首都。查询图数据库涉及遍历图结构并根据特定的条件检索节点、关系或模式。以下是一个简单的示例,演示如何查询图数据库:

假设你有一个表示社交网络的图数据库,其中用户是节点,它们的关系(如友谊)通过连接节点的边来表示。你想找到给定用户的朋友的朋友(共同联系人)。

1.从参考用户开始:确定图数据库中表示参考用户的节点。可以通过查询特定的用户标识符或其他相关条件来实现。2.遍历图:

使用图查询语言(如Neo4j中使用的Cypher或Gremlin)从参考用户节点开始遍历图。编写一个查询,指定您想要探索的模式或关系。在这种情况下,您想要找到朋友的朋友。例如Cypher查询:

代码语言:javascript
复制
MATCH (:User {userId: ‘referenceUser’})-[:FRIEND]->()-[:FRIEND]->(fof:User)

RETURN fof

这个查询从引用用户开始,在FRIEND关系中跟随到另一个节点(朋友),然后再跟随另一个FRIEND关系来查找朋友的朋友(fof)。

3.检索结果:

对图数据库执行查询,并根据查询模式检索结果节点(朋友的朋友)。如果需要,您可以获取特定的属性或其他关于检索节点的信息。

4.呈现结果:显示已检索的朋友的朋友给用户,或根据需要进一步处理数据。这些信息可以用于建议、网络分析或其他相关目的。

图形数据库提供更高级的查询功能,包括过滤、聚合和复杂模式匹配。具体的查询语言和语法可能有所不同,但一般的过程涉及遍历图结构以检索与所需条件匹配的节点和关系。查询向量数据库通常涉及搜索相似向量或根据特定条件检索向量。以下是一个简单的示例,展示了如何查询向量数据库:

假设你有一个向量数据库,包含以高维向量表示的客户概要,而你想要找到与给定的参考客户类似的其他客户。

1.定义参考客户向量:

首先,定义参考客户的向量表示。这可以通过提取相关特征或属性并将它们转换为向量格式来完成。

2. 执行相似性搜索:

使用适当的算法,如k最近邻算法(k-NN)或余弦相似度,对向量数据库进行相似性搜索。该算法将根据相似分数识别与参考客户向量最相似的邻居。

3.检索相似客户:

检索在前一步骤中鉴定的最近邻向量对应的客户配置文件。这些配置文件将代表基于定义的相似性度量,与参考客户相似的客户。

4.展示结果:最后,将检索到的客户概况或相关信息呈现给用户,如显示他们的姓名、人口统计信息或购买历史。这些信息可用于推荐、定向营销活动或个性化体验。

知识图谱的主要组成部分

知识图谱通常由两个主要组成部分组成:

1. 顶点/节点:

表示知识领域中的实体或对象。每个节点对应一个唯一的实体,并通过唯一标识符进行标识。例如,在一个关于钦奈国王的知识图中,节点的值可以是“费城费城人”和“大联盟板球”等。

2. 边:

表示两个节点之间的关系。例如,一条边“竞争”可以连接“钦奈国王”的节点和“大联盟板球”的节点。

知识图中的三元组

三元组是图中的基本数据单元。它由三个部分组成:

1.主语: 三元组所指的节点。2.宾语: 关系所指向的节点。3.谓语: 主语和宾语之间的关系。

在下面的三元组示例中,“Chennai Kings”是主语,“compete in”是谓语,“Major League Cricket”是宾语。

代码语言:javascript
复制
(Chennai Kings) — [compete in]->(Major League Cricket)

知识图谱数据库能够通过存储三元组来高效地存储和查询复杂的图形数据。

知识图谱相比于矢量数据库在LLM幻觉方面有何优势?

知识图谱提供比向量数据库更精确和特定的信息。向量数据库指示两个实体或概念之间的相似性或相关性,而知识图谱能够更好地理解它们之间的关系。例如,知识图谱可以告诉你“埃菲尔铁塔”是“巴黎”的地标,而向量数据库只能指示这两个概念有多相似。这可以帮助LLM生成更准确和相关的文本。•知识图谱支持比向量数据库更多样化和复杂的查询。向量数据库主要可以回答基于向量距离、相似度或最近邻的查询,这些查询仅限于直接的相似度度量。相比之下,知识图谱可以处理基于逻辑运算符的查询,例如“具有属性Z的所有实体是什么?”或“W和V的共同类别是什么?”这可以帮助LLM生成更多样化和有趣的文本。•知识图谱比向量数据库能够进行更多的推理和推断。向量数据库只能提供存储在数据库中的直接信息。相反,知识图谱可以提供由实体或概念之间的关系推导出的间接信息。例如,知识图谱可以根据“巴黎是法国的首都”和“法国位于欧洲”的事实推断出“埃菲尔铁塔位于欧洲”。这可以帮助LLM生成更符合逻辑和一致的文本。总之,与向量数据库相比,知识图谱是解决LLM中产生幻觉的更好解决方案。知识图谱为LLM提供了更准确、相关、多样、有趣、逻辑和一致的信息。使用知识图谱可以减少LLM中的幻觉,使其在生成准确和事实性文本方面更可靠。但关键在于文档必须清晰地展现出关系,否则知识图谱将无法捕捉到它。

向量化数据库和知识图谱的区别

存储和表示数据的方式不同

1.一个向量化数据库和知识图谱采用两种不同的方法来存储和表示数据。 2.向量化数据库方法使用数值向量来表示数据,主要用于相似性搜索。

•每个实体都表示为高维向量,并且实体之间的相似性是基于向量距离计算的。•向量化数据库非常适合基于相似性的操作,但可能难以表示实体之间的复杂关系和语义意义。相比之下,知识图谱旨在捕捉和表示对象之间的关系。•知识图谱捕捉实体之间的复杂关系和依赖,并提供语义分析和推理能力。•知识图谱可以通过逻辑运算符回答复杂查询,并进行高级推理和知识发现。

3.图数据库主要关注对象之间的一对一关系,而向量数据库则关注向量的相似度。

数据存储方式不同

1.图数据库

•利用节点和边表示关系的图形数据库•图形数据库非常适合分析实体间的关系和复杂网络。

2.向量数据库

•向量数据库使用数值数组。•向量数据库非常适合相似度搜索和最佳匹配搜索。

如何选择?

选择使用哪种方法的问题取决于几个重要因素,例如数据的性质及其关系、查询和分析的要求以及相似搜索或关系探索的效率。这两种方法各有优势和劣势,具体的使用案例将决定哪种方法最合适。主要比较因素:

•数据结构:数据存储完全不同,Graph(图数据库)用于存储节点和边,非常擅长映射关系,将关系作为一等公民对待。VectorDB(向量数据库)将数据存储为数值数组。•数据检索和分析:Graph(图数据库)用于分析实体之间的关系,而向量数据库擅长分析模式。•查询:Graph(图数据库)查询实体之间的关系和复杂网络。而VectorDB(向量数据库)非常擅长相似度搜索或者最佳匹配搜索。•性能:根据查询重点,GraphDB(图数据库)/知识图谱在处理涉及关系的查询方面非常出色,而VectorDB(向量数据库)提供快速的相似度搜索。

比较图数据库和向量数据库时,有几个重要的问题需要考虑。以下是一些关键问题可以探讨:

•数据的性质及其关系是什么?•数据主要是结构化还是非结构化信息?•实体之间是否存在复杂的关系和依赖?•查询和分析有什么具体要求?•需要进行高效的相似性搜索和推荐吗?•是否需要进行复杂的图遍历和关系探索?•语义分析和推理能力是否至关重要?•对于实时应用来说,低延迟是否至关重要?•是否存在多种类型的关系和属性需要捕捉?•有哪些可用的查询语言、API和生态系统集成?总结一下,向量数据库和知识图谱使用不同的方法来存储和表示数据。虽然向量数据库适用于基于相似性的操作,知识图谱则旨在捕捉和分析复杂的关系和依赖关系。选择合适的方法取决于您项目的具体需求和目标。

代码实现

使用的技术栈

1.LlamaIndex: LlamaIndex是一个编排框架,用于简化将私人数据与公共数据集成,以构建使用大型语言模型(LLMs)的应用程序。它提供了数据摄取、索引和查询工具,使其成为生成型人工智能需求的多功能解决方案。2.嵌入模型:嵌入模型用于将文本转化为数字表示,以表达提供的文本信息。该表示捕捉了所嵌入内容的语义意义,使其适用于许多行业应用。在这里,我们使用了 "thenlper/gte-large" 模型。3.LLM:大型语言模型用于根据提供的问题和上下文生成响应。在这里,我们使用了 Zephyr 7B beta 模型。

逐步代码实现

此代码实现将引导您使用Llama Index创建知识图谱。

1.在这里,我们将读取一个.pdf文件并将其转换为结构化知识图谱。2.将嵌入存储在图形数据存储库中。3.检索与用户查询匹配的相关上下文。4.向LLM提供响应以生成回答。

实施步骤

安装所需依赖

代码语言:javascript
复制
%%capture
pip install llama_index pyvis Ipython langchain pypdf

启用诊断日志记录

•记录日志可以为代码执行提供有价值的见解。•这里将日志级别设置为“INFO”,这将输出有助于监控应用程序操作流程的消息

代码语言:javascript
复制
import logging
import sys
#
logging.basicConfig(stream=sys.stdout, level=logging.INFO)
logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))

导入必要的依赖项

代码语言:javascript
复制
from llama_index import (SimpleDirectoryReader,
                         LLMPredictor,
                         ServiceContext,
                         KnowledgeGraphIndex)
#
from llama_index.graph_stores import SimpleGraphStore
from llama_index.storage.storage_context import StorageContext
from llama_index.llms import HuggingFaceInferenceAPI
from langchain.embeddings import HuggingFaceInferenceAPIEmbeddings
from llama_index.embeddings import LangchainEmbedding
from pyvis.network import Network

使用的包的简要概述

•SimpleDirectoryReader:用于读取非结构化数据。•LLMPredictor:用于使用大型语言模型(LLM)生成预测。•ServiceContext:为组织各种服务提供必要的上下文数据。•KnowledgeGraphIndex:构建和操作知识图谱所需。•SimpleGraphStore:用于存储图形数据的简单存储库。•HuggingFaceInferenceAPI:用于利用开源LLM的模块。

设置LLM

在这里,我们使用了HuggingFace推理API的端点。

代码语言:javascript
复制
HF_TOKEN = "Your Huggaingface api key "
llm = HuggingFaceInferenceAPI(
    model_name="HuggingFaceH4/zephyr-7b-beta", token=HF_TOKEN
)

设置嵌入模型

代码语言:javascript
复制
embed_model = LangchainEmbedding(
HuggingFaceInferenceAPIEmbeddings(api_key=HF_TOKEN,model_name="thenlper/gte-large")
)

加载数据

代码语言:javascript
复制
documents = SimpleDirectoryReader("/content/Documents").load_data()
print(len(documents))
输出
代码语言:javascript
复制
44

构建知识图谱索引

创建知识图谱通常涉及专门且复杂的任务。然而,通过利用Llama Index(LLM)、KnowledgeGraphIndex和GraphStore,我们可以从Llama Hub支持的任何数据源中轻松创建一个相对有效的知识图谱。

设置服务上下文

代码语言:javascript
复制
service_context = ServiceContext.from_defaults(
 chunk_size=256,
 llm=llm,
 embed_model=embed_model
)

设置存储上下文

代码语言:javascript
复制
#setup the service context

service_context = ServiceContext.from_defaults(
    chunk_size=256,
    llm=llm,
    embed_model=embed_model
)

#setup the storage context

graph_store = SimpleGraphStore()
storage_context = StorageContext.from_defaults(graph_store=graph_store)

#Construct the Knowlege Graph Undex
index = KnowledgeGraphIndex.from_documents( documents=documents,
                                           max_triplets_per_chunk=3,
                                           service_context=service_context,
                                           storage_context=storage_context,
                                          include_embeddings=True)

•max_triplets_per_chunk:它决定了每个数据块处理的关系三元组的数量。•include_embeddings:用于切换在索引中包含向量嵌入以进行高级分析。

由文档创建的知识图谱

代码语言:javascript
复制
Text: page_label: 2
file_path: /content/Documents/Employee-Stock-Option-Plans-ESOP-Best-Practices-2.pdf

What is an ESOP?
Triplets:
(page_label, is, 2)
(ESOP, is, What is an ESOP?)
---------------------
Text: page_label: 3
file_path: /content/Documents/Employee-Stock-Option-Plans-ESOP-Best-Practices-2.pdf

Why Offer an ESOP?
Triplets:
(page_label, is, 3)
(ESOP, is, Why Offer an ESOP?)
---------------------
Text: page_label: 4
file_path: /content/Documents/Employee-Stock-Option-Plans-ESOP-Best-P
(page_label, is, part of)
(page_label, is, Table of Contents)
(file_path, is, path of)
(file_path, is, /content/Documents/Employee-Stock-Option-Plans-ESOP-Best-Practices-2.pdf)
(ESOP, is, part of)
(ESOP, is, Intro to Options Plans)
...省略部分内容,感兴趣的可以直接查看原文:https://medium.aiplanet.com/implement-rag-with-knowledge-graph-and-llama-index-6a3370e93cdd

通过构建查询引擎查询知识图谱

代码语言:javascript
复制
query = "What is ESOP?"
query_engine = index.as_query_engine(include_text=True,
                                     response_mode ="tree_summarize",
                                     embedding_mode="hybrid",
                                     similarity_top_k=5,)
#
message_template =f"""<|system|>Please check if the following pieces of context has any mention of the  keywords provided in the Question.If not then don't know the answer, just say that you don't know.Stop there.Please donot try to make up an answer.</s>
<|user|>
Question: {query}
Helpful Answer:
</s>"""
#
response = query_engine.query(message_template)
#
print(response.response.split("<|assistant|>")[-1].strip())
#####OUTPUT #####################
ESOP stands for Employee Stock Ownership Plan. It is a retirement plan that allows employees to receive company stock or stock options as part of their compensation. In simpler terms, it is a plan that allows employees to own a portion of the company they work for. This can be a motivating factor for employees as they have a direct stake in the company's success. ESOPs can also be a tax-efficient way for companies to provide retirement benefits to their employees.
代码语言:javascript
复制
query ="Who is Atul?"
message_template =f"""<|system|>Please check if the following pieces of context has any mention of the  keywords provided in the Question.If not then don't know the answer, just say that you don't know.Stop there.Please donot try to make up an answer.</s>
<|user|>
Question: {query}
Helpful Answer:
</s>"""
#
response = query_engine.query(message_template)
#
print(response.response.split("<|assistant|>")[-1].strip())

################OUTPUT#####################
I do not have prior knowledge or context about who atul is. Please provide more information or context so I can assist you better. Without any further context, I do not know the answer to your question.

图形可视化

•pyvis库用于知识图的图形表示•notebook=True确保图与Jupyter笔记本兼容•cdn_resources=”in_line”指定资源的内联排列•directed=True将图定义为有向输入

代码语言:javascript
复制

from pyvis.network import Network
from IPython.display import display
g = index.get_networkx_graph()
net = Network(notebook=True,cdn_resources="in_line",directed=True)
net.from_nx(g)
net.show("graph.html")
net.save_graph("Knowledge_graph.html")
#
import IPython
IPython.display.HTML(filename="/content/Knowledge_graph.html")

数据持久化

数据保留在知识图和相关索引的构建过程中起到了至关重要的作用,特别是当它们非常复杂或需要大量计算工作时。通过持久化数据,我们可以轻松地检索未来分析所需的数据,而无需进行完全的重建。

代码语言:javascript
复制
 storage_context.persist()

保存以下信息的文件夹:

结论

总之,矢量数据库和知识图谱之间的区别在于它们存储和表示数据的方法。矢量数据库擅长于基于相似性的操作,依靠数值向量来测量实体之间的距离。另一方面,知识图谱是为了捕捉复杂的关系和依赖关系而量身定制的,通过节点和边来促进语义分析和高级推理。对于语言模型(LLM)的幻觉问题而言,知识图谱证明优于向量数据库。知识图谱提供更准确、多样、有趣、逻辑和一致性的信息,减少了LLM中出现幻觉的可能性。这种优势源于其提供关于实体之间关系的精确细节,而不仅仅指示相似性,支持更复杂的查询和逻辑推理。每种方法的有效性取决于数据的特定性质、关系的复杂程度和期望的结果。图数据库作为知识图谱的支撑,擅长分析关系和复杂网络。向量数据库则凭借其数值数组在相似度搜索和最佳匹配场景中表现突出。最终,选择哪种方法取决于项目需求,包括数据的性质、对关系探索的需求以及预期的查询类型。在进行此选择时需要考虑的关键因素包括数据的性质及其关系、复杂依赖关系的存在、查询和分析需求、对高效相似性搜索的需求以及实时应用的考虑。此外,应考虑查询语言、API和生态系统集成的可用性。总之,向量化数据库和知识图谱都有各自的优势和劣势,最佳选择取决于具体的用例。了解数据的性质和项目需求在确定是采用向量化数据库还是知识图谱来存储和表示相关信息时是至关重要的。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-12-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 山行AI 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是向量数据库?
  • 什么是知识图谱?
  • 知识图谱的主要组成部分
    • 知识图中的三元组
    • 知识图谱相比于矢量数据库在LLM幻觉方面有何优势?
      • 向量化数据库和知识图谱的区别
        • 存储和表示数据的方式不同
        • 数据存储方式不同
        • 如何选择?
        • 使用的技术栈
    • 代码实现
      • 逐步代码实现
      • 实施步骤
        • 安装所需依赖
          • 启用诊断日志记录
            • 导入必要的依赖项
              • 使用的包的简要概述
                • 设置LLM
                  • 设置嵌入模型
                    • 加载数据
                      • 构建知识图谱索引
                      • 设置服务上下文
                      • 设置存储上下文
                        • 由文档创建的知识图谱
                          • 通过构建查询引擎查询知识图谱
                            • 图形可视化
                              • 数据持久化
                              • 结论
                              相关产品与服务
                              对象存储
                              对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
                              领券
                              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档