Combinar grafos léxicos con búsqueda vectorial

Graph RAG con LangChain y Neo4j

Adam Cowley

Manager, Developer Education at Neo4j

Usar relaciones en búsqueda semántica

¿Cómo es trabajar en Neo4j?

Un diagrama de grafo con un nodo Review y la propiedad de texto "Neo4j is a great place to work"

Graph RAG con LangChain y Neo4j

Usar relaciones en búsqueda semántica

¿Cómo es trabajar en Neo4j?

La reseña la publica una Persona con el apodo @emileifrem

Graph RAG con LangChain y Neo4j

Usar relaciones en búsqueda semántica

¿Cómo es trabajar en Neo4j?

Emil Eifrem tiene una relación WORKS_AT con un nodo Company llamado Neo4j

Graph RAG con LangChain y Neo4j

De propiedades de texto a embeddings

 

  • Crea embeddings de nodos desde la propiedad text

una escena con relaciones HAS_CHUNK hacia nodos Chunk con una propiedad de cadena

Graph RAG con LangChain y Neo4j

De propiedades de texto a embeddings

 

  • Crea embeddings de nodos desde la propiedad text
  • Búsqueda vectorial sobre embeddings
  • Usa las relaciones como contexto

Las propiedades de texto de los nodos se usan para crear un embedding

Graph RAG con LangChain y Neo4j

Neo4j como almacén vectorial

from langchain_neo4j import Neo4jVector

 

  • Neo4jVector.from_documents(): Crea nodos e índice a partir de Documents
  • Neo4jVector.from_existing_graph(): Crea un índice sobre combinaciones existentes de etiqueta y propiedad
Graph RAG con LangChain y Neo4j

Fragmentar propiedades de nodos existentes

Un grafo de conocimiento que destaca la relación HAS_SCENE del nodo Act al nodo 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: # Crear trozos a partir de scene['text']
Graph RAG con LangChain y Neo4j

Fragmentar propiedades de nodos existentes

  • Divide text por "\n\n"
  • Las acotaciones van en una línea
  • Las réplicas empiezan con el nombre del personaje
    • Las líneas siguientes contienen las palabras dichas
 Entran Sampson y Gregory armados con espadas..

SAMPSON.
Gregory, por mi palabra...
GREGORY. No, porque entonces deberíamos...
SAMPSON. Quiero decir, si estamos coléricos, desenvainaremos...
Graph RAG con LangChain y Neo4j

Fragmentar propiedades de nodos existentes

# Divide el texto en líneas
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 con LangChain y Neo4j

Fragmentar propiedades de nodos existentes

# ...Continuando el bucle sobre escenas

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 con LangChain y Neo4j

Crear un índice vectorial en un grafo existente

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 con LangChain y Neo4j

Recuperación vectorial con LCEL

# Crear recuperador
retriever = store.as_retriever()

# Invocar manualmente retriever.invoke("¿Qué piensa Romeo de Julieta?") # [ Document, Document, ... ]
Graph RAG con LangChain y Neo4j

¡Vamos a practicar!

Graph RAG con LangChain y Neo4j

Preparing Video For Download...