Vector search answers "what text is semantically similar to this query." It's genuinely bad at questions like "who did the user mention working with," "what happened before the refund request," or "trace how this decision was made" — these require understanding explicit relationships between entities, not just semantic similarity of isolated facts.
Take the fact: "Sarah, the CTO at Acme Corp, introduced our sales rep to their CFO last Tuesday."
- Entities: Sarah (person), Acme Corp (organization), CFO (person, unnamed), sales rep (person)
- Relationships: Sarah
works_atAcme Corp (as CTO), Sarahintroducedsales reptoCFO, this happenedonlast Tuesday
A graph represents this as nodes (entities) connected by edges (relationships), often with properties attached (like the date).
import networkx as nx
graph = nx.MultiDiGraph()
graph.add_node("Sarah", type="person")
graph.add_node("Acme Corp", type="organization")
graph.add_node("CFO_of_Acme", type="person")
graph.add_edge("Sarah", "Acme Corp", relationship="works_at", role="CTO")
graph.add_edge("Sarah", "CFO_of_Acme", relationship="introduced_to_sales_rep", date="last Tuesday")
# Query: what is Sarah connected to?
for neighbor in graph.neighbors("Sarah"):
edge_data = graph.get_edge_data("Sarah", neighbor)
print(f"Sarah -> {neighbor}: {edge_data}")
GRAPH_EXTRACTION_PROMPT = """Extract entities and relationships from this text as JSON.
Format: {{"entities": [{{"name": "...", "type": "person|organization|product|other"}}],
"relationships": [{{"source": "...", "relationship": "...", "target": "...", "date": "... or null"}}]}}
Text: {text}
JSON:"""
def extract_graph(text):
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": GRAPH_EXTRACTION_PROMPT.format(text=text)}],
response_format={"type": "json_object"}
)
return json.loads(response.choices[0].message.content)
result = extract_graph("Sarah, the CTO at Acme Corp, introduced our sales rep to their CFO last Tuesday.")
print(result)
The advanced version of this (what Zep's Graphiti does) attaches validity time ranges to relationships, so the graph can answer both "what's true now" and "what was true at time X." Example: if "Sarah works at Acme Corp" is true from Jan 2024 to present, but then you learn "Sarah left Acme Corp in June 2026 and joined Beta Inc," a temporal graph keeps both facts with their time ranges, rather than just overwriting — so a query like "who did Sarah work for last year" still resolves correctly, while "who does Sarah work for now" resolves to Beta Inc.
- Use vector search for: "find anything related to X" style fuzzy semantic queries
- Use a graph for: multi-hop relational queries ("who introduced whom," "what led to what") and anything requiring precise, structured relationship traversal
- Production systems (Mem0^g, Zep) typically use both together — vector search for broad semantic recall, graph traversal for precise relational questions, combined at retrieval time (this is exactly what Module 7 covers)
- Take the 10 facts you extracted in Module 4's exercise, run the graph extraction prompt above on the original conversation, build the resulting graph in NetworkX.
- Write 3 queries that are naturally graph queries (relational) and 3 that are naturally vector queries (semantic fuzzy) — notice how differently you'd have to phrase code to answer each.