解密prompt系列41. GraphRAG真的是Silver Bullet?

风雨中的小七發表於2024-10-27

這一章我們介紹GraphRAG正規化,算著時間也是該到圖譜了,NLP每一輪新模型出來後,往往都是先研究微調,然後各種預訓練方案,接著琢磨資料,各種主動學習半監督,弱監督,無監督,再之後就到圖譜和對抗學習~

前一陣Graph RAG的風吹得呼呼的,經常被問你們也Graph RAG了麼?但Graph RAG雖好但並非RAG的Silver Bullet,它有特定適合的問題和場景,更適合作為RAG中的一路召回,用來解決實體密集,依賴全域性關係的資訊召回。所以這一章我們來聊聊GraphRAG的實現和具體解決哪些問題。

Graph RAG和Naive RAG的效果對比

  • https://graphrag-demo.deepset.ai/

我們先基於Deepset提供的Graph RAG的demo來看幾個效果對比。Demo基於美股的季報構建了圖譜,然後橫向對比同一個問題使用GPT4-O基於圖譜回答和使用樸素RAG的區別。我們來看3個Graph RAG會出現顯著優勢的問題型別

問題1:Which companies bought GPUs, write one line summary for each company

image

問題2:Compare Tesla and Apple Inc, answer the question in a structure and concise way

image

問題3: What do these reports talk about?

image

以上3個Demo展示了Graph RAG最核心的優勢和適配的場景,範圍從大到小分別是

  • Dataset Global Info:依賴資料全域性結構化資訊,回答“有哪些?”,“the best、most、top”類問題
  • Subgroup Abstract Info:依賴對全域性資料進行分類劃分,對區域性進行資訊抽象,可以回答一些衍生的“某一類,某主題”,“有幾類”問題
  • Entity and Relationship Info: 依賴實體和實體間的關聯資訊,回答“A的各個方面”,“A vs B”對比差異類問題。這裡也可以從實體延伸到文件,包括多文件和文件間的關聯絡資訊

靜態圖譜:微軟Graph RAG實現

  • https://github.com/microsoft/graphrag
  • GRAPH Retrieval-Augmented Generation: A Survey
  • From Local to Global: A Graph RAG Approach to Query-Focused Summarization

阿里的graph RAG綜述對GRAG的流程進行了分類,Graph RAG其實就是在RAG的召回內容中加入圖譜召回,來最佳化回答,主要包含以下三個部分:圖譜構建,圖資料召回,圖增強回答。所以不同Graph RAG論文的差異也主要就在以上三個部分的不同實現和排列組合,下面我們看下微軟GraphRAG的具體實現。

step1.圖譜構建

第一步是對文件進行chunking,分塊的目標是因為大模型在處理太長的上文時會導致實體抽取的召回率較低,論文對比了不同的chunk大小從600-2400字,隨著chunk變大,段落中能檢測到的實體量級會逐漸降低。

第二步是使用大模型對分段的內容進行實體抽取,通用領域直接使用以下指令進行未指定實體型別的廣義實體(entity,type,description),和實體三元組(source,target,relation)抽取,而對於垂直領域會需要依賴few-shot來提升抽取效果。這裡論文會使用模型進行多輪反思“針對抽取結果是否有未識別出的實體?”如果存在則進行補充抽取,來提升對於構建圖譜最關鍵的實體三元組抽取的召回率。

GRAPH_EXTRACTION_PROMPT = """
-Goal-
Given a text document that is potentially relevant to this activity and a list of entity types, identify all entities of those types from the text and all relationships among the identified entities.

-Steps-
1. Identify all entities. For each identified entity, extract the following information:
- entity_name: Name of the entity, capitalized
- entity_type: One of the following types: [{entity_types}]
- entity_description: Comprehensive description of the entity's attributes and activities
Format each entity as ("entity"{{tuple_delimiter}}<entity_name>{{tuple_delimiter}}<entity_type>{{tuple_delimiter}}<entity_description>)

2. From the entities identified in step 1, identify all pairs of (source_entity, target_entity) that are *clearly related* to each other.
For each pair of related entities, extract the following information:
- source_entity: name of the source entity, as identified in step 1
- target_entity: name of the target entity, as identified in step 1
- relationship_description: explanation as to why you think the source entity and the target entity are related to each other
- relationship_strength: an integer score between 1 to 10, indicating strength of the relationship between the source entity and target entity
Format each relationship as ("relationship"{{tuple_delimiter}}<source_entity>{{tuple_delimiter}}<target_entity>{{tuple_delimiter}}<relationship_description>{{tuple_delimiter}}<relationship_strength>)

3. Return output in {language} as a single list of all the entities and relationships identified in steps 1 and 2. Use **{{record_delimiter}}** as the list delimiter.

4. If you have to translate into {language}, just translate the descriptions, nothing else!

5. When finished, output {{completion_delimiter}}.

-Examples-
######################
{examples}

-Real Data-
######################
entity_types: [{entity_types}]
text: {{input_text}}
######################
output:"""

使用以上Promtp抽取出的實體結果如下

image

有了實體三元組,就可以直接進行圖譜構建了,這裡graphrag直接使用NetworkX構建無向圖。

step2.圖譜劃分和描述生成

有了圖,下一步就是如何描述圖譜資訊,在大模型之前我們更多是採用模版,來把實體和實體關係資訊轉化成文字,而在LLM時代有了更多可能。這裡微軟的特色是多了一步對圖譜進行劃分和描述。

圖譜劃分,也叫社群發現,之所以要做社群發現,其實就來自GraphRag要解決全域性主體,彙總類,關聯類的問題,而這種問題就是透過先對全域性進行層次劃分,對所有區域性主題(社群)都預先進行資訊彙總實現的,這部分資訊既包含了區域性結構資訊例如主營業務為GPU的有幾家公司,也包含了區域性語義例如抽象主題和概念。

社群發現有很多種演算法, 有基於modularity,有基於層次聚類,還有基於隨機遊走的各種演算法,這裡論文選用了Leiden,是對Louvain演算法的最佳化,也屬於modularity型別的演算法,會生成互斥的多個子圖。

針對每個子圖,會使用以下Prompt指令讓模型生成社群的相關總結,這裡一個子圖其實就對應一個topic,可以是一個事件,一個主體相關的所有資訊,一類話題等等。以下prompt除了生成summary,還會生成finding,也就對應前面提到的抽象,主題,話題型別的資訊抽象。

COMMUNITY_REPORT_SUMMARIZATION_PROMPT = """
{persona}

# Goal
Write a comprehensive assessment report of a community taking on the role of a {role}. The content of this report includes an overview of the community's key entities and relationships.

# Report Structure
The report should include the following sections:
- TITLE: community's name that represents its key entities - title should be short but specific. When possible, include representative named entities in the title.
- SUMMARY: An executive summary of the community's overall structure, how its entities are related to each other, and significant points associated with its entities.
- REPORT RATING: {report_rating_description}
- RATING EXPLANATION: Give a single sentence explanation of the rating.
- DETAILED FINDINGS: A list of 5-10 key insights about the community. Each insight should have a short summary followed by multiple paragraphs of explanatory text grounded according to the grounding rules below. Be comprehensive.

.....此處省略輸出格式和few-shot
"""

得到的針對每個社群的結構化總結如下,後面會把title+summary+findings['summary']+findings['explanation']整體拼接的文字作為該區域性資訊的總結。這裡其實是整個流程中最消耗模型的部分,並且雖然論文並未提及,但是當圖譜有新增節點資訊時,這裡的report也需要進行增量更新,需要識別到出現變更的子圖,並對應去更新子圖的report

image

step3. 圖譜資訊回答

最後就是如何使用以上資訊,當使用者的query進來,微軟的論文中採用了針對以上生成的report,全部用於回答,再對回答進行篩選的邏輯。但其實也可以先加入召回邏輯,基於使用者query去召回相關的子圖report,雖然肯定會有一些損失,但是可以大幅降低耗時和成本。微軟的實現是

  • Concatenation:把所有report打散,拼接成多個chunk,每個chunk作為一段context上文
  • Map:使用以上多個context和使用者query得到多箇中間回答,然後使用大模型對所有中間回答進行打分0-100
  • Reduce:以上打分降序,保留視窗長度限制內的所有答案拼接作為上文,使用大模型生成最終回答。

效果上論文對比了在podcast和news article資料集上,分別使用不同level的子圖生成的report作為context(C0-C3),以及直接使用圖節點資訊(TS)來對比naive RAG(SS)的效果。以下是使用大模型分別評估回答的全面性,多樣性,有用性和直接性,在以上4個評估角度上,兩兩對比的勝率。使用圖資訊的所有方案均超越naive rag~

image

LightRAG

  • https://github.com/HKUDS/LightRAG
  • LightRAG: Simple and Fast Retrieval-Augmented Generation

LightRAG是港大剛出的新RAG框架,對比微軟的graph rag實現,它更多在資訊召回層面做了最佳化。這裡我們只看下lightrag和graph rag的核心差異點:對圖索引的構建和圖資訊召回

image

在圖譜構建的環節二者基本是一致的,差異在於LightRAG為了構建召回索引,在graphRAG抽取實體和關係的Prompt指令中加入了high-level關鍵詞抽取的指令,用於抽取可以描述圖區域性抽象資訊的關鍵詞,該關鍵詞作為索引可以直接用於主題,概念等問題的資訊召回。對比微軟使用子圖report來描述區域性資訊,lightrag在抽取時使用關鍵詞來描述區域性資訊,更加輕量級,但對於範圍更大的子圖資訊描述會有不足。

GRAPH_EXTRACTION_PROMPT = """
...同上

- relationship_keywords: one or more high-level key words that summarize the overarching nature of the relationship, focusing on concepts or themes rather than specific details
Format each relationship as ("relationship"{tuple_delimiter}<source_entity>{tuple_delimiter}<target_entity>{tuple_delimiter}<relationship_description>{tuple_delimiter}<relationship_keywords>{tuple_delimiter}<relationship_strength>)

...同上
"""

而在檢索階段,lightrag加入了兩路圖資訊召回

  • low level:用於回答細節類的問題,例如誰寫了傲慢與偏見,問題專注於具體實體,關係
  • high level:用於回答全域性類,概念類問題,需要掌握全域性,抽象資訊,例如人工智慧如何影響當代教育

針對以上兩個角度,lightrag會使用指令讓大模型分別生成兩類檢索關鍵詞,一類針對具體實體進行檢索,一類針對主題概念進行檢索,對應上面實體抽取過程中生成的high level keywords,prompt和few-shot如下

image

使用以上兩類關鍵詞會分別進行兩路召回,再對資訊進行合併

  • low level:使用基於query生成low level關鍵詞,去檢索entity,因為low level針對的是實體導向的細節資訊。這裡論文是對實體進行了向量化,使用實體名稱+描述過embedding模型
  • high level:使用基於query生成的high level關鍵詞,去檢索relation,因為在前面抽取時針對關係抽取了區域性的抽象關鍵詞,而relation的向量化使用了這些關鍵詞還有關係的描述,因此主題類的區域性召回可以透過召回關係來實現

image

拼接上文和大模型回答之類的都大差不差就不細說了,感興趣的同學可以去扒拉扒拉程式碼~

想看更全的大模型論文·微調預訓練資料·開源框架·AIGC應用 >> DecryPrompt

相關文章