Adding Temporal Reasoning to Graph RAG: Tracking Fact Freshness and Staleness MachineLearningMastery
Vince and Ava debate a MachineLearningMastery article that adds timestamps and recency decay to Graph-RAG, treating it as a useful retrieval primitive but not a complete truth mechanism.
Transcript
Vince Ava, this is one of those Graph-RAG pieces where I like the product instinct, and I already hear you sharpening knives.
Ava Only a small knife. The useful part is obvious: standard subject, predicate, object triples are weirdly timeless, so the article adds a timestamp and calls them temporal quads. Fine. But then it slides from “newer” to “more truthful,” and that is where my eyebrow goes up. Recency is evidence. It is not a verdict.
Vince Right.
Ava The example is TechCorp having Alice as C E O in January twenty twenty-one, Bob in November twenty twenty-three, Charlie two days later, then Bob again two days after that. The code stores those in a little TemporalGraph, then calculate_recency_weight uses exponential decay. With a three hundred sixty-five day half-life, a one-year-old fact gets weight zero point five, and a current fact gets one.
Vince And that is exactly why I’m more sympathetic than you are. If a RAG answer pulls Alice, Bob, and Charlie into the same context window, the model is going to do model things. It will smooth the mess. It might say “leadership has included,” when the user asked who the C E O is. A ranking layer that says, as of this query date, Bob is freshest? That is not philosophy. That is fewer dumb answers.
Ava Mm-hm.
Vince This is basically our extraction-pipeline argument again, by the way. The glamour word is Graph-RAG. The product is receipts with dates attached, and a retrieval path that does not make the language model improvise the calendar.
Ava I buy that. I just don’t buy the implied generality. “Freshest wins” works for the toy C E O timeline because the predicate is functionally single-valued. One company, one current C E O. But lots of facts do not decay like milk. “Founded in San Francisco” from May first, twenty ten should not become less true because it is old.
Vince Sure.
Ava So the half-life cannot be global. It has to be per predicate, maybe per source type, maybe per domain. Executive roles might decay fast. Headquarters maybe slower. Founding location maybe never. If you set one half_life_days value across the graph, you have built a confidence blender with a calendar sticker on it.
Vince Okay, “confidence blender with a calendar sticker” is unfair and annoyingly good.
Ava I obviously prepared that devastating phrase for episode one thousand forty. This is the glamorous work now. We sit here and bully dictionaries until they admit time exists.
Vince The Bob came back part did make me laugh. That little fake company had a rough week. Imagine the org chart export. Just one box on a swivel chair.
Ava Poor Charlie. Forty-eight hours of authority, then the temporal graph quietly demotes him by sorting a list.
Vince Which, weirdly, is the use case. Not the tragedy of Charlie, specifically. The fact that query_temporal_graph filters out future facts, scores only facts on or before the as-of date, and sorts by weight. That gives you deterministic behavior before the LLM sees anything. Product teams can reason about that. They can test it.
Ava Yes, and the deterministic part is the strongest part of the article. The previous three-tier Graph-RAG setup was already trying to isolate priority tiers before calling a local Llama instance. This temporal piece fits that architecture pretty cleanly. My technical complaint is that assertion time is not validity time. “We learned this on Tuesday” and “this became true on Tuesday” are different facts.
Vince Oh interesting.
Ava That matters a lot. If a document published today says Alice was C E O in twenty twenty-one, freshness of the document should not make Alice the current answer. You need effective dates, observed dates, maybe retraction dates. Otherwise the recency score rewards the newest source, not the newest state of the world.
Vince No, I think that’s the right critique, but I’d still defend the article as a starter pattern. The central claim is not that timestamps solve truth. It is that Graph-RAG needs temporal metadata in the retrieval layer, because timeless triples make conflict resolution impossible. I’m with that. Temporal ranking is a conflict-resolution feature, not a truth engine.
Ava That sentence I’m fine with. My worry is just deployment cosplay, where somebody pastes this into a knowledge graph, watches the freshest answer pop to the top, and calls it grounded. You still need provenance, entity normalization, source authority, and rules for static predicates. We literally just went through silent graph junk with the extraction article.
Vince Completely. And this is where I’d care if I were building support search, internal policy Q and A, vendor records, anything where stale facts are worse than no facts. The practical change is small but real: you stop treating the graph as a museum and start treating it like an inventory system.
Ava Okay, fair.
Vince For testing, the article actually gives enough to poke. Use TemporalGraph, add_fact, calculate_recency_weight, and query_temporal_graph. Then try breaking it: one static fact, one fast-changing role, one backdated correction, and one newer-but-wrong source. If the ranking still looks sane, you have something.
Ava And vary half_life_days by predicate, not just because tuning is fun, though I know you love a knob with a product name. Do it because that parameter is carrying domain semantics. A bad half-life is not a small numerical error. It changes which world-state the retriever believes.
Vince You say “knob with a product name” like I’m not already workshopping Freshness Studio. Terrible. I know. Bob has resigned again. We can stop.