因為在找資料的路上,一直注意到 Vector vs Graph,我想就這兩種資料儲存格式做個比較
圖形資料庫以圖的形式存儲數據,其中包括節點(nodes)、關係(relationships)和屬性(properties),這種結構使 Neo4j 特別適合處理高度關聯的數據和複雜的查詢
向量查詢依賴關鍵字匹配和向量相似性,在複雜的資料集當中會遇到不完整或所謂膚淺的知識。而向量資料拉出來的有限的區塊很可能會成為後續 LLM 全面理解的貧頸。這邊有個推薦文章,他有提到因為在特定領域缺乏上下文,很容易在高度專業化的領域沒有好的表現。
從此篇論文我們也發現 vector RAG 方法能從知識庫找資料,幫助大型語言模型回答問題,但它不擅長回答概括整份文本的問題,而現有可以用於概括文本的方法,又難以處理 RAG 裡那麼大量的資訊
Graph RAG 擅長處理實體間的複雜關係和數據的整體結構。它利用知識圖譜來捕捉數據中的語義和層次關係,能進行更複雜的推理。
這邊有一個有趣的實作比較,他想得到 Peter Quill 的訊息,單純用 Vector ,只會得到簡單的身份、演員訊息。但使用 Graph + Vector 後,則得到了他的角色目標、身份變化等資訊。
在我們之前分享的 Langchain 中,也有 Graph 相關應用,以下一步步來看:
將問題轉換為圖形數據庫查詢
from langchain_community.graphs import Neo4jGraph
graph = Neo4jGraph()
# Import movie information
movies_query = """
LOAD CSV WITH HEADERS FROM
'https://raw.githubusercontent.com/tomasonjo/blog-datasets/main/movies/movies_small.csv'
AS row
MERGE (m:Movie {id:row.movieId})
SET m.released = date(row.released),
m.title = row.title,
m.imdbRating = toFloat(row.imdbRating)
FOREACH (director in split(row.director, '|') |
MERGE (p:Person {name:trim(director)})
MERGE (p)-[:DIRECTED]->(m))
FOREACH (actor in split(row.actors, '|') |
MERGE (p:Person {name:trim(actor)})
MERGE (p)-[:ACTED_IN]->(m))
FOREACH (genre in split(row.genres, '|') |
MERGE (g:Genre {name:trim(genre)})
MERGE (m)-[:IN_GENRE]->(g))
"""
執行圖形數據庫查詢
print(graph.query(movies_query))
你會得到 []。
如果你執行遇到 APOC 的問題,請參考這篇最下面解法
ValueError: Could not use APOC procedures. Please ensure the APOC plugin is installed in Neo4j and that 'apoc.meta.data()' is allowed in Neo4j configuration
MATCH (p:Person)-[:ACTED_IN]->(m:Movie {title: 'Casino'}) RETURN p.name
Full Context:
[{'p.name': 'James Woods'}, {'p.name': 'Joe Pesci'}, {'p.name': 'Robert De Niro'}, {'p.name': 'Sharon Stone'}]
> Finished chain.