Un pipeline GraphRAG completamente local con LangExtract, Neo4j, Qdrant y Ollama
Construir GraphRAG con modelos locales: extraer entidades con LangExtract, almacenarlas en Neo4j, indexarlas en Qdrant y luego expandir subgrafos para obtener respuestas basadas en grafos.
Fuentes: A Practical GraphRAG Architecture Using LangExtract, Neo4j, Qdrant, and Ollama
Esta versión es un sistema GraphRAG que funciona íntegramente con modelos locales. Los componentes son Ollama para los modelos de lenguaje y de incrustación, Neo4j para el grafo, Qdrant para la búsqueda vectorial y LangExtract para extraer estructura del texto. En lugar de obtener fragmentos de documentos como lo hace el RAG tradicional, convierte el texto en bruto en un grafo de conocimiento y recupera entidades semánticamente cercanas a una pregunta, para luego seguir las relaciones que existen entre ellas.
La pieza clave de este diseño es LangExtract, que identifica entidades y relaciones en texto no estructurado y las devuelve en un formato que el grafo puede almacenar. Qdrant aporta significado mediante la similitud vectorial, mientras que Neo4j aporta contexto a través del recorrido de las relaciones. Juntos forman un pipeline de recuperación que tiene en cuenta tanto el tema de la pregunta como cómo se conectan los hechos.
Cómo fluye la arquitectura
El texto en bruto ingresa primero a la capa LangExtract. Los pipelines convencionales dividirían de inmediato los documentos en fragmentos y los incrustarían. Aquí, el texto se convierte en conocimiento estructurado antes que nada más. LangExtract, respaldado por un modelo alojado en Ollama, identifica las entidades y las relaciones entre ellas. El ejemplo utilizado son datos de medicamentos: se extraen los fármacos, las dosis, las frecuencias y las condiciones médicas, y sus conexiones se mantienen mediante un agrupamiento compartido. El lenguaje natural pasa a ser un registro estructurado de hechos y no un montón de pasajes almacenados.
A continuación, las entidades y relaciones extraídas se convierten en partes del grafo. Cada concepto se transforma en un nodo con un ID único, mientras que relaciones como la dosis, la frecuencia o la condición se convierten en aristas explícitas entre los nodos. La información ahora está organizada en torno a las entidades y sus conexiones, no alrededor de los límites del documento, lo que permite conservar el contexto que normalmente se perdería con un método de recuperación basado en fragmentos.
Luego, el grafo se carga en Neo4j, el principal almacenamiento de conocimiento estructurado. Las entidades se convierten en nodos y las relaciones en aristas nativas. Dado que Neo4j puede recorrer eficientemente los conceptos conectados, el sistema puede seguir posteriormente rutas de múltiples saltos y mostrar el contexto que se encuentra más allá del punto donde comenzó la extracción.
Una vez creado el grafo, se genera un embedding para cada nodo. El modelo de embedding lee directamente los nombres de las entidades y los conceptos, en lugar de documentos completos o fragmentos. El resultado es un índice semántico sobre las entidades del grafo, de modo que la recuperación se centra en los conceptos en lugar de en pasajes completos.
Dichos vectores se introducen en Qdrant junto con los IDs de los nodos correspondientes de Neo4j. Qdrant funciona como la capa semántica rápida, mientras que Neo4j sigue siendo la estructurada. Dado que cada carga de trabajo de Qdrant contiene un ID de nodo de Neo4j, un hit vectorial se relaciona directamente con una entidad del grafo. Esta división permite que cada base de datos haga lo que mejor sabe hacer: la búsqueda por similitud en una, y el recorrido de relaciones y el razonamiento gráfico en la otra.
En el momento de la consulta, un usuario plantea una pregunta en lenguaje natural. El mismo modelo de embedding la convierte en un vector, el cual se busca en Qdrant para encontrar las entidades del grafo más relevantes. En lugar de fragmentos de documentos, la búsqueda devuelve identificadores de nodos. Dichos nodos sirven como puntos de entrada semánticos al grafo, representando los conceptos más cercanos a lo que desea el usuario.
Los identificadores luego generan una consulta en Neo4j. En lugar de detenerse en las entidades coincidentes, el sistema se expande hacia nodos y relaciones vecinas y recopila un subgrafo relevante que incluye tanto las coincidencias como su contexto circundante. Esta expansión permite obtener hechos de apoyo que la similitud vectorial por sí sola no habría encontrado, de modo que el contexto aporta tanto relevancia semántica como estructura.
El subgráfico se remodela a continuación para un modelo de lenguaje. Los nodos se agrupan en una lista estructurada, y las relaciones se convierten en triples legibles que indican conexiones explícitas, como dosis de Lisinopril 10 mg o uso de Metformin en la diabetes. Este paso conecta las bases de datos de grafos con los modelos de lenguaje al transformar la estructura del grafo en texto que el modelo puede interpretar.
Finalmente, el contexto del grafo formateado se envía al LLM. El modelo recibe entidades y relaciones, y no fragmentos recuperados, por lo que puede razonar sobre los hechos expuestos sin necesidad de inferir conexiones a partir de pasajes fragmentados. Dado que el contexto proviene del recorrido del grafo, también es más explicable y trazable que la recuperación vectorial habitual.
En conjunto, se trata de un sistema híbrido de recuperación de información. LangExtract se encarga de la extracción de conocimiento, Neo4j gestiona las relaciones estructuradas, Qdrant recupera entidades de forma semántica, y el LLM razona sobre un contexto basado en grafos. Al combinar la similitud con el recorrido por los grafos, se responden las preguntas a partir de conocimientos interconectados y no de fragmentos de texto aislados. Eso hace que este enfoque sea especialmente eficaz en campos como la salud, las finanzas, el derecho, la gestión de conocimiento empresarial e investigación científica, donde las relaciones entre entidades suelen ser más importantes que cualquier pasaje individual.
Método por método
__init__() es el punto de entrada de todo el sistema. Lee la configuración desde variables de entorno, que incluyen las credenciales de Neo4j, los detalles de conexión a Qdrant y la configuración de Ollama. Establece conexiones con Neo4j y Qdrant que el resto del proceso reutiliza, y crea el cliente de Ollama necesario para la extracción, las representaciones vectoriales y la síntesis de respuestas. Los nombres de los modelos y las dimensiones vectoriales se almacenan como parámetros, lo que permite mantener la configuración adaptable.
def __init__(self,env_path: str = ".env",ollama_model_extract: str = "gemma3:latest",
ollama_model_answer: str = "gemma3:latest",ollama_embedding_model: str = "embeddinggemma:latest",
ollama_host: str | None = None,vector_dimension: int = 768,
):
load_dotenv(env_path)
self.qdrant_key = os.getenv("QDRANT_KEY")
self.qdrant_url = os.getenv("QDRANT_URL")
self.neo4j_uri = os.getenv("NEO4J_URI")
self.neo4j_username = os.getenv("NEO4J_USERNAME")
self.neo4j_password = os.getenv("NEO4J_PASSWORD")
self.neo4j_driver = GraphDatabase.driver(
self.neo4j_uri, auth=(self.neo4j_username, self.neo4j_password)
)
self.qdrant_client = QdrantClient(
url=self.qdrant_url,
api_key=self.qdrant_key,
)
# Ollama client for local embeddings (embeddinggemma:latest)
self.ollama_client = ollama.Client(host=ollama_host) if ollama_host else ollama.Client()
# langextract needs a plain URL string, not a client object
self.ollama_url = ollama_host or os.environ.get("OLLAMA_HOST", "http://localhost:11434")
# Model / config knobs
self.ollama_model_extract = ollama_model_extract
self.ollama_model_answer = ollama_model_answer
self.ollama_embedding_model = ollama_embedding_model
self.vector_dimension = vector_dimension
extract_graph_components() convierte el texto en bruto en conocimiento estructurado. Proporciona instrucciones de extracción junto con ejemplos que guían a LangExtract hacia las entidades y relaciones adecuadas. Un modelo alojado en Ollama procesa luego la entrada y extrae medicamentos, dosis, frecuencias y condiciones. Lo que se obtiene sigue siendo un conjunto de elementos extraídos y no un grafo, por lo que el método los pasa a otro proceso para la construcción del grafo.
def extract_graph_components(self, raw_data: str):
"""Extract medication entities and relationships using langextract + Ollama."""
prompt_description = textwrap.dedent("""
Extract medications with their details, using attributes to group related information:
1. Extract entities in the order they appear in the text
2. Each entity must have a 'medication_group' attribute linking it to its medication
3. All details about a medication should share the same medication_group value
""").strip()
examples = [
lx.data.ExampleData(
text=(
"Patient takes Aspirin 100mg daily for heart health and"
" Simvastatin 20mg at bedtime."
),
extractions=[
lx.data.Extraction(
extraction_class="medication",
extraction_text="Aspirin",
attributes={"medication_group": "Aspirin"},
),
lx.data.Extraction(
extraction_class="dosage",
extraction_text="100mg",
attributes={"medication_group": "Aspirin"},
),
lx.data.Extraction(
extraction_class="frequency",
extraction_text="daily",
attributes={"medication_group": "Aspirin"},
),
lx.data.Extraction(
extraction_class="condition",
extraction_text="heart health",
attributes={"medication_group": "Aspirin"},
),
lx.data.Extraction(
extraction_class="medication",
extraction_text="Simvastatin",
attributes={"medication_group": "Simvastatin"},
),
lx.data.Extraction(
extraction_class="dosage",
extraction_text="20mg",
attributes={"medication_group": "Simvastatin"},
),
lx.data.Extraction(
extraction_class="frequency",
extraction_text="at bedtime",
attributes={"medication_group": "Simvastatin"},
),
],
)
]
result = lx.extract(
text_or_documents=raw_data,
prompt_description=prompt_description,
examples=examples,
model_id=self.ollama_model_extract,
model_url=self.ollama_url,
resolver_params={"format_handler": lx_ollama.OLLAMA_FORMAT_HANDLER},
max_char_buffer=4000,
show_progress=True,
)
return self._convert_extractions_to_graph(result.extractions)
_convert_extractions_to_graph() transforma las extracciones en formato de grafo. Agrupa los elementos relacionados entre sí y elige la entidad principal de cada grupo como nodo de anclaje. Cada nodo recibe un identificador único para que Neo4j y Qdrant mantengan coherencia. A continuación, los bordes conectan los nodos de anclaje con sus atributos, preservando así el significado original. El resultado es un conjunto de nodos y bordes listo para ser utilizado en una base de datos de grafo.
def _convert_extractions_to_graph(self, extractions: list):
"""Convert langextract's flat, grouped extractions into (nodes, relationships)."""
groups: dict[str, list] = {}
for ext in extractions:
if not ext.attributes or "medication_group" not in ext.attributes:
continue
group_name = ext.attributes["medication_group"]
groups.setdefault(group_name, []).append(ext)
nodes: dict[str, str] = {}
relationships: list[dict] = []
for group_name, group_extractions in groups.items():
anchor_ext = next(
(e for e in group_extractions if e.extraction_class == "medication"),
None,
)
# Fall back to the group name itself if no explicit "medication"
# extraction was found in this group, so we still get an anchor.
anchor_text = anchor_ext.extraction_text if anchor_ext else group_name
if anchor_text not in nodes:
nodes[anchor_text] = str(uuid.uuid4())
for ext in group_extractions:
if ext is anchor_ext:
continue
target_text = ext.extraction_text
if target_text not in nodes:
nodes[target_text] = str(uuid.uuid4())
relationships.append(
{
"source": nodes[anchor_text],
"target": nodes[target_text],
"type": ext.extraction_class,
}
)
return nodes, relationships
ingest_to_neo4j() escribe el grafo en Neo4j, donde cada entidad se almacena como un nodo y cada relación como un arista. Esa estructura permite un recorrido y exploración eficientes posteriormente. Cada nodo mantiene su identificador único, lo que le permite vincularse con los resultados de la búsqueda vectorial. Cuando el método finaliza, el grafo se convierte en el almacén estructurado de conocimientos del sistema.
def ingest_to_neo4j(self, nodes: dict, relationships: list):
"""
Ingest nodes and relationships into Neo4j.
"""
with self.neo4j_driver.session() as session:
# Create nodes in Neo4j
for name, node_id in nodes.items():
session.run(
"CREATE (n:Entity {id: $id, name: $name})",
id=node_id,
name=name,
)
# Create relationships in Neo4j, using the semantic type
# (dosage/frequency/condition/etc.) as the actual relationship
# label instead of a generic "RELATIONSHIP" type.
for relationship in relationships:
rel_type = self._sanitize_relationship_type(relationship["type"])
session.run(
"MATCH (a:Entity {id: $source_id}), (b:Entity {id: $target_id}) "
f"CREATE (a)-[:{rel_type} {{type: $type}}]->(b)",
source_id=relationship["source"],
target_id=relationship["target"],
type=relationship["type"],
)
return nodes
_sanitize_relationship_type() existe porque los nombres de las relaciones provienen de la salida de los LLM y pueden contener caracteres inválidos o formatos inusuales. Este método limpia y estandariza las etiquetas antes de que lleguen a Neo4j, generando identificadores en mayúsculas seguros que cumplen con las reglas de Cypher. También protege contra nombres mal formados y los problemas en las consultas que podrían causar. Aunque es un método sencillo, ayuda a mantener el grafo en buen estado.
@staticmethod
def _sanitize_relationship_type(raw_type: str) -> str:
"""
Cypher relationship types can't be passed as query parameters, so
they have to be interpolated into the query string directly. Since
raw_type comes from LLM-extracted text, sanitize it to a safe
UPPER_SNAKE_CASE identifier before interpolation, to avoid Cypher
injection or syntax errors from unexpected characters.
"""
safe = "".join(ch if ch.isalnum() else "_" for ch in raw_type.strip())
safe = safe.upper().strip("_") or "RELATIONSHIP"
if safe[0].isdigit():
safe = f"REL_{safe}"
return safe
create_collection() se asegura de que exista una colección en Qdrant antes de almacenar cualquier vector. Verifica si la colección especificada ya está presente y la crea en caso contrario, configurando la dimensión del vector y la métrica de similitud que se utilizará en la recuperación. Este control previo evita crear colecciones innecesariamente y deja el layer de vectores listo antes de que comience la ingesta.
def create_collection(self, collection_name: str, vector_dimension: int = None):
vector_dimension = vector_dimension or self.vector_dimension
try:
# Try to fetch the collection status
self.qdrant_client.get_collection(collection_name)
print(f"Skipping creating collection; '{collection_name}' already exists.")
except Exception as e:
# If collection does not exist, an error will be thrown, so we create the collection
if "Not found: Collection" in str(e) or "doesn't exist" in str(e) or "404" in str(e):
print(f"Collection '{collection_name}' not found. Creating it now...")
self.qdrant_client.create_collection(
collection_name=collection_name,
vectors_config=models.VectorParams(
size=vector_dimension, distance=models.Distance.COSINE
),
)
print(f"Collection '{collection_name}' created successfully.")
else:
print(f"Error while checking collection: {e}")
ollama_embeddings() genera vectores densos con el modelo de embeddings de Ollama. Cada entidad del grafo y cada consulta de usuario pasan por él. Los vectores expresan el significado de forma numérica para que puedan compararse eficientemente, lo cual permite la búsqueda por similitud en Qdrant. En efecto, este método funciona como puente entre el lenguaje natural y la recuperación de vectores.
def ollama_embeddings(self, text: str) -> list[float]:
response = self.ollama_client.embeddings(
model=self.ollama_embedding_model,
prompt=text,
)
return response["embedding"]
ingest_to_qdrant() crea un embedding para cada entidad una vez que existen los nodos del grafo y lo almacena en Qdrant. Junto con cada vector, también guarda metadatos, específicamente el identificador del nodo de Neo4j y el nombre de la entidad. Esa asociación vincula la base de datos vectorial con la base de datos de grafo, de modo que los resultados de búsqueda puedan ser posteriormente traducidos de vuelta a entidades del grafo. Este método constituye la capa de búsqueda semántica de la arquitectura.
def ingest_to_qdrant(self, collection_name: str, raw_data: str, node_id_mapping: dict):
names = list(node_id_mapping.keys())
embeddings = [self.ollama_embeddings(name) for name in names]
self.qdrant_client.upsert(
collection_name=collection_name,
points=[
{
"id": str(uuid.uuid4()),
"vector": embedding,
"payload": {"id": node_id_mapping[name], "name": name},
}
for name, embedding in zip(names, embeddings)
],
)
retriever_search() realiza una recuperación semántica en el momento de la consulta. La consulta se incrusta y se compara con los vectores en Qdrant. Lo que se obtiene son entidades del grafo que se asemejan a la consulta y no fragmentos de texto, y estas sirven como puntos de entrada al grafo de conocimiento. Por lo tanto, la recuperación está impulsada por conceptos y no por documentos.
def retriever_search(self, collection_name: str, query: str, top_k: int = 5):
retriever = QdrantNeo4jRetriever(
driver=self.neo4j_driver,
client=self.qdrant_client,
collection_name=collection_name,
id_property_external="id",
id_property_neo4j="id",
)
results = retriever.search(
query_vector=self.ollama_embeddings(query), top_k=top_k
)
return results
fetch_related_graph() solicita a Neo4j la información sobre los elementos cercanos a las entidades recién encontradas. Recorre el grafo para reunir los nodos vecinos y las relaciones que los conectan con las entidades obtenidas. Esa expansión aporta contexto que la coincidencia vectorial podría haber omitido y genera un subgrafo significativo en lugar de entidades aisladas. Este paso permite que GraphRAG razone sobre las relaciones.
def fetch_related_graph(self, entity_ids: list):
query = """
MATCH (e:Entity)-[r1]-(n1)-[r2]-(n2)
WHERE e.id IN $entity_ids
RETURN e, r1 as r, n1 as related, r2, n2
UNION
MATCH (e:Entity)-[r]-(related)
WHERE e.id IN $entity_ids
RETURN e, r, related, null as r2, null as n2
"""
with self.neo4j_driver.session() as session:
result = session.run(query, entity_ids=entity_ids)
subgraph = []
for record in result:
subgraph.append(
{
"entity": record["e"],
"relationship": record["r"],
"related_node": record["related"],
}
)
if record["r2"] and record["n2"]:
subgraph.append(
{
"entity": record["related"],
"relationship": record["r2"],
"related_node": record["n2"],
}
)
return subgraph
format_graph_context() prepara el subgráfico para el modelo, ya que la salida bruta del gráfico no es adecuada para un LLM directamente. Convierte la estructura en texto limpio compuesto por nodos y declaraciones de relaciones, redactado como triples legibles que describen cómo se conectan las entidades. Este formato mantiene la estructura del gráfico al mismo tiempo que resulta fácil de seguir para un modelo de lenguaje. Es la última etapa de preparación del contexto antes de responder.
def format_graph_context(self, subgraph: list):
nodes = set()
edges = []
for entry in subgraph:
entity = entry["entity"]
related = entry["related_node"]
relationship = entry["relationship"]
nodes.add(entity["name"])
nodes.add(related["name"])
edges.append(f"{entity['name']} {relationship['type']} {related['name']}")
return {"nodes": list(nodes), "edges": edges}
graphRAG_run() genera la respuesta final. Une el contexto del grafo formateado con la pregunta del usuario en una prompt. El modelo recibe información basada en el grafo y no fragmentos brutos de documentos, por lo que puede razonar sobre relaciones y hechos conectados, y su respuesta se basa en los conocimientos del grafo recuperados. Esta es la capa de razonamiento al final del proceso.
def graphRAG_run(self, graph_context: dict, user_query: str):
nodes_str = ", ".join(graph_context["nodes"])
edges_str = "; ".join(graph_context["edges"])
prompt = f"""
You are an intelligent assistant with access to the following knowledge graph:
Nodes: {nodes_str}
Edges: {edges_str}
Using this graph, Answer the following question:
User Query: "{user_query}"
"""
try:
response = chat(
model=self.ollama_model_answer,
messages=[
{
"role": "system",
"content": "Provide the answer for the following question:",
},
{"role": "user", "content": prompt},
],
)
return response.message.content
except Exception as e:
return f"Error querying LLM: {str(e)}"
create_and_ingest() coordina todo el flujo de trabajo de ingestión: crea la colección de vectores, extrae los componentes del grafo, los almacena en Neo4j, genera embeddings e indexa las entidades en Qdrant. Al ejecutarlo, el texto en bruto se convierte en una base de conocimientos GraphRAG buscable. Normalmente se ejecuta una sola vez, durante la preparación de los datos, después de lo cual el sistema puede responder a consultas.
def create_and_ingest(self, raw_data: str, query: str, collection_name: str = "medicationGraphRAGstore"):
print("Creating collection...")
self.create_collection(collection_name, self.vector_dimension)
print("Collection created/verified")
print("Extracting graph components...")
nodes, relationships = self.extract_graph_components(raw_data)
print("Nodes:", nodes)
print("Relationships:", relationships)
print("Ingesting to Neo4j...")
node_id_mapping = self.ingest_to_neo4j(nodes, relationships)
print("Neo4j ingestion complete")
print("Ingesting to Qdrant...")
self.ingest_to_qdrant(collection_name, raw_data, node_id_mapping)
print("Qdrant ingestion complete")
run_pipeline() coordina la recuperación de información y el razonamiento desde el principio hasta el final. Comienza con la recuperación semántica desde Qdrant, resuelve las entidades del grafo correspondiente y recorre Neo4j. El subgrafo resultante se formatea para el modelo de razonamiento, y la respuesta generada se envía de vuelta al usuario. Representa el camino completo desde la pregunta hasta la respuesta.
def run_pipeline(self, raw_data: str, query: str, collection_name: str = "medicationGraphRAGstore"):
# run only the first time, comment this for subsequent runs
# self.create_and_ingest(raw_data, query, collection_name)
print("Starting retriever search...")
retriever_result = self.retriever_search(collection_name, query)
print("Retriever results:", retriever_result)
print("Extracting entity IDs...")
entity_ids = [
item.content.split("'id': '")[1].split("'")[0]
for item in retriever_result.items
]
print("Entity IDs:", entity_ids)
print("Fetching related graph...")
subgraph = self.fetch_related_graph(entity_ids)
print("Subgraph:", subgraph)
print("Formatting graph context...")
graph_context = self.format_graph_context(subgraph)
print("Graph context:", graph_context)
print("Running GraphRAG...")
answer = self.graphRAG_run(graph_context, query)
print("Final Answer:", answer)
return answer
close() se encarga de la limpieza. Cierra la conexión del controlador Neo4j y libera los recursos relacionados, lo que evita fugas de conexión y permite un apagado ordenado. Es sencillo, pero siempre debe llamarse al final del procesamiento.
def close(self):
self.neo4j_driver.close()
El código del controlador une a la clase:
if __name__ == "__main__":
print("Script started")
graph_rag = MedicationGraphRAG(env_path="../.env")
# Example-1
# raw_data = textwrap.dedent("""
# The patient was prescribed Lisinopril and Metformin last month.
# He takes the Lisinopril 10mg daily for hypertension, but often misses
# his Metformin 500mg dose which should be taken twice daily for diabetes.
# """).strip()
# Example-2
raw_data = textwrap.dedent("""
The patient is a 62-year-old man with a history of multiple chronic conditions
being managed through an extensive medication regimen. He was prescribed
Lisinopril, Metformin, Atorvastatin, Aspirin, Levothyroxine, and Sertraline
over the course of the past year, with his treatment plan adjusted several
times based on follow-up visits.
He takes Lisinopril 10mg daily for hypertension, but often misses his
Metformin 500mg dose which should be taken twice daily for diabetes. His
cardiologist also started him on Atorvastatin 40mg at bedtime for high
cholesterol after his last lipid panel showed elevated LDL levels. To reduce
his risk of cardiovascular events, he was additionally prescribed Aspirin
81mg daily for heart disease prevention, which he takes alongside his
breakfast each morning.
Following a routine thyroid screening, he was found to have an underactive
thyroid and was started on Levothyroxine 75mcg every morning for
hypothyroidism, to be taken on an empty stomach before any other medications.
More recently, after reporting persistent low mood and difficulty sleeping
during a wellness visit, his primary care physician added Sertraline 50mg
daily for depression, with plans to reassess the dosage after eight weeks.
Despite the number of prescriptions, the patient has had difficulty
maintaining consistency with his Metformin and occasionally forgets his
evening Atorvastatin dose, which his care team is now addressing through a
simplified pill organizer and reminder system.
""").strip()
# Sample Questions
#1. "What is the dosage and frequency for Lisinopril?"
#2. "What is the dosage and frequency for Metformin?"
#3. "Which medications does the patient take once daily versus twice daily?"
#4. "What medication is prescribed for hypothyroidism, and at what dose?"
#5. "List all medications related to cardiovascular conditions and their dosages."
#6. "How often does the patient take Aspirin?"
#7. "What condition is Levothyroxine prescribed for?"
#8. "What time of day should Levothyroxine be taken, and why?"
#9. "Which medications does the patient have trouble taking consistently?"
#10. "What is the dosage and frequency for Sertraline?"
query = "List all medications related to cardiovascular conditions and their dosages."
answer = graph_rag.run_pipeline(raw_data, query, collection_name="medicationGraphRAGstore")
graph_rag.close()
El guion completo
Todas las partes juntas en un solo archivo:
import os
import uuid
import textwrap
import ollama
from dotenv import load_dotenv, find_dotenv
from ollama import chat
from neo4j import GraphDatabase
from qdrant_client import QdrantClient, models
from neo4j_graphrag.retrievers import QdrantNeo4jRetriever
import langextract as lx
from langextract.providers import ollama as lx_ollama
load_dotenv(find_dotenv())
class MedicationGraphRAG:
def __init__(self,env_path: str = ".env",ollama_model_extract: str = "gemma3:latest",
ollama_model_answer: str = "gemma3:latest",ollama_embedding_model: str = "embeddinggemma:latest",
ollama_host: str | None = None,vector_dimension: int = 768,
):
load_dotenv(env_path)
self.qdrant_key = os.getenv("QDRANT_KEY")
self.qdrant_url = os.getenv("QDRANT_URL")
self.neo4j_uri = os.getenv("NEO4J_URI")
self.neo4j_username = os.getenv("NEO4J_USERNAME")
self.neo4j_password = os.getenv("NEO4J_PASSWORD")
self.neo4j_driver = GraphDatabase.driver(
self.neo4j_uri, auth=(self.neo4j_username, self.neo4j_password)
)
self.qdrant_client = QdrantClient(
url=self.qdrant_url,
api_key=self.qdrant_key,
)
# Ollama client for local embeddings (embeddinggemma:latest)
self.ollama_client = ollama.Client(host=ollama_host) if ollama_host else ollama.Client()
# langextract needs a plain URL string, not a client object
self.ollama_url = ollama_host or os.environ.get("OLLAMA_HOST", "http://localhost:11434")
# Model / config knobs
self.ollama_model_extract = ollama_model_extract
self.ollama_model_answer = ollama_model_answer
self.ollama_embedding_model = ollama_embedding_model
self.vector_dimension = vector_dimension
def extract_graph_components(self, raw_data: str):
"""Extract medication entities and relationships using langextract + Ollama."""
prompt_description = textwrap.dedent("""
Extract medications with their details, using attributes to group related information:
1. Extract entities in the order they appear in the text
2. Each entity must have a 'medication_group' attribute linking it to its medication
3. All details about a medication should share the same medication_group value
""").strip()
examples = [
lx.data.ExampleData(
text=(
"Patient takes Aspirin 100mg daily for heart health and"
" Simvastatin 20mg at bedtime."
),
extractions=[
lx.data.Extraction(
extraction_class="medication",
extraction_text="Aspirin",
attributes={"medication_group": "Aspirin"},
),
lx.data.Extraction(
extraction_class="dosage",
extraction_text="100mg",
attributes={"medication_group": "Aspirin"},
),
lx.data.Extraction(
extraction_class="frequency",
extraction_text="daily",
attributes={"medication_group": "Aspirin"},
),
lx.data.Extraction(
extraction_class="condition",
extraction_text="heart health",
attributes={"medication_group": "Aspirin"},
),
lx.data.Extraction(
extraction_class="medication",
extraction_text="Simvastatin",
attributes={"medication_group": "Simvastatin"},
),
lx.data.Extraction(
extraction_class="dosage",
extraction_text="20mg",
attributes={"medication_group": "Simvastatin"},
),
lx.data.Extraction(
extraction_class="frequency",
extraction_text="at bedtime",
attributes={"medication_group": "Simvastatin"},
),
],
)
]
result = lx.extract(
text_or_documents=raw_data,
prompt_description=prompt_description,
examples=examples,
model_id=self.ollama_model_extract,
model_url=self.ollama_url,
resolver_params={"format_handler": lx_ollama.OLLAMA_FORMAT_HANDLER},
max_char_buffer=4000,
show_progress=True,
)
return self._convert_extractions_to_graph(result.extractions)
def _convert_extractions_to_graph(self, extractions: list):
"""Convert langextract's flat, grouped extractions into (nodes, relationships)."""
groups: dict[str, list] = {}
for ext in extractions:
if not ext.attributes or "medication_group" not in ext.attributes:
continue
group_name = ext.attributes["medication_group"]
groups.setdefault(group_name, []).append(ext)
nodes: dict[str, str] = {}
relationships: list[dict] = []
for group_name, group_extractions in groups.items():
anchor_ext = next(
(e for e in group_extractions if e.extraction_class == "medication"),
None,
)
# Fall back to the group name itself if no explicit "medication"
# extraction was found in this group, so we still get an anchor.
anchor_text = anchor_ext.extraction_text if anchor_ext else group_name
if anchor_text not in nodes:
nodes[anchor_text] = str(uuid.uuid4())
for ext in group_extractions:
if ext is anchor_ext:
continue
target_text = ext.extraction_text
if target_text not in nodes:
nodes[target_text] = str(uuid.uuid4())
relationships.append(
{
"source": nodes[anchor_text],
"target": nodes[target_text],
"type": ext.extraction_class,
}
)
return nodes, relationships
def ingest_to_neo4j(self, nodes: dict, relationships: list):
"""
Ingest nodes and relationships into Neo4j.
"""
with self.neo4j_driver.session() as session:
# Create nodes in Neo4j
for name, node_id in nodes.items():
session.run(
"CREATE (n:Entity {id: $id, name: $name})",
id=node_id,
name=name,
)
# Create relationships in Neo4j, using the semantic type
# (dosage/frequency/condition/etc.) as the actual relationship
# label instead of a generic "RELATIONSHIP" type.
for relationship in relationships:
rel_type = self._sanitize_relationship_type(relationship["type"])
session.run(
"MATCH (a:Entity {id: $source_id}), (b:Entity {id: $target_id}) "
f"CREATE (a)-[:{rel_type} {{type: $type}}]->(b)",
source_id=relationship["source"],
target_id=relationship["target"],
type=relationship["type"],
)
return nodes
@staticmethod
def _sanitize_relationship_type(raw_type: str) -> str:
"""
Cypher relationship types can't be passed as query parameters, so
they have to be interpolated into the query string directly. Since
raw_type comes from LLM-extracted text, sanitize it to a safe
UPPER_SNAKE_CASE identifier before interpolation, to avoid Cypher
injection or syntax errors from unexpected characters.
"""
safe = "".join(ch if ch.isalnum() else "_" for ch in raw_type.strip())
safe = safe.upper().strip("_") or "RELATIONSHIP"
if safe[0].isdigit():
safe = f"REL_{safe}"
return safe
def create_collection(self, collection_name: str, vector_dimension: int = None):
vector_dimension = vector_dimension or self.vector_dimension
try:
# Try to fetch the collection status
self.qdrant_client.get_collection(collection_name)
print(f"Skipping creating collection; '{collection_name}' already exists.")
except Exception as e:
# If collection does not exist, an error will be thrown, so we create the collection
if "Not found: Collection" in str(e) or "doesn't exist" in str(e) or "404" in str(e):
print(f"Collection '{collection_name}' not found. Creating it now...")
self.qdrant_client.create_collection(
collection_name=collection_name,
vectors_config=models.VectorParams(
size=vector_dimension, distance=models.Distance.COSINE
),
)
print(f"Collection '{collection_name}' created successfully.")
else:
print(f"Error while checking collection: {e}")
def ollama_embeddings(self, text: str) -> list[float]:
response = self.ollama_client.embeddings(
model=self.ollama_embedding_model,
prompt=text,
)
return response["embedding"]
def ingest_to_qdrant(self, collection_name: str, raw_data: str, node_id_mapping: dict):
names = list(node_id_mapping.keys())
embeddings = [self.ollama_embeddings(name) for name in names]
self.qdrant_client.upsert(
collection_name=collection_name,
points=[
{
"id": str(uuid.uuid4()),
"vector": embedding,
"payload": {"id": node_id_mapping[name], "name": name},
}
for name, embedding in zip(names, embeddings)
],
)
def retriever_search(self, collection_name: str, query: str, top_k: int = 5):
retriever = QdrantNeo4jRetriever(
driver=self.neo4j_driver,
client=self.qdrant_client,
collection_name=collection_name,
id_property_external="id",
id_property_neo4j="id",
)
results = retriever.search(
query_vector=self.ollama_embeddings(query), top_k=top_k
)
return results
def fetch_related_graph(self, entity_ids: list):
query = """
MATCH (e:Entity)-[r1]-(n1)-[r2]-(n2)
WHERE e.id IN $entity_ids
RETURN e, r1 as r, n1 as related, r2, n2
UNION
MATCH (e:Entity)-[r]-(related)
WHERE e.id IN $entity_ids
RETURN e, r, related, null as r2, null as n2
"""
with self.neo4j_driver.session() as session:
result = session.run(query, entity_ids=entity_ids)
subgraph = []
for record in result:
subgraph.append(
{
"entity": record["e"],
"relationship": record["r"],
"related_node": record["related"],
}
)
if record["r2"] and record["n2"]:
subgraph.append(
{
"entity": record["related"],
"relationship": record["r2"],
"related_node": record["n2"],
}
)
return subgraph
def format_graph_context(self, subgraph: list):
nodes = set()
edges = []
for entry in subgraph:
entity = entry["entity"]
related = entry["related_node"]
relationship = entry["relationship"]
nodes.add(entity["name"])
nodes.add(related["name"])
edges.append(f"{entity['name']} {relationship['type']} {related['name']}")
return {"nodes": list(nodes), "edges": edges}
def graphRAG_run(self, graph_context: dict, user_query: str):
nodes_str = ", ".join(graph_context["nodes"])
edges_str = "; ".join(graph_context["edges"])
prompt = f"""
You are an intelligent assistant with access to the following knowledge graph:
Nodes: {nodes_str}
Edges: {edges_str}
Using this graph, Answer the following question:
User Query: "{user_query}"
"""
try:
response = chat(
model=self.ollama_model_answer,
messages=[
{
"role": "system",
"content": "Provide the answer for the following question:",
},
{"role": "user", "content": prompt},
],
)
return response.message.content
except Exception as e:
return f"Error querying LLM: {str(e)}"
def create_and_ingest(self, raw_data: str, query: str, collection_name: str = "medicationGraphRAGstore"):
print("Creating collection...")
self.create_collection(collection_name, self.vector_dimension)
print("Collection created/verified")
print("Extracting graph components...")
nodes, relationships = self.extract_graph_components(raw_data)
print("Nodes:", nodes)
print("Relationships:", relationships)
print("Ingesting to Neo4j...")
node_id_mapping = self.ingest_to_neo4j(nodes, relationships)
print("Neo4j ingestion complete")
print("Ingesting to Qdrant...")
self.ingest_to_qdrant(collection_name, raw_data, node_id_mapping)
print("Qdrant ingestion complete")
def run_pipeline(self, raw_data: str, query: str, collection_name: str = "medicationGraphRAGstore"):
# run only the first time, comment this for subsequent runs
# self.create_and_ingest(raw_data, query, collection_name)
print("Starting retriever search...")
retriever_result = self.retriever_search(collection_name, query)
print("Retriever results:", retriever_result)
print("Extracting entity IDs...")
entity_ids = [
item.content.split("'id': '")[1].split("'")[0]
for item in retriever_result.items
]
print("Entity IDs:", entity_ids)
print("Fetching related graph...")
subgraph = self.fetch_related_graph(entity_ids)
print("Subgraph:", subgraph)
print("Formatting graph context...")
graph_context = self.format_graph_context(subgraph)
print("Graph context:", graph_context)
print("Running GraphRAG...")
answer = self.graphRAG_run(graph_context, query)
print("Final Answer:", answer)
return answer
def close(self):
self.neo4j_driver.close()
if __name__ == "__main__":
print("Script started")
graph_rag = MedicationGraphRAG(env_path="../.env")
# Example-1
# raw_data = textwrap.dedent("""
# The patient was prescribed Lisinopril and Metformin last month.
# He takes the Lisinopril 10mg daily for hypertension, but often misses
# his Metformin 500mg dose which should be taken twice daily for diabetes.
# """).strip()
# Example-2
raw_data = textwrap.dedent("""
The patient is a 62-year-old man with a history of multiple chronic conditions
being managed through an extensive medication regimen. He was prescribed
Lisinopril, Metformin, Atorvastatin, Aspirin, Levothyroxine, and Sertraline
over the course of the past year, with his treatment plan adjusted several
times based on follow-up visits.
He takes Lisinopril 10mg daily for hypertension, but often misses his
Metformin 500mg dose which should be taken twice daily for diabetes. His
cardiologist also started him on Atorvastatin 40mg at bedtime for high
cholesterol after his last lipid panel showed elevated LDL levels. To reduce
his risk of cardiovascular events, he was additionally prescribed Aspirin
81mg daily for heart disease prevention, which he takes alongside his
breakfast each morning.
Following a routine thyroid screening, he was found to have an underactive
thyroid and was started on Levothyroxine 75mcg every morning for
hypothyroidism, to be taken on an empty stomach before any other medications.
More recently, after reporting persistent low mood and difficulty sleeping
during a wellness visit, his primary care physician added Sertraline 50mg
daily for depression, with plans to reassess the dosage after eight weeks.
Despite the number of prescriptions, the patient has had difficulty
maintaining consistency with his Metformin and occasionally forgets his
evening Atorvastatin dose, which his care team is now addressing through a
simplified pill organizer and reminder system.
""").strip()
# Sample Questions
#1. "What is the dosage and frequency for Lisinopril?"
#2. "What is the dosage and frequency for Metformin?"
#3. "Which medications does the patient take once daily versus twice daily?"
#4. "What medication is prescribed for hypothyroidism, and at what dose?"
#5. "List all medications related to cardiovascular conditions and their dosages."
#6. "How often does the patient take Aspirin?"
#7. "What condition is Levothyroxine prescribed for?"
#8. "What time of day should Levothyroxine be taken, and why?"
#9. "Which medications does the patient have trouble taking consistently?"
#10. "What is the dosage and frequency for Sertraline?"
query = "List all medications related to cardiovascular conditions and their dosages."
answer = graph_rag.run_pipeline(raw_data, query, collection_name="medicationGraphRAGstore")
graph_rag.close()
Ejecutándolo
Tres preguntas de ejemplo muestran cómo funciona el sistema. Cada una muestra los resultados del recuperador y luego la respuesta basada en el gráfico.
query = "List all medications related to cardiovascular conditions and their dosages."
Console:
Starting retriever search...
Retriever results: items=[RetrieverResultItem(content="<Record node=<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}> score=0.5062605>", metadata=None), RetrieverResultItem(content="<Record node=<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:0' labels=frozenset({'Entity'}) properties={'name': 'Atorvastatin', 'id': '1db81626-c3de-4cab-b5dd-091327785182'}> score=0.47961158>", metadata=None), RetrieverResultItem(content="<Record node=<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:6' labels=frozenset({'Entity'}) properties={'name': 'heart disease prevention', 'id': '44573186-869f-4d5d-ba04-fe254ec4ed21'}> score=0.45777896>", metadata=None), RetrieverResultItem(content="<Record node=<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}> score=0.45199984>", metadata=None), RetrieverResultItem(content="<Record node=<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}> score=0.4511963>", metadata=None)] metadata={'__retriever': 'QdrantNeo4jRetriever'}
Extracting entity IDs...
Entity IDs: ['1c9fb28e-c3e1-4515-afa0-01939beac419', '1db81626-c3de-4cab-b5dd-091327785182', '44573186-869f-4d5d-ba04-fe254ec4ed21', '04f27c55-38a3-46a9-a411-4faf07836a56', '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb']
Fetching related graph...
Subgraph: [{'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:6' labels=frozenset({'Entity'}) properties={'name': 'heart disease prevention', 'id': '44573186-869f-4d5d-ba04-fe254ec4ed21'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:5' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:4' labels=frozenset({'Entity'}) properties={'name': 'Aspirin', 'id': '10939c85-6fc1-41b4-9b80-abe1662eda11'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:6' labels=frozenset({'Entity'}) properties={'name': 'heart disease prevention', 'id': '44573186-869f-4d5d-ba04-fe254ec4ed21'}>) type='CONDITION' properties={'type': 'condition'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:4' labels=frozenset({'Entity'}) properties={'name': 'Aspirin', 'id': '10939c85-6fc1-41b4-9b80-abe1662eda11'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:4' labels=frozenset({'Entity'}) properties={'name': 'Aspirin', 'id': '10939c85-6fc1-41b4-9b80-abe1662eda11'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:4' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:4' labels=frozenset({'Entity'}) properties={'name': 'Aspirin', 'id': '10939c85-6fc1-41b4-9b80-abe1662eda11'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>) type='FREQUENCY' properties={'type': 'frequency'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:6' labels=frozenset({'Entity'}) properties={'name': 'heart disease prevention', 'id': '44573186-869f-4d5d-ba04-fe254ec4ed21'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:5' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:4' labels=frozenset({'Entity'}) properties={'name': 'Aspirin', 'id': '10939c85-6fc1-41b4-9b80-abe1662eda11'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:6' labels=frozenset({'Entity'}) properties={'name': 'heart disease prevention', 'id': '44573186-869f-4d5d-ba04-fe254ec4ed21'}>) type='CONDITION' properties={'type': 'condition'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:4' labels=frozenset({'Entity'}) properties={'name': 'Aspirin', 'id': '10939c85-6fc1-41b4-9b80-abe1662eda11'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:4' labels=frozenset({'Entity'}) properties={'name': 'Aspirin', 'id': '10939c85-6fc1-41b4-9b80-abe1662eda11'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:3' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:4' labels=frozenset({'Entity'}) properties={'name': 'Aspirin', 'id': '10939c85-6fc1-41b4-9b80-abe1662eda11'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:5' labels=frozenset({'Entity'}) properties={'name': '81mg', 'id': '9d1d3859-cf6f-4a22-81b8-7d80e3cc8e89'}>) type='DOSAGE' properties={'type': 'dosage'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:5' labels=frozenset({'Entity'}) properties={'name': '81mg', 'id': '9d1d3859-cf6f-4a22-81b8-7d80e3cc8e89'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:7' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>) type='FREQUENCY' properties={'type': 'frequency'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:17' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:20' labels=frozenset({'Entity'}) properties={'name': 'Sertraline', 'id': '42844c4c-ce96-4bd9-8d37-d8adad5a75fe'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>) type='FREQUENCY' properties={'type': 'frequency'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:20' labels=frozenset({'Entity'}) properties={'name': 'Sertraline', 'id': '42844c4c-ce96-4bd9-8d37-d8adad5a75fe'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:7' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>) type='FREQUENCY' properties={'type': 'frequency'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:4' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:4' labels=frozenset({'Entity'}) properties={'name': 'Aspirin', 'id': '10939c85-6fc1-41b4-9b80-abe1662eda11'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>) type='FREQUENCY' properties={'type': 'frequency'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:4' labels=frozenset({'Entity'}) properties={'name': 'Aspirin', 'id': '10939c85-6fc1-41b4-9b80-abe1662eda11'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:15' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}>) type='ROUTE' properties={'type': 'route'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:14' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:18' labels=frozenset({'Entity'}) properties={'name': 'hypothyroidism', 'id': '95b91440-5ff1-41eb-a036-b57880094b05'}>) type='CONDITION' properties={'type': 'condition'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:18' labels=frozenset({'Entity'}) properties={'name': 'hypothyroidism', 'id': '95b91440-5ff1-41eb-a036-b57880094b05'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:15' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}>) type='ROUTE' properties={'type': 'route'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:13' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:17' labels=frozenset({'Entity'}) properties={'name': 'every morning', 'id': '7fb1c7e5-e414-43ec-8606-474b08dc9173'}>) type='FREQUENCY' properties={'type': 'frequency'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:17' labels=frozenset({'Entity'}) properties={'name': 'every morning', 'id': '7fb1c7e5-e414-43ec-8606-474b08dc9173'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:15' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}>) type='ROUTE' properties={'type': 'route'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:12' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:16' labels=frozenset({'Entity'}) properties={'name': '75mcg', 'id': '75b6f7a1-2f53-419c-9365-5f026dcb1e25'}>) type='DOSAGE' properties={'type': 'dosage'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:16' labels=frozenset({'Entity'}) properties={'name': '75mcg', 'id': '75b6f7a1-2f53-419c-9365-5f026dcb1e25'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:0' labels=frozenset({'Entity'}) properties={'name': 'Atorvastatin', 'id': '1db81626-c3de-4cab-b5dd-091327785182'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:2' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:0' labels=frozenset({'Entity'}) properties={'name': 'Atorvastatin', 'id': '1db81626-c3de-4cab-b5dd-091327785182'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:3' labels=frozenset({'Entity'}) properties={'name': 'high cholesterol', 'id': 'dc85b413-3eca-4f26-a1dd-95de9d61e46c'}>) type='CONDITION' properties={'type': 'condition'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:3' labels=frozenset({'Entity'}) properties={'name': 'high cholesterol', 'id': 'dc85b413-3eca-4f26-a1dd-95de9d61e46c'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:0' labels=frozenset({'Entity'}) properties={'name': 'Atorvastatin', 'id': '1db81626-c3de-4cab-b5dd-091327785182'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:1' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:0' labels=frozenset({'Entity'}) properties={'name': 'Atorvastatin', 'id': '1db81626-c3de-4cab-b5dd-091327785182'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:2' labels=frozenset({'Entity'}) properties={'name': 'at bedtime', 'id': 'f9a049d4-bdb9-443d-a70f-3aa0ad290f5d'}>) type='FREQUENCY' properties={'type': 'frequency'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:2' labels=frozenset({'Entity'}) properties={'name': 'at bedtime', 'id': 'f9a049d4-bdb9-443d-a70f-3aa0ad290f5d'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:0' labels=frozenset({'Entity'}) properties={'name': 'Atorvastatin', 'id': '1db81626-c3de-4cab-b5dd-091327785182'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:0' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:0' labels=frozenset({'Entity'}) properties={'name': 'Atorvastatin', 'id': '1db81626-c3de-4cab-b5dd-091327785182'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:1' labels=frozenset({'Entity'}) properties={'name': '40mg', 'id': '960fd15d-ad36-4b90-aede-3473dd53f70c'}>) type='DOSAGE' properties={'type': 'dosage'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:1' labels=frozenset({'Entity'}) properties={'name': '40mg', 'id': '960fd15d-ad36-4b90-aede-3473dd53f70c'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:6' labels=frozenset({'Entity'}) properties={'name': 'heart disease prevention', 'id': '44573186-869f-4d5d-ba04-fe254ec4ed21'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:5' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:4' labels=frozenset({'Entity'}) properties={'name': 'Aspirin', 'id': '10939c85-6fc1-41b4-9b80-abe1662eda11'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:6' labels=frozenset({'Entity'}) properties={'name': 'heart disease prevention', 'id': '44573186-869f-4d5d-ba04-fe254ec4ed21'}>) type='CONDITION' properties={'type': 'condition'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:4' labels=frozenset({'Entity'}) properties={'name': 'Aspirin', 'id': '10939c85-6fc1-41b4-9b80-abe1662eda11'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:15' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}>) type='ROUTE' properties={'type': 'route'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:14' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:18' labels=frozenset({'Entity'}) properties={'name': 'hypothyroidism', 'id': '95b91440-5ff1-41eb-a036-b57880094b05'}>) type='CONDITION' properties={'type': 'condition'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:18' labels=frozenset({'Entity'}) properties={'name': 'hypothyroidism', 'id': '95b91440-5ff1-41eb-a036-b57880094b05'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:13' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:17' labels=frozenset({'Entity'}) properties={'name': 'every morning', 'id': '7fb1c7e5-e414-43ec-8606-474b08dc9173'}>) type='FREQUENCY' properties={'type': 'frequency'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:17' labels=frozenset({'Entity'}) properties={'name': 'every morning', 'id': '7fb1c7e5-e414-43ec-8606-474b08dc9173'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:12' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:16' labels=frozenset({'Entity'}) properties={'name': '75mcg', 'id': '75b6f7a1-2f53-419c-9365-5f026dcb1e25'}>) type='DOSAGE' properties={'type': 'dosage'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:16' labels=frozenset({'Entity'}) properties={'name': '75mcg', 'id': '75b6f7a1-2f53-419c-9365-5f026dcb1e25'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:8' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:11' labels=frozenset({'Entity'}) properties={'name': 'hypertension', 'id': '1bc0479e-5e00-4ede-8a9d-704e56f58814'}>) type='CONDITION' properties={'type': 'condition'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:11' labels=frozenset({'Entity'}) properties={'name': 'hypertension', 'id': '1bc0479e-5e00-4ede-8a9d-704e56f58814'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:7' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>) type='FREQUENCY' properties={'type': 'frequency'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:6' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:9' labels=frozenset({'Entity'}) properties={'name': '10mg', 'id': 'cddff401-0958-4093-b196-ad270b7aa797'}>) type='DOSAGE' properties={'type': 'dosage'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:9' labels=frozenset({'Entity'}) properties={'name': '10mg', 'id': 'cddff401-0958-4093-b196-ad270b7aa797'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:15' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}>) type='ROUTE' properties={'type': 'route'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>}]
Formatting graph context...
Graph context: {'nodes': ['on an empty stomach before any other medications', 'hypertension', 'Atorvastatin', 'Lisinopril', 'Levothyroxine', 'at bedtime', 'high cholesterol', 'Aspirin', '75mcg', '81mg', 'daily', '10mg', 'heart disease prevention', 'every morning', 'Sertraline', 'hypothyroidism', '40mg'], 'edges': ['heart disease prevention condition Aspirin', 'Aspirin frequency daily', 'heart disease prevention condition Aspirin', 'Aspirin dosage 81mg', 'Lisinopril frequency daily', 'daily frequency Sertraline', 'Lisinopril frequency daily', 'daily frequency Aspirin', 'on an empty stomach before any other medications route Levothyroxine', 'Levothyroxine condition hypothyroidism', 'on an empty stomach before any other medications route Levothyroxine', 'Levothyroxine frequency every morning', 'on an empty stomach before any other medications route Levothyroxine', 'Levothyroxine dosage 75mcg', 'Atorvastatin condition high cholesterol', 'Atorvastatin frequency at bedtime', 'Atorvastatin dosage 40mg', 'heart disease prevention condition Aspirin', 'Levothyroxine route on an empty stomach before any other medications', 'Levothyroxine condition hypothyroidism', 'Levothyroxine frequency every morning', 'Levothyroxine dosage 75mcg', 'Lisinopril condition hypertension', 'Lisinopril frequency daily', 'Lisinopril dosage 10mg', 'on an empty stomach before any other medications route Levothyroxine']}
Running GraphRAG...
Final Answer: Here’s a list of medications related to cardiovascular conditions and their dosages based on the knowledge graph:
* **Aspirin:** 81mg (frequency: daily) - for heart disease prevention.
* **Atorvastatin:** 40mg (frequency: at bedtime) - for high cholesterol.
* **Lisinopril:** 10mg (frequency: daily) - for hypertension.
query = "What medication is prescribed for hypothyroidism, and at what dose?"
Console:
Starting retriever search...
Retriever results: items=[RetrieverResultItem(content="<Record node=<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:18' labels=frozenset({'Entity'}) properties={'name': 'hypothyroidism', 'id': '95b91440-5ff1-41eb-a036-b57880094b05'}> score=0.6616618>", metadata=None), RetrieverResultItem(content="<Record node=<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}> score=0.5983002>", metadata=None), RetrieverResultItem(content="<Record node=<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}> score=0.4675771>", metadata=None), RetrieverResultItem(content="<Record node=<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}> score=0.4620626>", metadata=None), RetrieverResultItem(content="<Record node=<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:9' labels=frozenset({'Entity'}) properties={'name': '10mg', 'id': 'cddff401-0958-4093-b196-ad270b7aa797'}> score=0.4382253>", metadata=None)] metadata={'__retriever': 'QdrantNeo4jRetriever'}
Extracting entity IDs...
Entity IDs: ['95b91440-5ff1-41eb-a036-b57880094b05', '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb', 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847', '1c9fb28e-c3e1-4515-afa0-01939beac419', 'cddff401-0958-4093-b196-ad270b7aa797']
Fetching related graph...
Subgraph: [{'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:9' labels=frozenset({'Entity'}) properties={'name': '10mg', 'id': 'cddff401-0958-4093-b196-ad270b7aa797'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:6' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:9' labels=frozenset({'Entity'}) properties={'name': '10mg', 'id': 'cddff401-0958-4093-b196-ad270b7aa797'}>) type='DOSAGE' properties={'type': 'dosage'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:8' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:11' labels=frozenset({'Entity'}) properties={'name': 'hypertension', 'id': '1bc0479e-5e00-4ede-8a9d-704e56f58814'}>) type='CONDITION' properties={'type': 'condition'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:11' labels=frozenset({'Entity'}) properties={'name': 'hypertension', 'id': '1bc0479e-5e00-4ede-8a9d-704e56f58814'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:9' labels=frozenset({'Entity'}) properties={'name': '10mg', 'id': 'cddff401-0958-4093-b196-ad270b7aa797'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:6' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:9' labels=frozenset({'Entity'}) properties={'name': '10mg', 'id': 'cddff401-0958-4093-b196-ad270b7aa797'}>) type='DOSAGE' properties={'type': 'dosage'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:7' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>) type='FREQUENCY' properties={'type': 'frequency'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:18' labels=frozenset({'Entity'}) properties={'name': 'hypothyroidism', 'id': '95b91440-5ff1-41eb-a036-b57880094b05'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:14' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:18' labels=frozenset({'Entity'}) properties={'name': 'hypothyroidism', 'id': '95b91440-5ff1-41eb-a036-b57880094b05'}>) type='CONDITION' properties={'type': 'condition'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:15' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}>) type='ROUTE' properties={'type': 'route'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:18' labels=frozenset({'Entity'}) properties={'name': 'hypothyroidism', 'id': '95b91440-5ff1-41eb-a036-b57880094b05'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:14' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:18' labels=frozenset({'Entity'}) properties={'name': 'hypothyroidism', 'id': '95b91440-5ff1-41eb-a036-b57880094b05'}>) type='CONDITION' properties={'type': 'condition'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:13' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:17' labels=frozenset({'Entity'}) properties={'name': 'every morning', 'id': '7fb1c7e5-e414-43ec-8606-474b08dc9173'}>) type='FREQUENCY' properties={'type': 'frequency'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:17' labels=frozenset({'Entity'}) properties={'name': 'every morning', 'id': '7fb1c7e5-e414-43ec-8606-474b08dc9173'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:18' labels=frozenset({'Entity'}) properties={'name': 'hypothyroidism', 'id': '95b91440-5ff1-41eb-a036-b57880094b05'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:14' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:18' labels=frozenset({'Entity'}) properties={'name': 'hypothyroidism', 'id': '95b91440-5ff1-41eb-a036-b57880094b05'}>) type='CONDITION' properties={'type': 'condition'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:12' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:16' labels=frozenset({'Entity'}) properties={'name': '75mcg', 'id': '75b6f7a1-2f53-419c-9365-5f026dcb1e25'}>) type='DOSAGE' properties={'type': 'dosage'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:16' labels=frozenset({'Entity'}) properties={'name': '75mcg', 'id': '75b6f7a1-2f53-419c-9365-5f026dcb1e25'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:15' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}>) type='ROUTE' properties={'type': 'route'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:14' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:18' labels=frozenset({'Entity'}) properties={'name': 'hypothyroidism', 'id': '95b91440-5ff1-41eb-a036-b57880094b05'}>) type='CONDITION' properties={'type': 'condition'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:18' labels=frozenset({'Entity'}) properties={'name': 'hypothyroidism', 'id': '95b91440-5ff1-41eb-a036-b57880094b05'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:15' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}>) type='ROUTE' properties={'type': 'route'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:13' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:17' labels=frozenset({'Entity'}) properties={'name': 'every morning', 'id': '7fb1c7e5-e414-43ec-8606-474b08dc9173'}>) type='FREQUENCY' properties={'type': 'frequency'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:17' labels=frozenset({'Entity'}) properties={'name': 'every morning', 'id': '7fb1c7e5-e414-43ec-8606-474b08dc9173'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:15' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}>) type='ROUTE' properties={'type': 'route'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:12' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:16' labels=frozenset({'Entity'}) properties={'name': '75mcg', 'id': '75b6f7a1-2f53-419c-9365-5f026dcb1e25'}>) type='DOSAGE' properties={'type': 'dosage'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:16' labels=frozenset({'Entity'}) properties={'name': '75mcg', 'id': '75b6f7a1-2f53-419c-9365-5f026dcb1e25'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:15' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}>) type='ROUTE' properties={'type': 'route'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:14' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:18' labels=frozenset({'Entity'}) properties={'name': 'hypothyroidism', 'id': '95b91440-5ff1-41eb-a036-b57880094b05'}>) type='CONDITION' properties={'type': 'condition'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:18' labels=frozenset({'Entity'}) properties={'name': 'hypothyroidism', 'id': '95b91440-5ff1-41eb-a036-b57880094b05'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:13' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:17' labels=frozenset({'Entity'}) properties={'name': 'every morning', 'id': '7fb1c7e5-e414-43ec-8606-474b08dc9173'}>) type='FREQUENCY' properties={'type': 'frequency'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:17' labels=frozenset({'Entity'}) properties={'name': 'every morning', 'id': '7fb1c7e5-e414-43ec-8606-474b08dc9173'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:12' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:16' labels=frozenset({'Entity'}) properties={'name': '75mcg', 'id': '75b6f7a1-2f53-419c-9365-5f026dcb1e25'}>) type='DOSAGE' properties={'type': 'dosage'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:16' labels=frozenset({'Entity'}) properties={'name': '75mcg', 'id': '75b6f7a1-2f53-419c-9365-5f026dcb1e25'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:9' labels=frozenset({'Entity'}) properties={'name': '10mg', 'id': 'cddff401-0958-4093-b196-ad270b7aa797'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:6' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:9' labels=frozenset({'Entity'}) properties={'name': '10mg', 'id': 'cddff401-0958-4093-b196-ad270b7aa797'}>) type='DOSAGE' properties={'type': 'dosage'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:11' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:15' labels=frozenset({'Entity'}) properties={'name': 'diabetes', 'id': '9cbb512f-ca6b-47de-bb12-378ac35826bd'}>) type='CONDITION' properties={'type': 'condition'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:15' labels=frozenset({'Entity'}) properties={'name': 'diabetes', 'id': '9cbb512f-ca6b-47de-bb12-378ac35826bd'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:10' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:14' labels=frozenset({'Entity'}) properties={'name': 'twice daily', 'id': '73d5a502-05be-4bb7-916a-10b8ff5130fa'}>) type='FREQUENCY' properties={'type': 'frequency'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:14' labels=frozenset({'Entity'}) properties={'name': 'twice daily', 'id': '73d5a502-05be-4bb7-916a-10b8ff5130fa'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:9' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:13' labels=frozenset({'Entity'}) properties={'name': '500mg', 'id': '6c38fe32-0ca3-4bcc-a072-05e302aaa8e7'}>) type='DOSAGE' properties={'type': 'dosage'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:13' labels=frozenset({'Entity'}) properties={'name': '500mg', 'id': '6c38fe32-0ca3-4bcc-a072-05e302aaa8e7'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:18' labels=frozenset({'Entity'}) properties={'name': 'hypothyroidism', 'id': '95b91440-5ff1-41eb-a036-b57880094b05'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:14' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:18' labels=frozenset({'Entity'}) properties={'name': 'hypothyroidism', 'id': '95b91440-5ff1-41eb-a036-b57880094b05'}>) type='CONDITION' properties={'type': 'condition'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:15' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}>) type='ROUTE' properties={'type': 'route'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>}]
Formatting graph context...
Graph context: {'nodes': ['Lisinopril', '75mcg', 'twice daily', 'diabetes', 'on an empty stomach before any other medications', 'hypertension', 'daily', 'Metformin', '500mg', '10mg', 'hypothyroidism', 'Levothyroxine', 'every morning'], 'edges': ['10mg dosage Lisinopril', 'Lisinopril condition hypertension', '10mg dosage Lisinopril', 'Lisinopril frequency daily', 'hypothyroidism condition Levothyroxine', 'Levothyroxine route on an empty stomach before any other medications', 'hypothyroidism condition Levothyroxine', 'Levothyroxine frequency every morning', 'hypothyroidism condition Levothyroxine', 'Levothyroxine dosage 75mcg', 'on an empty stomach before any other medications route Levothyroxine', 'Levothyroxine condition hypothyroidism', 'on an empty stomach before any other medications route Levothyroxine', 'Levothyroxine frequency every morning', 'on an empty stomach before any other medications route Levothyroxine', 'Levothyroxine dosage 75mcg', 'Levothyroxine route on an empty stomach before any other medications', 'Levothyroxine condition hypothyroidism', 'Levothyroxine frequency every morning', 'Levothyroxine dosage 75mcg', '10mg dosage Lisinopril', 'Metformin condition diabetes', 'Metformin frequency twice daily', 'Metformin dosage 500mg', 'hypothyroidism condition Levothyroxine', 'on an empty stomach before any other medications route Levothyroxine']}
Running GraphRAG...
Final Answer: Levothyroxine 75mcg is prescribed for hypothyroidism, taken every morning.
query = "Which medications does the patient take once daily versus twice daily?"
Console:
Starting retriever search...
Retriever results: items=[RetrieverResultItem(content="<Record node=<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:14' labels=frozenset({'Entity'}) properties={'name': 'twice daily', 'id': '73d5a502-05be-4bb7-916a-10b8ff5130fa'}> score=0.6052238>", metadata=None), RetrieverResultItem(content="<Record node=<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}> score=0.50138044>", metadata=None), RetrieverResultItem(content="<Record node=<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}> score=0.424541>", metadata=None), RetrieverResultItem(content="<Record node=<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:15' labels=frozenset({'Entity'}) properties={'name': 'diabetes', 'id': '9cbb512f-ca6b-47de-bb12-378ac35826bd'}> score=0.42364278>", metadata=None), RetrieverResultItem(content="<Record node=<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}> score=0.4210245>", metadata=None)] metadata={'__retriever': 'QdrantNeo4jRetriever'}
Extracting entity IDs...
Entity IDs: ['73d5a502-05be-4bb7-916a-10b8ff5130fa', '1c9fb28e-c3e1-4515-afa0-01939beac419', '06da6faa-baa5-4657-a961-5091f58e3058', '9cbb512f-ca6b-47de-bb12-378ac35826bd', 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847']
Fetching related graph...
Subgraph: [{'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:17' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:20' labels=frozenset({'Entity'}) properties={'name': 'Sertraline', 'id': '42844c4c-ce96-4bd9-8d37-d8adad5a75fe'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>) type='FREQUENCY' properties={'type': 'frequency'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:20' labels=frozenset({'Entity'}) properties={'name': 'Sertraline', 'id': '42844c4c-ce96-4bd9-8d37-d8adad5a75fe'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:20' labels=frozenset({'Entity'}) properties={'name': 'Sertraline', 'id': '42844c4c-ce96-4bd9-8d37-d8adad5a75fe'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:18' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:20' labels=frozenset({'Entity'}) properties={'name': 'Sertraline', 'id': '42844c4c-ce96-4bd9-8d37-d8adad5a75fe'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:22' labels=frozenset({'Entity'}) properties={'name': 'depression', 'id': '3aca7091-a4fa-4b12-ba5a-a8dbbbac5df4'}>) type='CONDITION' properties={'type': 'condition'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:22' labels=frozenset({'Entity'}) properties={'name': 'depression', 'id': '3aca7091-a4fa-4b12-ba5a-a8dbbbac5df4'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:17' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:20' labels=frozenset({'Entity'}) properties={'name': 'Sertraline', 'id': '42844c4c-ce96-4bd9-8d37-d8adad5a75fe'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>) type='FREQUENCY' properties={'type': 'frequency'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:20' labels=frozenset({'Entity'}) properties={'name': 'Sertraline', 'id': '42844c4c-ce96-4bd9-8d37-d8adad5a75fe'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:20' labels=frozenset({'Entity'}) properties={'name': 'Sertraline', 'id': '42844c4c-ce96-4bd9-8d37-d8adad5a75fe'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:16' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:20' labels=frozenset({'Entity'}) properties={'name': 'Sertraline', 'id': '42844c4c-ce96-4bd9-8d37-d8adad5a75fe'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:21' labels=frozenset({'Entity'}) properties={'name': '50mg', 'id': '5fe00dee-bd0f-4476-b5a6-b19974033f78'}>) type='DOSAGE' properties={'type': 'dosage'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:21' labels=frozenset({'Entity'}) properties={'name': '50mg', 'id': '5fe00dee-bd0f-4476-b5a6-b19974033f78'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:4' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:4' labels=frozenset({'Entity'}) properties={'name': 'Aspirin', 'id': '10939c85-6fc1-41b4-9b80-abe1662eda11'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>) type='FREQUENCY' properties={'type': 'frequency'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:4' labels=frozenset({'Entity'}) properties={'name': 'Aspirin', 'id': '10939c85-6fc1-41b4-9b80-abe1662eda11'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:4' labels=frozenset({'Entity'}) properties={'name': 'Aspirin', 'id': '10939c85-6fc1-41b4-9b80-abe1662eda11'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:5' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:4' labels=frozenset({'Entity'}) properties={'name': 'Aspirin', 'id': '10939c85-6fc1-41b4-9b80-abe1662eda11'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:6' labels=frozenset({'Entity'}) properties={'name': 'heart disease prevention', 'id': '44573186-869f-4d5d-ba04-fe254ec4ed21'}>) type='CONDITION' properties={'type': 'condition'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:6' labels=frozenset({'Entity'}) properties={'name': 'heart disease prevention', 'id': '44573186-869f-4d5d-ba04-fe254ec4ed21'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:4' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:4' labels=frozenset({'Entity'}) properties={'name': 'Aspirin', 'id': '10939c85-6fc1-41b4-9b80-abe1662eda11'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>) type='FREQUENCY' properties={'type': 'frequency'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:4' labels=frozenset({'Entity'}) properties={'name': 'Aspirin', 'id': '10939c85-6fc1-41b4-9b80-abe1662eda11'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:4' labels=frozenset({'Entity'}) properties={'name': 'Aspirin', 'id': '10939c85-6fc1-41b4-9b80-abe1662eda11'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:3' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:4' labels=frozenset({'Entity'}) properties={'name': 'Aspirin', 'id': '10939c85-6fc1-41b4-9b80-abe1662eda11'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:5' labels=frozenset({'Entity'}) properties={'name': '81mg', 'id': '9d1d3859-cf6f-4a22-81b8-7d80e3cc8e89'}>) type='DOSAGE' properties={'type': 'dosage'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:5' labels=frozenset({'Entity'}) properties={'name': '81mg', 'id': '9d1d3859-cf6f-4a22-81b8-7d80e3cc8e89'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:7' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>) type='FREQUENCY' properties={'type': 'frequency'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:8' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:11' labels=frozenset({'Entity'}) properties={'name': 'hypertension', 'id': '1bc0479e-5e00-4ede-8a9d-704e56f58814'}>) type='CONDITION' properties={'type': 'condition'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:11' labels=frozenset({'Entity'}) properties={'name': 'hypertension', 'id': '1bc0479e-5e00-4ede-8a9d-704e56f58814'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:7' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>) type='FREQUENCY' properties={'type': 'frequency'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:6' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:9' labels=frozenset({'Entity'}) properties={'name': '10mg', 'id': 'cddff401-0958-4093-b196-ad270b7aa797'}>) type='DOSAGE' properties={'type': 'dosage'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:9' labels=frozenset({'Entity'}) properties={'name': '10mg', 'id': 'cddff401-0958-4093-b196-ad270b7aa797'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:14' labels=frozenset({'Entity'}) properties={'name': 'twice daily', 'id': '73d5a502-05be-4bb7-916a-10b8ff5130fa'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:10' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:14' labels=frozenset({'Entity'}) properties={'name': 'twice daily', 'id': '73d5a502-05be-4bb7-916a-10b8ff5130fa'}>) type='FREQUENCY' properties={'type': 'frequency'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:11' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:15' labels=frozenset({'Entity'}) properties={'name': 'diabetes', 'id': '9cbb512f-ca6b-47de-bb12-378ac35826bd'}>) type='CONDITION' properties={'type': 'condition'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:15' labels=frozenset({'Entity'}) properties={'name': 'diabetes', 'id': '9cbb512f-ca6b-47de-bb12-378ac35826bd'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:14' labels=frozenset({'Entity'}) properties={'name': 'twice daily', 'id': '73d5a502-05be-4bb7-916a-10b8ff5130fa'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:10' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:14' labels=frozenset({'Entity'}) properties={'name': 'twice daily', 'id': '73d5a502-05be-4bb7-916a-10b8ff5130fa'}>) type='FREQUENCY' properties={'type': 'frequency'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:9' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:13' labels=frozenset({'Entity'}) properties={'name': '500mg', 'id': '6c38fe32-0ca3-4bcc-a072-05e302aaa8e7'}>) type='DOSAGE' properties={'type': 'dosage'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:13' labels=frozenset({'Entity'}) properties={'name': '500mg', 'id': '6c38fe32-0ca3-4bcc-a072-05e302aaa8e7'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:15' labels=frozenset({'Entity'}) properties={'name': 'diabetes', 'id': '9cbb512f-ca6b-47de-bb12-378ac35826bd'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:11' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:15' labels=frozenset({'Entity'}) properties={'name': 'diabetes', 'id': '9cbb512f-ca6b-47de-bb12-378ac35826bd'}>) type='CONDITION' properties={'type': 'condition'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:10' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:14' labels=frozenset({'Entity'}) properties={'name': 'twice daily', 'id': '73d5a502-05be-4bb7-916a-10b8ff5130fa'}>) type='FREQUENCY' properties={'type': 'frequency'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:14' labels=frozenset({'Entity'}) properties={'name': 'twice daily', 'id': '73d5a502-05be-4bb7-916a-10b8ff5130fa'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:15' labels=frozenset({'Entity'}) properties={'name': 'diabetes', 'id': '9cbb512f-ca6b-47de-bb12-378ac35826bd'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:11' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:15' labels=frozenset({'Entity'}) properties={'name': 'diabetes', 'id': '9cbb512f-ca6b-47de-bb12-378ac35826bd'}>) type='CONDITION' properties={'type': 'condition'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:9' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:13' labels=frozenset({'Entity'}) properties={'name': '500mg', 'id': '6c38fe32-0ca3-4bcc-a072-05e302aaa8e7'}>) type='DOSAGE' properties={'type': 'dosage'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:13' labels=frozenset({'Entity'}) properties={'name': '500mg', 'id': '6c38fe32-0ca3-4bcc-a072-05e302aaa8e7'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:15' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}>) type='ROUTE' properties={'type': 'route'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:14' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:18' labels=frozenset({'Entity'}) properties={'name': 'hypothyroidism', 'id': '95b91440-5ff1-41eb-a036-b57880094b05'}>) type='CONDITION' properties={'type': 'condition'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:18' labels=frozenset({'Entity'}) properties={'name': 'hypothyroidism', 'id': '95b91440-5ff1-41eb-a036-b57880094b05'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:15' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}>) type='ROUTE' properties={'type': 'route'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:13' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:17' labels=frozenset({'Entity'}) properties={'name': 'every morning', 'id': '7fb1c7e5-e414-43ec-8606-474b08dc9173'}>) type='FREQUENCY' properties={'type': 'frequency'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:17' labels=frozenset({'Entity'}) properties={'name': 'every morning', 'id': '7fb1c7e5-e414-43ec-8606-474b08dc9173'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:15' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}>) type='ROUTE' properties={'type': 'route'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:12' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:16' labels=frozenset({'Entity'}) properties={'name': '75mcg', 'id': '75b6f7a1-2f53-419c-9365-5f026dcb1e25'}>) type='DOSAGE' properties={'type': 'dosage'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:16' labels=frozenset({'Entity'}) properties={'name': '75mcg', 'id': '75b6f7a1-2f53-419c-9365-5f026dcb1e25'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:17' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:20' labels=frozenset({'Entity'}) properties={'name': 'Sertraline', 'id': '42844c4c-ce96-4bd9-8d37-d8adad5a75fe'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>) type='FREQUENCY' properties={'type': 'frequency'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:20' labels=frozenset({'Entity'}) properties={'name': 'Sertraline', 'id': '42844c4c-ce96-4bd9-8d37-d8adad5a75fe'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:4' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:4' labels=frozenset({'Entity'}) properties={'name': 'Aspirin', 'id': '10939c85-6fc1-41b4-9b80-abe1662eda11'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>) type='FREQUENCY' properties={'type': 'frequency'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:4' labels=frozenset({'Entity'}) properties={'name': 'Aspirin', 'id': '10939c85-6fc1-41b4-9b80-abe1662eda11'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:7' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:10' labels=frozenset({'Entity'}) properties={'name': 'daily', 'id': '06da6faa-baa5-4657-a961-5091f58e3058'}>) type='FREQUENCY' properties={'type': 'frequency'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:8' labels=frozenset({'Entity'}) properties={'name': 'Lisinopril', 'id': '04f27c55-38a3-46a9-a411-4faf07836a56'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:11' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:15' labels=frozenset({'Entity'}) properties={'name': 'diabetes', 'id': '9cbb512f-ca6b-47de-bb12-378ac35826bd'}>) type='CONDITION' properties={'type': 'condition'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:15' labels=frozenset({'Entity'}) properties={'name': 'diabetes', 'id': '9cbb512f-ca6b-47de-bb12-378ac35826bd'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:10' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:14' labels=frozenset({'Entity'}) properties={'name': 'twice daily', 'id': '73d5a502-05be-4bb7-916a-10b8ff5130fa'}>) type='FREQUENCY' properties={'type': 'frequency'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:14' labels=frozenset({'Entity'}) properties={'name': 'twice daily', 'id': '73d5a502-05be-4bb7-916a-10b8ff5130fa'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:9' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:13' labels=frozenset({'Entity'}) properties={'name': '500mg', 'id': '6c38fe32-0ca3-4bcc-a072-05e302aaa8e7'}>) type='DOSAGE' properties={'type': 'dosage'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:13' labels=frozenset({'Entity'}) properties={'name': '500mg', 'id': '6c38fe32-0ca3-4bcc-a072-05e302aaa8e7'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:14' labels=frozenset({'Entity'}) properties={'name': 'twice daily', 'id': '73d5a502-05be-4bb7-916a-10b8ff5130fa'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:10' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:14' labels=frozenset({'Entity'}) properties={'name': 'twice daily', 'id': '73d5a502-05be-4bb7-916a-10b8ff5130fa'}>) type='FREQUENCY' properties={'type': 'frequency'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:15' labels=frozenset({'Entity'}) properties={'name': 'diabetes', 'id': '9cbb512f-ca6b-47de-bb12-378ac35826bd'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:11' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:15' labels=frozenset({'Entity'}) properties={'name': 'diabetes', 'id': '9cbb512f-ca6b-47de-bb12-378ac35826bd'}>) type='CONDITION' properties={'type': 'condition'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:12' labels=frozenset({'Entity'}) properties={'name': 'Metformin', 'id': 'd14d70ef-3780-4ebe-b803-1ab8bd8ec847'}>}, {'entity': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}>, 'relationship': <Relationship element_id='5:a53f7783-1308-4f3d-9a27-45cede6b6376:15' nodes=(<Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>, <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:19' labels=frozenset({'Entity'}) properties={'name': 'on an empty stomach before any other medications', 'id': '1c9fb28e-c3e1-4515-afa0-01939beac419'}>) type='ROUTE' properties={'type': 'route'}>, 'related_node': <Node element_id='4:a53f7783-1308-4f3d-9a27-45cede6b6376:7' labels=frozenset({'Entity'}) properties={'name': 'Levothyroxine', 'id': '60654f2d-2ec8-4f4e-be02-cd57b7c5abfb'}>}]
Formatting graph context...
Graph context: {'nodes': ['twice daily', 'daily', '75mcg', '50mg', '81mg', 'Aspirin', 'on an empty stomach before any other medications', 'hypothyroidism', 'hypertension', 'depression', 'Lisinopril', 'Levothyroxine', 'heart disease prevention', 'every morning', 'Sertraline', 'diabetes', '500mg', '10mg', 'Metformin'], 'edges': ['daily frequency Sertraline', 'Sertraline condition depression', 'daily frequency Sertraline', 'Sertraline dosage 50mg', 'daily frequency Aspirin', 'Aspirin condition heart disease prevention', 'daily frequency Aspirin', 'Aspirin dosage 81mg', 'daily frequency Lisinopril', 'Lisinopril condition hypertension', 'daily frequency Lisinopril', 'Lisinopril dosage 10mg', 'twice daily frequency Metformin', 'Metformin condition diabetes', 'twice daily frequency Metformin', 'Metformin dosage 500mg', 'diabetes condition Metformin', 'Metformin frequency twice daily', 'diabetes condition Metformin', 'Metformin dosage 500mg', 'on an empty stomach before any other medications route Levothyroxine', 'Levothyroxine condition hypothyroidism', 'on an empty stomach before any other medications route Levothyroxine', 'Levothyroxine frequency every morning', 'on an empty stomach before any other medications route Levothyroxine', 'Levothyroxine dosage 75mcg', 'daily frequency Sertraline', 'daily frequency Aspirin', 'daily frequency Lisinopril', 'Metformin condition diabetes', 'Metformin frequency twice daily', 'Metformin dosage 500mg', 'twice daily frequency Metformin', 'diabetes condition Metformin', 'on an empty stomach before any other medications route Levothyroxine']}
Running GraphRAG...
Final Answer: Here’s the breakdown of medications taken once daily versus twice daily based on the knowledge graph:
**Once Daily:**
* Aspirin: daily frequency
* Sertraline: daily frequency
* Levothyroxine: every morning frequency
**Twice Daily:**
* Metformin: twice daily frequency
Lo que muestra la compilación
El resultado es un pipeline completo de GraphRAG con cada componente ejecutándose localmente en Ollama, Neo4j, Qdrant y LangExtract. El texto no estructurado se convierte en conocimiento estructurado a través de la extracción de entidades y relaciones, y ese conocimiento se almacena como un grafo en Neo4j. Qdrant proporciona recuperación semántica sobre las entidades del grafo y vincula la búsqueda vectorial con el recorrido del grafo. Juntos reemplazan la recuperación basada en fragmentos por una recuperación consciente del contexto, impulsada por conocimientos conectados, de modo que un LLM puede razonar sobre relaciones y no solo sobre fragmentos aislados de texto, lo que genera respuestas más fundamentadas y fáciles de explicar. Dado que toda la infraestructura es local, los desarrolladores mantienen un control total sobre sus datos, modelos e infraestructura. A medida que crece la adopción de GraphRAG, un diseño como este ofrece un plan práctico para una recuperación consciente de relaciones construida con herramientas de código abierto.