詞彙圖

使用 LangChain 與 Neo4j 的 Graph RAG

Adam Cowley

Manager, Developer Education at Neo4j

重點回顧

結果被注入提示,準備送到 LLM

使用 LangChain 與 Neo4j 的 Graph RAG

詞彙圖

 

  • 非結構化文字與文件的圖形表示法
  • 儲存書籍、研究論文等的階層結構表示
  • 最細層級儲存原始文字

一張圖示,呈現文件的階層:與頁面的 1 對多關係,每頁有多個區塊節點

使用 LangChain 與 Neo4j 的 Graph RAG

羅密歐與茱麗葉

導言:

The Project Gutenberg eBook of Romeo and Juliet

This ebook is for the use of anyone anywhere in the United States and
most other parts of the world at no cost and with almost no restrictions

Title: Romeo and Juliet
Author: William Shakespeare

角色資訊:

Dramatis Personæ

ESCALUS, Prince of Verona.
MERCUTIO, kinsman to the Prince, and friend to Romeo.
PARIS, a young Nobleman, kinsman to the Prince.
Page to Paris.
...

序幕:

 Enter Chorus.

CHORUS.
Two households, both alike in dignity,
In fair Verona, where we lay our scene,
From ancient grudge break to new mutiny,
...

幕與場次:

ACT I
SCENE I. A public place.
 Enter Sampson and Gregory armed with swords and bucklers.

SAMPSON.
Gregory, on my word, we'll not carry coals.

GREGORY.
No, for then we should be colliers...
1 https://gutenberg.org/ebooks/1513
使用 LangChain 與 Neo4j 的 Graph RAG

以知識圖表示《羅密歐與茱麗葉》

 

  • 劇本由 Act(幕) 組成

一張知識圖,突顯 Act 節點

使用 LangChain 與 Neo4j 的 Graph RAG

以知識圖表示《羅密歐與茱麗葉》

 

  • 劇本由 Act(幕) 組成
  • 每幕包含 Scene(場)

一張知識圖,突顯從 Act 到 Scene 的 HAS_SCENE 關係

使用 LangChain 與 Neo4j 的 Graph RAG

以知識圖表示《羅密歐與茱麗葉》

 

  • 劇本由 Act(幕) 組成
  • 每幕包含 Scene(場)
  • 每場有 Line(台詞)

一張知識圖,突顯從 Scene 到 Line 的 HAS_LINE 關係

使用 LangChain 與 Neo4j 的 Graph RAG

以知識圖表示《羅密歐與茱麗葉》

 

  • 劇本由 Act(幕) 組成
  • 每幕包含 Scene(場)
  • 每場有 Line(台詞)
  • Character(角色) 說出台詞

一張知識圖,突顯從 Line 到 Character 的 SPOKEN_BY 關係

使用 LangChain 與 Neo4j 的 Graph RAG

以知識圖表示《羅密歐與茱麗葉》

 

  • 劇本由 Act(幕) 組成
  • 每幕包含 Scene(場)
  • 每場有 Line(台詞)
  • Character(角色) 說出台詞

 

→ 每個 Line 節點都會有文字與 embedding 屬性

一張圖形,顯示以下關係:Act HAS_SCENE Scene、Scene HAS_LINE Line、Line SPOKEN_BY Character

使用 LangChain 與 Neo4j 的 Graph RAG

載入文件

使用文件載入器把文件載入記憶體:

# Load the PDF
loader = PyPDFLoader("romeo-and-juliet.pdf")
pages = loader.load()
使用 LangChain 與 Neo4j 的 Graph RAG

切分文件

act_splitter = RecursiveCharacterTextSplitter(
    # Split text into acts
    separators=[ r"\n\nTHE PROLOGUE.",  r"\n\nACT", r"\n\n\*\*\* END"],
    is_separator_regex=True
)

scene_splitter = RecursiveCharacterTextSplitter( # Split act into scenes separators=[r"\nSCENE "], is_separator_regex=True )
使用 LangChain 與 Neo4j 的 Graph RAG

建立節點與關係

play = Node(

type="Play",
id="romeo-and-juliet",
properties={ "title": "Romeo and Juliet", "playwright": "William Shakespeare", "genres": ["Romance", "Tragedy"] }
)
# Store in a graph document graph_doc = GraphDocument(nodes=[play], relationships=[])
使用 LangChain 與 Neo4j 的 Graph RAG

擷取幕別(Acts)

parts = act_splitter.split_text(text)

for act in parts: print(act[:20])
THE PROLOGUE...

ACT I
ACT II
ACT III
使用 LangChain 與 Neo4j 的 Graph RAG

擷取幕別(Acts)

parts = act_splitter.split_text(text)

for a, act in enumerate(parts):

first_line = act_text.split("\n")[0].strip()
if first_line.startswith("ACT"):
act_node = Node(
type="Act",
id=first_line,
)
graph_doc.nodes.append(act_node)
使用 LangChain 與 Neo4j 的 Graph RAG

擷取幕別(Acts)

for a, act in enumerate(parts):
    # ...
    # act_node = Node(...)


# Create a relationship relationship = Relationship(
source=play,
target=act_node,
type="HAS_ACT",
properties=dict(order=a)
)
graph_doc.relationships.append(relationship)
使用 LangChain 與 Neo4j 的 Graph RAG

儲存節點與關係

使用 Neo4jGraph 物件:

graph = Neo4jGraph(
    url=NEO4J_URI, 
    username=NEO4J_USERNAME, 
    password=NEO4J_PASSWORD
)
graph.add_graph_documents([graph_doc])
使用 LangChain 與 Neo4j 的 Graph RAG

一起來練習吧!

使用 LangChain 與 Neo4j 的 Graph RAG

Preparing Video For Download...