继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

基于检索的生成技术RAG详解:图谱 vs 向量(RAG + 龙马3.1)

慕尼黑5688855
关注TA
已关注
手记 236
粉丝 8
获赞 16

检索增强生成(RAG)是一种技术,可以让大型语言模型(LLMs)变得更强大。通过提供与用户查询相关的额外信息,这一信息检索步骤增强了LLMs生成准确和全面回复的能力。RAG的工作原理如下:

  1. 用户查询:用户提出一个问题或提供一个提示。
  2. 检索:系统根据查询意图从数据库中检索相关信息。expand_more
  3. 增强:检索到的信息与用户的查询一起提供给大语言模型。expand_more
  4. 生成:大语言模型利用查询和检索到的信息来生成回复。expand_more

在RAG中有两种主要的信息检索方法:让我们来比较图RAG和向量型RAG,并分别深入了解。

Rag vs Graph Rag

RAG向量

想象一个巨大的图书馆,书籍是根据主题联系来组织的。基于向量的检索与生成(Vector RAG)使用向量数据库。这些数据库将信息(如文档或实体)表示为高维空间中的数值向量。具有相似主题或意义的文档,其向量在这个空间中会更接近。在检索过程中,Vector RAG 会在数据库中搜索与用户查询最接近的文档,从而找到与查询最相关的文档。

例如:

  • 用户提问:“法国大革命的原因是什么?”
  • 检索信息(基于向量的搜索):关于法国大革命起源的历史文献,以及关于18世纪法国社会经济情况的资料。
  • 生成的响应:LLM 将使用这些资料来解释法国大革命背后的政治、社会和经济因素。

RAG图

想象一张详细的地图,其中位置及其连接都清晰地定义了。Graph RAG 使用知识图谱。这些是用于表示实体(如人、地点或事件)及其之间关系的结构化数据库。在检索过程中,Graph RAG 根据用户的查询在知识图谱中进行遍历,识别与用户意图相关的实体和关系。这种方法提供了对检索到信息的上下文和关联的更深入理解。

例子

  • 用户提问:谁写了《魔戒》三部曲?
  • 检索信息(图搜索):J.R.R. Tolkien与《魔戒》三部曲之间存在“作者”关系。
  • 生成回复:LLM通过知识图谱识别J.R.R. Tolkien是《魔戒》三部曲的作者。

(图形RAG 与 向量RAG 的对比)

基于图的RAG和基于向量的RAG之间的关键区别在于它们表示和检索大型语言模型信息的方式。

  • 向量检索助手:可以将其视为在图书馆中查找相似的书籍。它使用向量数据库,其中信息以数值代码的形式存储。这些代码捕捉了信息的意义和主题。在检索时,向量检索助手会搜索与用户查询最接近的代码(文档、实体),从而找到与查询最相关的最相关的信息。
  • 图谱检索助手:可以想象在一张详细地图上导航以找到相连的位置。它使用知识图谱,将实体(如人物、地点和事件)及其关系进行标绘。在处理查询时,图谱检索助手会探索知识图谱,识别与用户意图相关的实体和联系。这种方法提供了对信息背景和关系更深入的理解。

主题的相关性 vs. 情境与关系,

  • 主题相关性集中在话题的相似性上。想象一下,有一份关于法国大革命的文档和另一份关于美国革命的文档。两者都讨论了革命,因此对于“革命”的查询,它们在主题上是相关的。
  • 上下文和关系则更进一步探讨。在这里,我们不仅考虑话题本身,还考虑它们之间的联系。图谱RAG中的知识图谱可能显示美国革命受到了法国革命的启发,从而提供了更丰富的上下文。

信息对比实体:

  • 信息指任何获取到的知识,范围更广。在基于向量的RAG中,检索到的信息可以是完整的文档或摘要。
  • 实体指的是信息中的特定对象或概念。在基于图的RAG中,检索到的信息主要关注识别实体(如法国大革命)及其相互之间的关系(例如,历史事件与其原因之间的关联)。

选好合适的RAG方法

选择 Vector RAG 还是 Graph RAG 完全取决于您的具体需求。Vector RAG 在大规模数据集中查找主题相关的信息方面表现出色,非常适合文档检索或产品推荐等任务。Graph RAG 更适合理解上下文和关系时表现更佳,对于问答系统或知识库完善非常有价值。此外,一些系统甚至结合了这两种方法,采用混合方法,利用各自的优势。

最终,无论是Vector RAG还是Graph RAG都代表了利用LLMs的激动人心的进展。通过向它们提供相关的信息,我们释放了它们真正的潜力,从而能够提供详尽且有洞察力的回答。

RAG图:RAG与知识图谱

知识图谱是现实世界中实体和它们之间关系的结构化表示。

它们主要由两个部分构成:节点和连线。

节点代表具体的实体,比如人、地方、物体或概念。

另一方面,边表示这些节点之间的连接,表明它们是如何连接的。

这种结构大大增强了LLM生成知情回答的能力,通过使模型能够访问精确和上下文相关的数据。

图谱RAG(Graph RAG)的创新点在于它将图数据库与大型语言模型(LLMs)结合起来,从而丰富模型的上下文信息并生成响应。

一些流行的图数据库:OntotextNebulaGraphNeo4J

一个简单的知识图

开码时间啦!

请在您的 Google Colab 中安装以下内容哦

    %pip install --upgrade --quiet  \  
        langchain-openai \  
        langchain \  
        langchain-community \  
        langchain-google-genai\  
        langchain-groq\  
        langchain-experimental\  
        networkx\  
        langchain-chroma\  
        json-repair\  
        neo4j

使用Gemini Pro生成嵌入,你可以选择任何你想要的嵌入模型。

我选择了“Rani Lakshmibai”的传记作为文本。

将文本分割成文档,并使用convert_to_graph_documents和llama 3.1通过groq api调用llm生成图文档。

使用NetworkxEntityGraph创建了一个图,然后添加了节点和边(关系)。

生成的图被添加到GraphQAChain中,并包含了llm和生成的图文档。

    from langchain_community.document_loaders import TextLoader  
    from langchain_openai import OpenAIEmbeddings  
    from langchain_text_splitters import CharacterTextSplitter  
    from langchain_google_genai import GoogleGenerativeAIEmbeddings  
    from langchain_core.documents import Document  
    from langchain_experimental.graph_transformers import LLMGraphTransformer  
    from langchain_google_genai import GoogleGenerativeAI  
    from langchain.indexes.graph import NetworkxEntityGraph  
    from langchain.chains import GraphQAChain  
    from langchain_groq import ChatGroq  
    GOOGLE_API_KEY = ""  
    GROQ_API_KEY = ""
    文本 = "拉克希米·巴依(或称拉尼·拉克希米·巴依)于1828年11月19日(一些资料记载为1835年)出生在班纳勒斯(今瓦拉纳西),出生在一个马拉地语Karhade Brahmin家庭。\  
    她的原名是Manikarnika Tambe,昵称为Manu。[8]她的父亲是Moropant Tambe[9],母亲是Bhagirathi Sapre(Bhagirathi Bai)。\  
    她的父母来自马哈拉施特拉邦拉特纳吉里区古哈加尔地区的坦贝村。\  
    她的母亲在她五岁时去世。她的父亲在加亚普兰特战争中担任指挥官。她的父亲为比托尔区的Peshwa Baji Rao II工作。\  
    Peshwa称她为\"Chhabili\",意为“美丽”和“活泼可爱”。 \  
    她在家接受教育,能够阅读和写作,比同龄人更加独立;\  
    她的学习包括射击、骑马、击剑和与童年朋友Nana Sahib和Tantia Tope一起练习的马拉卡姆巴(malla khambā)。 \  
    拉克希米·巴依与当时印度社会对女性的父权文化期待形成对比。\  
    她以其独特的视角和敢于挑战社会规范的勇气而闻名,这在当时的社会中是罕见的。\  
    拉克希米·巴依习惯于骑马陪同随从往返于宫殿与寺庙之间,有时她则乘轿子出行。\  
    她的马包括Sarangi、Pavan和巴阿达尔;根据历史学家的说法,她在1858年逃离堡垒时骑的是巴阿达尔。现在的Rani Mahal已改建成博物馆。\  
    博物馆收藏了公元9世纪至12世纪的考古遗物。"documents = [Document(page_content=文本)]llm =  ChatGroq(temperature=0, model_name="llama-3.1-70b-versatile", groq_api_key=GROQ_API_KEY)llm_transformer_filtered = LLMGraphTransformer(llm=llm,  
        allowed_nodes=["Person", "Country", "Organization"],  
        allowed_relationships=["NATIONALITY","Father","Mother", "LOCATED_IN", "WORKED_AT", "SPOUSE"],)graph_documents_filtered = llm_transformer_filtered.convert_to_graph_documents(documents)graph = NetworkxEntityGraph()#将节点添加到图中  
    for node in graph_documents_filtered[0].nodes:  
      graph.add_node(node.id)#将边添加到图中  
    for edge in graph_documents_filtered[0].relationships:  
      graph._graph.add_edge(edge.source.id,  
                            edge.target.id,  
                            relation = edge.type)  
    print(f"节点:{graph_documents_filtered[0].nodes}")  
    print(f"关系:{graph_documents_filtered[0].relationships}")  
    graph_rag =  GraphQAChain.from_llm(llm, graph=graph, verbose=True)

这是给Rag的流程,文本分割 -> 嵌入 -> 嵌入到Chroma DB -> RetrievalQA + LLM + 文档检索

    from langchain_community.document_loaders import TextLoader  
    from langchain_openai import OpenAIEmbeddings  
    from langchain_text_splitters import CharacterTextSplitter  
    from langchain_google_genai import GoogleGenerativeAIEmbeddings  
    from langchain_chroma import Chroma  
    from langchain.chains import RetrievalQA
    embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001", google_api_key=GOOGLE_API_KEY)  
    loader = TextLoader("/content/sample_data/Text_1.txt")  
    documents = loader.load()  
    text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)  
    texts = text_splitter.split_documents(documents)  
    doc_search = Chroma.from_documents(texts, embeddings)  
    base_rag = RetrievalQA.from_chain_type(  
        llm=llm,  
        chain_type="stuff",  
        retriever=doc_search.as_retriever(search_kwargs={"k": 10}),  
    )  
    prompts = ["她是谁,",  
               "拉尼·拉克希米·巴依的父亲,",  
               "拉尼·拉克希米·巴依的母亲,",  
               "曼尼卡尼卡·塔姆贝是谁,",  
               "曼尼卡尼卡·塔姆贝与拉尼·拉克希米·巴依有什么关系,",  
               "莫罗潘特·塔姆贝与曼尼卡尼卡·塔姆贝有什么关系"]
    定义空列表 prompt_rag_list = []  
    定义空列表 base_rag_list = []  
    定义空列表 graph_rag_list = []  
    对于每个 prompt, 从 prompts 中遍历:  
        prompt_rag_list 追加 prompt  
        base_rag_list 追加 base_rag 执行 prompt  
        graph_rag_list 追加 graph_rag 执行 prompt
import pandas as pd  
# 这是一段用于创建数据框的代码,其中包含了提示、基础评分和图表评分的列表。
df = pd.DataFrame({'Prompt': prompt_rag_list, 'Base Rag': base_rag_list, 'Graph Rag': graph_rag_list})  
df

拉格图对比图表:

要在 Google Colab 中运行这段代码,你需要以下密钥

Google 的 API 密钥

Groq 的 API 密钥

这样你就能了解rag和graph rag技术是怎么运作的。

快乐学习!
加油!

欢迎大家随时提意见或建议,让教学更好。

直白点 🚀

(Note: I've retained the rocket emoji as per the source text, but it can be removed if strictly following the expert suggestion to maintain consistency in colloquial zh expression.)

感谢你加入_In Plain English 社区!在你离开前,

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP