Skip to lesson

NVIDIANVIDIA-Certified Professional: Agentic AI2026-105.1 Implement memory mechanisms for short- and long-term context retention.

Rank useful memories and retire stale ones

Completed by the knowledge check

Learning objective

Retrieve memories by relevance and recency, and apply decay, expiry, and deletion.

Core idea

Memory retrieval has two different jobs: decide which records are eligible, then rank the eligible records for the question. Relevance measures usefulness to a query; recency measures time. Decay changes ranking as time passes, expiry makes a record ineligible at a deadline, and deletion removes a stored copy. A strong similarity match cannot override an expiry deadline.

The ownership and isolation rules are established in 1.4.2, and 5.1.2 covers supported writes and corrections. Here you implement the read pipeline and its cleanup path. The central failure is operational: returning the nearest few vectors first, then dropping stale records, can leave the agent with no memory even when useful eligible records exist farther down the candidate list.

How it works

Generate candidates with the right score meaning

NeMo Agent Toolkit’s MemoryEditor.search(query, top_k, **kwargs) is the provider seam for retrieval. The automatic wrapper passes search_params to that method. A custom provider can implement candidate selection, eligibility checks, and reranking before returning the final MemoryItem list. MemoryItem.metadata holds application-defined timestamps and lifecycle fields; adding those fields does not itself enforce them.

NVIDIA’s documented RedisEditor.search accepts user_id, top_k, and an optional similarity_threshold. Its score is L2 distance: lower scores mean closer matches, and results above the threshold are filtered out. A comparison written for a similarity score where larger is better reverses this behavior. Calibrate a threshold on representative questions and memories rather than copy one from an unrelated embedding setup.

A LangGraph store offers asearch(namespace_prefix, query=..., filter=..., limit=..., offset=...). Semantic search requires an embedding index. NVIDIA’s existing-graph integration uses workflow._type: langgraph_wrapper, with graph naming the implementation; the store calls belong inside that graph. This is a separate implementation path from a NeMo memory provider, not a promise that all provider keyword arguments are interchangeable.

Filter, rank, and bound the final context

At query time, exclude records that fail the authorized scope, active-status, or expiry checks. Where the backend supports the required filters, apply them during candidate generation. Otherwise retrieve enough candidates for the provider to check and replenish before selecting the final results. Preserve a retrieval work limit: filtering cannot justify unlimited searches on the answer path.

For recency, choose which timestamp expresses the fact’s freshness. created_at measures insertion and updated_at measures store updates in LangGraph’s item model. A bookkeeping update need not mean that a business fact was revalidated. An application-defined verified_at can capture that event explicitly. Do not refresh it merely because retrieval returned the memory; otherwise frequently retrieved mistakes remain artificially young.

A concrete custom reranker can convert a nonnegative L2 distance d to a relevance value 1 / (1 + d) and multiply it by a decay factor 2 ** (-age_days / half_life_days). This is an example application rule, not a RedisEditor scoring option. Record the timestamp basis and half-life per memory category in a retrieval specification. Stable preferences can have a longer half-life than temporary meeting arrangements; validate that choice with retrieval cases containing both relevant distant records and irrelevant recent records.

Return only enough ranked memory to fit the answer’s token allocation. top_k or limit bounds item count, not total text length. A few large records can still overwhelm context. If eligible candidates cannot fill the requested count within the work budget, return fewer and answer from the remaining authoritative context instead of weakening expiry checks.

Candidates pass the eligibility checks before reranking, and a shortfall is replenished only within the work limit.

Candidates pass the eligibility checks before reranking, and a shortfall is replenished only within the work limitStarts at candidate selection. Eligibility checks exclude records that fail them. If the eligible candidates fill the requested count, they go to reranking; if not, the provider replenishes within the retrieval work limit, or returns fewer. Every path ends by returning only enough ranked memory.FailEligibleReplenish within the work limitYes, or return fewerCandidate selectionEligibility checksExclude recordsFill the requestedcount?RerankingReturn only enoughranked memory

Expire immediately and delete deliberately

Implement expiry as a read-time predicate, for example now < expires_at in a custom provider’s search. Here expires_at is application metadata, not a portable toolkit setting. A periodic cleanup worker can remove expired keys later, but the predicate prevents that scheduling delay from exposing expired content. Decay alone cannot deliver this guarantee because a sufficiently relevant decayed record can still rank first.

Use LangGraph’s adelete(namespace, key) for targeted store removal, or implement the required selection in a custom MemoryEditor.remove_items. Verify a concrete provider’s deletion semantics before calling it: the abstract interface’s **kwargs does not specify a universal per-record deletion parameter. Track the exact keys to remove rather than infer deletion scope from the method name.

For bulk cleanup through a LangGraph store, asearch supports limit and offset. The stores documentation warns that results beyond limit are truncated without an overflow signal. Enumerate a stable set of affected keys before deleting, or use a backend traversal that tolerates mutations. Increasing an offset while deleting earlier rows can skip records as the result set shrinks.

After cleanup, verify both direct key absence and retrieval behavior. A stored summary may contain the retired fact even when the original record is absent; follow the source and derivative relationships established in 1.4.2. Also exclude a record marked ineligible before cleanup from any in-flight answer assembly. A stale candidate list must not bypass the final eligibility check.

Key distinctions and trade-offs

Choose each operation for its own effect:

OperationDeciding conditionMechanismCost or limitation
Relevance rankingThe question needs semantically related factsRedisEditor.search with L2 distance, or indexed store asearch(query=...)Requires embeddings and score calibration
Recency preference and decayEligible facts lose usefulness with ageCustom reranker over a chosen timestamp and half-lifeCan suppress useful distant facts; requires retrieval evaluation
ExpiryA record must stop influencing answers after a deadlineCustom search eligibility predicate on expires_atRequires a trustworthy clock and checks on every read path
DeletionThe retained record must be removedadelete(namespace, key) or scoped custom remove_itemsRequires key enumeration and verification of affected derivatives

LangGraph documents backend-dependent default ordering: InMemoryStore uses insertion order, while PostgresStore and AsyncPostgresStore list by descending updated_at. An unqueried store listing is therefore not a portable relevance-and-recency ranking policy. Make ordering explicit when application behavior depends on it.

Architecture / decision scenario

A consulting firm’s research assistant recalls client-meeting arrangements. Its retrieval budget permits 20 candidates and a final context of four memories. Temporary arrangements expire after seven days. The team selects a two-day half-life based on its retrieval tests; both numbers are scenario policy, not toolkit defaults.

One candidate has L2 distance 0.1 and was verified six days ago. Another has distance 0.4 and was verified one day ago. Under the example rule, their scores are approximately 0.909 × 0.125 = 0.114 and 0.714 × 0.707 = 0.505. The less similar but more recent arrangement ranks higher. A third record with distance 0.01 is eight days old: expiry excludes it before scoring, regardless of its excellent relevance.

The tempting design retrieves four nearest vectors and deletes expired records nightly. In a replay, three of those four vectors are already expired, so post-filtering supplies only one memory. The retrieval engineer instead considers up to 20 candidates, checks eligibility, applies the decay rule, and returns at most four within the context allocation. If that bounded candidate pool is insufficient, the response proceeds with fewer memories.

The platform owner snapshots expired keys for targeted deletion and verifies their absence afterward. The product owner checks that a corrected arrangement remains preferred even if the superseded one was retrieved many times. Together these checks exercise ranking, time sensitivity, expiry, and removal rather than accepting “the vector query succeeded” as the result.

Common exam traps

  • Reading RedisEditor’s L2 distance as a score where higher means more relevant.
  • Assuming a recent record is relevant or a relevant record is still eligible.
  • Refreshing factual freshness every time an item is read.
  • Using decay as a substitute for expiry or expiry as proof of physical deletion.
  • Filtering only the final four candidates when eligible records exist outside that set.
  • Deleting one truncated listing and assuming it represented the complete namespace.

What to remember

Filter eligibility, retrieve sufficient candidates within a work budget, rank using explicit relevance and time semantics, then bound the injected context. Decay changes priority, expiry stops use, and deletion removes retained records. Implement these behaviors in the provider or graph that owns memory reads and verify them independently.

Knowledge check

References