使用知識(shí)圖譜提高RAG的能力,減少大模型幻覺(jué)
在使用大型語(yǔ)言模型(llm)時(shí),幻覺(jué)是一個(gè)常見(jiàn)的問(wèn)題。LLM生成流暢連貫的文本,但往往生成不準(zhǔn)確或不一致的信息。防止LLM產(chǎn)生幻覺(jué)的方法之一是使用提供事實(shí)信息的外部知識(shí)來(lái)源,如數(shù)據(jù)庫(kù)或知識(shí)圖譜。
向量數(shù)據(jù)庫(kù)和知識(shí)圖譜

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


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

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



































