Combiner des graphes lexicaux avec la recherche vectorielle

Graph RAG avec LangChain et Neo4j

Adam Cowley

Manager, Developer Education at Neo4j

Exploiter les relations en recherche sémantique

Comment est-ce de travailler chez Neo4j ?

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

Graph RAG avec LangChain et Neo4j

Exploiter les relations en recherche sémantique

Comment est-ce de travailler chez Neo4j ?

L'évaluation est publiée par une personne dont le nom d'utilisateur est @emileifrem

Graph RAG avec LangChain et Neo4j

Exploiter les relations en recherche sémantique

Comment est-ce 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 de texte aux plongements

 

  • Créer des plongements de nœuds à partir de 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 de texte aux plongements

 

  • Créer des plongements de nœuds à partir de text
  • Recherche vectorielle sur les plongements
  • Utiliser les relations pour le contexte

Les propriétés de texte sur les nœuds servent à créer un plongement

Graph RAG avec LangChain et Neo4j

Neo4j comme entrepôt vectoriel

from langchain_neo4j import Neo4jVector

 

  • Neo4jVector.from_documents(): créer des nœuds et l'index sous-jacent à partir de Documents
  • Neo4jVector.from_existing_graph(): créer un index sur des combinaisons d'étiquettes et de propriétés existantes
Graph RAG avec LangChain et Neo4j

Découper des propriétés de nœuds existantes en segments

Un diagramme de graphe de connaissances mettant en évidence 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

Découper des propriétés de nœuds existantes en segments

  • 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

Découper des propriétés de nœuds existantes en segments

# 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

Découper des propriétés de nœuds existantes en segments

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

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