Combiner graphes lexicaux et recherche vectorielle

Graph RAG avec LangChain et Neo4j

Adam Cowley

Manager, Developer Education at Neo4j

Utiliser les relations dans la recherche sémantique

Qu’est-ce que cela fait de travailler chez Neo4j ?

Un diagramme de graphe avec un nœud Review et la propriété text « Neo4j is a great place to work »

Graph RAG avec LangChain et Neo4j

Utiliser les relations dans la recherche sémantique

Qu’est-ce que cela fait de travailler chez Neo4j ?

L’avis est posté par une Person avec le pseudo @emileifrem

Graph RAG avec LangChain et Neo4j

Utiliser les relations dans la recherche sémantique

Qu’est-ce que cela fait de travailler chez Neo4j ?

Emil Eifrem a une relation WORKS_AT vers un nœud Company nommé Neo4j

Graph RAG avec LangChain et Neo4j

Des propriétés texte aux embeddings

 

  • Créer des embeddings de nœuds depuis la propriété text

une scène avec des relations HAS_CHUNK vers des nœuds Chunk avec une propriété chaîne

Graph RAG avec LangChain et Neo4j

Des propriétés texte aux embeddings

 

  • Créer des embeddings de nœuds depuis la propriété text
  • Recherche vectorielle sur les embeddings
  • Utiliser les relations pour le contexte

Les propriétés textuelles des nœuds servent à créer un embedding

Graph RAG avec LangChain et Neo4j

Neo4j comme magasin vectoriel

from langchain_neo4j import Neo4jVector

 

  • Neo4jVector.from_documents(): Créer des nœuds et l’index associé à partir de Documents
  • Neo4jVector.from_existing_graph(): Créer un index sur des combinaisons existantes de label et propriété
Graph RAG avec LangChain et Neo4j

Chunker des propriétés de nœuds existantes

Un graphe de connaissances mettant en avant la relation HAS_SCENE du nœud Act vers le nœud Scene

res = graph.query("""

MATCH (s:Scene)
WHERE NOT {(s)-[:HAS_LINE]->()}
RETURN s.id AS id, s.text AS text
""")
for scene in res: # Create chunks from scene['text']
Graph RAG avec LangChain et Neo4j

Chunker des propriétés de nœuds existantes

  • Séparer text par "\n\n"
  • Les didascalies tiennent sur une ligne
  • Les répliques commencent par le nom du personnage
    • Les lignes suivantes contiennent les paroles
 Enter Sampson and Gregory armed with swords..

SAMPSON.
Gregory, on my word...
GREGORY. No, for then we should...
SAMPSON. I mean, if we be in choler, we'll draw...
Graph RAG avec LangChain et Neo4j

Chunker des propriétés de nœuds existantes

# Split text into lines
lines = [
    line.strip() for line in text.split("\n\n")

if "\n" in line
]
for line in lines: parts = line.split("\n")
character = parts[0]
text = "\n".join(parts[1:])
Graph RAG avec LangChain et Neo4j

Chunker des propriétés de nœuds existantes

# ...Continuing loop over scenes

line_node = Node(type="Line", id=f"{scene.id}-line-{i}", properties={})
character_node = Node(type="Character", id=character, properties={})


# (:Scene)-[:HAS_LINE]->(:Line) graph_document.relationships.append( Relationship(source=scene, target=line_node, type="HAS_LINE"))
# (:Line)-[:SPOKEN_BY]->(:Character) graph_document.relationships.append(Relationship( source=line_node, target=characters[character], type="SPOKEN_BY"))
Graph RAG avec LangChain et Neo4j

Créer un index vectoriel sur un graphe existant

from langchain.embeddings import init_embeddings
store = Neo4jVector.from_existing_graph(

init_embeddings("openai:text-embedding-3-small"),
url=NEO4J_URI, username=NEO4J_USERNAME, password=NEO4J_PASSWORD,
node_label="Line",
text_node_properties=["text"],
embedding_node_property="embedding",
index_name="lines",
)
Graph RAG avec LangChain et Neo4j

Récupération vectorielle avec LCEL

# Create retriever
retriever = store.as_retriever()

# Invoke manually retriever.invoke("What does Romeo think of Juliet?") # [ Document, Document, ... ]
Graph RAG avec LangChain et Neo4j

Passons à la pratique !

Graph RAG avec LangChain et Neo4j

Preparing Video For Download...