词汇图

使用 LangChain 和 Neo4j 的 Graph RAG

Adam Cowley

Manager, Developer Education at Neo4j

回顾

结果被注入到提示中,准备发送给 LLM

使用 LangChain 和 Neo4j 的 Graph RAG

词汇图

 

  • 非结构化文本与文档的图表示
  • 存储书籍、论文等的层级结构表示
  • 细粒度层级存原始文本

展示文档层级:文档到页面的一对多关系,每页关联多个分块节点的示意图

使用 LangChain 和 Neo4j 的 Graph RAG

Romeo and Juliet

Introduction:

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

Character Information:

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.
...

Prologue:

 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 and Scenes:

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

将《罗密欧与朱丽叶》建成知识图

 

  • 戏剧由 Acts 组成

突出显示 Act 节点的知识图示意图

使用 LangChain 和 Neo4j 的 Graph RAG

将《罗密欧与朱丽叶》建成知识图

 

  • 戏剧由 Acts 组成
  • Act 包含 Scenes

突出显示从 Act 节点到 Scene 节点的 HAS_SCENE 关系的知识图

使用 LangChain 和 Neo4j 的 Graph RAG

将《罗密欧与朱丽叶》建成知识图

 

  • 戏剧由 Acts 组成
  • Act 包含 Scenes
  • Scene 含有 Lines

突出显示从 Scene 节点到 Line 节点的 HAS_LINE 关系的知识图

使用 LangChain 和 Neo4j 的 Graph RAG

将《罗密欧与朱丽叶》建成知识图

 

  • 戏剧由 Acts 组成
  • Act 包含 Scenes
  • Scene 含有 Lines
  • Line 由 Characters 说出

突出显示从 Line 节点到 Character 节点的 SPOKEN_BY 关系的知识图

使用 LangChain 和 Neo4j 的 Graph RAG

将《罗密欧与朱丽叶》建成知识图

 

  • 戏剧由 Acts 组成
  • Act 包含 Scenes
  • Scene 含有 Lines
  • Line 由 Characters 说出

 

→ 每个 Line 节点都有文本与向量嵌入属性

展示以下关系的图: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

提取 Act

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

提取 Act

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

提取 Act

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...