語彙グラフ

Graph RAG with LangChain and Neo4j

Adam Cowley

Manager, Developer Education at Neo4j

振り返り

結果がプロンプトに挿入され、LLM に送信する準備が整った状態

Graph RAG with LangChain and Neo4j

語彙グラフ

 

  • 非構造テキスト/文書のグラフ表現
  • 書籍や論文などの階層を保持
  • 末端レベルに生テキストを保持

ドキュメントの階層を表す図。ページへの1対多、各ページに多数のチャンクノードが関連

Graph RAG with LangChain and Neo4j

ロミオとジュリエット

序文:

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
Graph RAG with LangChain and Neo4j

ナレッジグラフとしての『ロミオとジュリエット』

 

  • 戯曲はで構成

幕ノードを強調したナレッジグラフ図

Graph RAG with LangChain and Neo4j

ナレッジグラフとしての『ロミオとジュリエット』

 

  • 戯曲はで構成
  • 幕はで構成

幕ノードから場ノードへの HAS_SCENE 関係を強調したナレッジグラフ図

Graph RAG with LangChain and Neo4j

ナレッジグラフとしての『ロミオとジュリエット』

 

  • 戯曲はで構成
  • 幕はで構成
  • 場には台詞がある

場ノードから台詞ノードへの HAS_LINE 関係を強調したナレッジグラフ図

Graph RAG with LangChain and Neo4j

ナレッジグラフとしての『ロミオとジュリエット』

 

  • 戯曲はで構成
  • 幕はで構成
  • 場には台詞がある
  • 台詞は人物が話す

台詞ノードから人物ノードへの SPOKEN_BY 関係を強調したナレッジグラフ図

Graph RAG with LangChain and Neo4j

ナレッジグラフとしての『ロミオとジュリエット』

 

  • 戯曲はで構成
  • 幕はで構成
  • 場には台詞がある
  • 台詞は人物が話す

 

→ 各台詞ノードは text と embedding のプロパティを持つ

次の関係を示すグラフ図: Act HAS_SCENE Scene, Scene HAS_LINE Line, Line SPOKEN_BY Character

Graph RAG with LangChain and Neo4j

ドキュメントの読み込み

ドキュメントローダーでメモリに読み込む:

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

ドキュメントの分割

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 )
Graph RAG with LangChain and Neo4j

ノードと関係の作成

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=[])
Graph RAG with LangChain and Neo4j

幕の抽出

parts = act_splitter.split_text(text)

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

ACT I
ACT II
ACT III
Graph RAG with LangChain and Neo4j

幕の抽出

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)
Graph RAG with LangChain and Neo4j

幕の抽出

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)
Graph RAG with LangChain and Neo4j

ノードと関係の保存

Neo4jGraph オブジェクトを使用:

graph = Neo4jGraph(
    url=NEO4J_URI, 
    username=NEO4J_USERNAME, 
    password=NEO4J_PASSWORD
)
graph.add_graph_documents([graph_doc])
Graph RAG with LangChain and Neo4j

練習しましょう!

Graph RAG with LangChain and Neo4j

Preparing Video For Download...