使用知識圖譜提高RAG的能力,減少大模型幻覺
在使用大型語言模型(llm)時,幻覺是一個常見的問題。LLM生成流暢連貫的文本,但往往生成不準確或不一致的信息。防止LLM產生幻覺的方法之一是使用提供事實信息的外部知識來源,如數據庫或知識圖譜。
向量數據庫和知識圖譜

向量數據庫
向量數據庫是表示實體或概念(如單詞、短語或文檔)的高維向量的集合。數據庫可用于測量不同實體或概念之間的相似性或相關性,基于它們的向量表示。
例如,一個向量數據庫可以根據“巴黎”和“法國”的向量距離告訴你,“巴黎”和“法國”比“巴黎”和“德國”更相關。
查詢向量數據庫通常涉及搜索相似的向量或 檢索基于特定標準的向量。下面是一個如何查詢向量數據庫的簡單示例:
讓我們假設有一個向量數據庫,其中包含以高維向量表示的客戶配置文件,并且您希望找到與給定參考客戶相似的客戶。
1、首先為參考客戶定義一個向量表示。這可以通過提取相關特征或屬性并將其轉換為向量格式來實現。
2、使用合適的算法,如k近鄰(k-NN)或余弦相似度,在向量數據庫中執行相似度搜索。該算法將根據參考客戶向量的相似度分數來識別最近鄰。
3、檢索與上一步中確定的最近鄰向量相對應的客戶配置文件。這些概要文件將根據定義的相似性度量表示與參考客戶相似的客戶。
4、向用戶顯示檢索到的客戶配置文件或相關信息,例如顯示他們的姓名、人口統計數據或購買歷史記錄。
知識圖譜
知識圖譜是表示實體或概念及其關系(如事實、屬性或類別)的節點和邊的集合?;谒鼈兊墓濣c和邊緣屬性,可用于查詢或推斷關于不同實體或概念的事實信息。
例如,一個知識圖可以根據邊緣標簽告訴你“巴黎”是“法國”的首都。
查詢圖數據庫涉及遍歷圖結構并根據特定標準檢索節點、關系或模式。
假設你有一個表示社交網絡的圖數據庫,其中用戶是節點,他們的關系表示為連接節點的邊。如果為給定用戶找到朋友的朋友(共同聯系),那么我們應該進行如下操作:
1、在圖數據庫中標識表示參考用戶的節點。這可以通過查詢特定的用戶標識符或其他相關標準來實現。
2、使用圖查詢語言,例如Cypher(在Neo4j中使用)或Gremlin,從參考用戶節點遍歷圖。指定要探索的模式或關系。
MATCH (:User {userId:
‘referenceUser’})-[:FRIEND]->()-[:FRIEND]->(fof:User) RETURN fof這個查詢從參考用戶開始,沿著FRIEND關系找到另一個節點(FRIEND),然后沿著另一個FRIEND關系找到朋友的朋友(fof)。
3、對圖數據庫執行查詢,根據查詢模式檢索結果節點(朋友的朋友),可以獲得關于檢索節點的特定屬性或其他信息。
圖數據庫可以提供更高級的查詢功能,包括過濾、聚合和復雜的模式匹配。具體的查詢語言和語法可能會有所不同,但一般的過程涉及遍歷圖結構以檢索符合所需標準的節點和關系。
知識圖譜解決“幻覺”問題的優勢
知識圖譜比向量數據庫提供更精確和具體的信息。向量數據庫表示兩個實體或概念之間的相似性或相關性,而知識圖可以更好地理解它們之間的關系。例如知識圖譜可以告訴你“埃菲爾鐵塔”是“巴黎”的地標,而向量數據庫只能表明這兩個概念的相似程度,但是具體他們之間如何相關的卻沒有說明。
知識圖支持比向量數據庫更多樣化、更復雜的查詢。向量數據庫主要可以回答基于向量距離、相似性或最近鄰的查詢,這些查詢僅限于直接的相似性測量。而知識圖可以處理基于邏輯運算符的查詢,例如“具有屬性Z的所有實體是什么?”或“W和V的共同范疇是什么?”這可以幫助LLM產生更多樣化和有趣的文本。
知識圖比向量數據庫更能進行推理和推斷。向量數據庫只能提供存儲在數據庫中的直接信息。而知識圖可以提供從實體或概念之間的關系派生的間接信息。例如,一個知識圖譜可以根據“巴黎是法國的首都”和“法國位于歐洲”這兩個事實推斷出“埃菲爾鐵塔位于歐洲”。這可以幫助LLM生成更具邏輯性和一致性的文本。
所以知識圖譜是一個比向量數據庫更好的解決方案。可以為LLM提供了更準確、相關、多樣、有趣、合乎邏輯和一致的信息,使它們更可靠地生成準確和真實的文本。但這里的關鍵是文檔文檔之間需要有清晰的關系,否則知識圖譜將無法捕捉到它。
但是,知識圖譜的使用并沒有向量數據庫那么直接簡單,不僅在內容的梳理(數據),應用部署,查詢生成等方面都沒有向量數據庫那么方便,這也影響了它在實際應用中的使用頻率。所以下面我們使用一個簡單的例子來介紹如何使用知識圖譜構建RAG。
代碼實現
我們需要使用3個主要工具/組件:
1、LlamaIndex是一個編排框架,它簡化了私有數據與公共數據的集成,它提供了數據攝取、索引和查詢的工具,使其成為生成式人工智能需求的通用解決方案。
2、嵌入模型將文本轉換為文本所提供的一條信息的數字表示形式。這種表示捕獲了所嵌入內容的語義含義,使其對于許多行業應用程序都很健壯。這里使用“thenlper/gte-large”模型。
3、需要大型語言模型來根據所提供的問題和上下文生成響應。這里使用Zephyr 7B beta模型
下面我們開始進行代碼編寫,首先安裝包
%%capture
pip install llama_index pyvis Ipython langchain pypdf啟用日志Logging Level設置為“INFO”,我們可以輸出有助于監視應用程序操作流的消息
import logging
import sys
#
logging.basicConfig(stream=sys.stdout, level=logging.INFO)
logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))導入依賴項
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我們使用Huggingface推理api端點載入LLM
HF_TOKEN = "api key DEEPHUB 123456"
llm = HuggingFaceInferenceAPI(
model_name="HuggingFaceH4/zephyr-7b-beta", token=HF_TOKEN
)首先載入嵌入模型:
embed_model = LangchainEmbedding(
HuggingFaceInferenceAPIEmbeddings(api_key=HF_TOKEN,model_name="thenlper/gte-large")
)加載數據集
documents = SimpleDirectoryReader("/content/Documents").load_data()
print(len(documents))
####Output###
44構建知識圖譜索引
創建知識圖譜通常涉及專業和復雜的任務。通過利用Llama Index (LLM)、KnowledgeGraphIndex和GraphStore,可以方便地任何數據源創建一個相對有效的知識圖譜。
#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:切換在索引中包含嵌入以進行高級分析。
通過構建查詢引擎對知識圖譜進行查詢
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.可以看到,輸出的結果已經很好了,可以說與向量數據庫的結果非常一致。
最后還可以可視化我們生成的圖譜,使用Pyvis庫進行可視化展示
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")


通過上面的代碼我們可以直接通過LLM生成知識圖譜,這樣簡化了我們非常多的人工操作。如果需要更精準更完整的知識圖譜,還需要人工手動檢查,這里就不細說了。
數據存儲,通過持久化數據,可以將結果保存到硬盤中,供以后使用。
storage_context.persist()存儲的結果如下:

總結
向量數據庫和知識圖譜的區別在于它們存儲和表示數據的方法。向量數據庫擅長基于相似性的操作,依靠數值向量來測量實體之間的距離。知識圖譜通過節點和邊緣捕獲復雜的關系和依賴關系,促進語義分析和高級推理。
對于語言模型(LLM)幻覺,知識圖被證明優于向量數據庫。知識圖譜提供了更準確、多樣、有趣、有邏輯性和一致性的信息,減少了LLM產生幻覺的可能性。這種優勢源于它們能夠提供實體之間關系的精確細節,而不僅僅是表明相似性,從而支持更復雜的查詢和邏輯推理。
在以前知識圖譜的應用難點在于圖譜的構建,但是現在LLM的出現簡化了這個過程,使得我們可以輕松的構建出可用的知識圖譜,這使得他在應用方面又向前邁出了一大步。對于RAG,知識圖譜是一個非常好的應用方向。



































