Recall Strategies
HEBBS supports four recall strategies. Each targets a different access pattern. Choose the strategy (or combine them) based on what the agent needs: semantic match, recency, cause-and-effect, or structural analogy.
Similarity
Section titled “Similarity”What it does: Returns memories whose content is semantically similar to the query. Uses vector embeddings and approximate nearest-neighbor search.
When to use it: When the agent needs context that sounds like or means something close to the current situation. “What did we discuss about pricing?” “Find memories related to this customer complaint.”
How it works internally: The query is embedded with the same model used at write time. HNSW (Hierarchical Navigable Small World) index performs approximate k-NN search. Results are ranked by cosine similarity. Time complexity is O(log n) with bounded ef_search for predictable latency.
Example use case: A sales agent receives a new lead. Similarity recall fetches past conversations with similar companies or topics to prime context before the call.
Defaults and Tuning
Section titled “Defaults and Tuning”| Parameter | Default | When to change |
|---|---|---|
ef_search | 50 | Increase (up to ~500) for large datasets where you need higher recall accuracy and can tolerate slightly higher latency. Decrease for real-time applications with tight latency budgets. |
Temporal
Section titled “Temporal”What it does: Returns memories for a specific entity in time order, optionally within a time range.
When to use it: When the agent needs “what happened with entity X” or “how has X changed over time.” Chronology matters more than semantic match.
How it works internally: A B-tree index on (entity_id, created_at) supports efficient range scans. The query specifies an entity_id and optional start_time/end_time. Results are streamed in time order. Time complexity is O(log n + k) where k is the number of memories in the range.
Requires entity_id: Temporal recall needs an entity to scope the timeline. During indexing, entity_ids are automatically assigned to propositions from LLM-extracted entities (e.g., “cloudvault”, “meridian analytics”). For manually stored memories, use hebbs remember --entity-id <entity>.
Example use case: A legal agent asks “what happened with Meridian?” Temporal recall with --entity-id meridian returns the chronological timeline: DPA signing, subprocessor change, violation, risk escalation.
Alternative for indexed content: If you don’t know the entity_id, use similarity recall with recency-weighted scoring (--weights 0.3:0.5:0.2:0) to get time-ordered results across all entities.
Defaults and Tuning
Section titled “Defaults and Tuning”| Parameter | Default | When to change |
|---|---|---|
time_range | None (unbounded) | Set explicit start/end timestamps to focus on a specific period (e.g. “last 24 hours”, “Q1 2025”). When omitted, all memories are eligible, returned newest-first up to top_k. |
Causal
Section titled “Causal”What it does: Returns memories connected by causal edges (CausedBy, FollowedBy). Traverses the graph from a seed memory to find causes, effects, or chains.
When to use it: When the agent needs to reason about why something happened or what followed from an event. “What led to this decision?” “What happened after the user said X?”
How it works internally: Starts from one or more seed memory IDs. Performs bounded graph traversal (max depth configurable) following edges of the specified types. Results are ranked by graph distance and recency. Time complexity is O(branching_factor ^ max_depth), bounded by configuration.
Works with indexed content: During indexing, the LLM extracts entity relationships which become EntityRelation graph edges. These edges connect propositions across documents, enabling causal traversal on indexed content without manual edge setup. For richer causal chains, store memories with explicit edges via hebbs remember --edge TARGET:caused_by:0.9.
Example use case: A research assistant traces how a conclusion was reached. Causal recall walks backward from the conclusion to the supporting evidence and reasoning steps.
Defaults and Tuning
Section titled “Defaults and Tuning”| Parameter | Default | When to change |
|---|---|---|
seed_memory_id | None (auto-detect) | Set explicitly when you know the starting point for the graph walk. When omitted, the engine embeds the cue and uses the closest memory as the seed. |
max_depth | 5 (bounded at 10) | Increase for deep causal chains. The hard cap of 10 prevents runaway traversals. Decrease for shallow “immediate cause” queries. |
edge_types | None (all types) | Filter to ["CausedBy"] for pure cause-tracing, or ["FollowedBy"] for sequential narratives. When omitted, all edge types are followed. |
Analogical
Section titled “Analogical”What it does: Finds memories that share structural patterns across domains. “This situation is like X in a different context.”
When to use it: When the agent needs cross-domain transfer: lessons from one project applied to another, or patterns that repeat across customers.
How it works internally: Structural pattern matching over memory graphs. Extracts relational structure (entities, actions, outcomes) and finds isomorphic or similar patterns in other memories. More expensive than similarity; typically used with smaller candidate sets or as a secondary pass.
Example use case: A product manager asks “Have we seen a similar launch failure before?” Analogical recall finds past launches with comparable failure patterns, even if the domains differ.
Defaults and Tuning
Section titled “Defaults and Tuning”| Parameter | Default | When to change |
|---|---|---|
analogical_alpha | 0.5 (balanced) | Lower (toward 0.0) to favor structural similarity — useful when you want pattern matches even if the surface content differs. Raise (toward 1.0) to favor embedding similarity — useful when content overlap is a stronger signal than structure. |
Multi-Strategy Recall
Section titled “Multi-Strategy Recall”You can invoke multiple strategies in a single recall request. When you do, HEBBS executes them in parallel, deduplicates results by memory ID (keeping the highest relevance), computes a composite score for each, and returns a single ranked list truncated to top_k.
When combining strategies, consider latency: similarity and temporal are fastest; causal and analogical add graph traversal cost. Use strategy-specific limits (top_k, max_depth) to stay within latency budgets.
Composite Scoring
Section titled “Composite Scoring”Every recall result includes a composite score — the number shown in CLI output and returned as score in API responses. This is not raw cosine similarity. It’s a weighted blend of four signals:
composite = w_relevance × relevance + w_recency × recency_signal + w_importance × importance + w_reinforcement × reinforcement_signalThe Four Signals
Section titled “The Four Signals”| Signal | Range | What it measures | How it’s computed |
|---|---|---|---|
| Relevance | 0.0 — 1.0 | Semantic match between query and memory | 1.0 - hnsw_distance (cosine similarity for normalized embeddings) |
| Recency | 0.0 — 1.0 | How recently the memory was created | 1.0 - (age / max_age), where max_age defaults to 30 days. A brand-new memory scores 1.0; a 30-day-old memory scores 0.0. |
| Importance | 0.0 — 1.0 | Memory’s importance value | The importance field set at remember time. Defaults to 0.5 if not specified. |
| Reinforcement | 0.0 — 1.0 | How often this memory has been recalled | log₂(1 + access_count) / log₂(1 + cap), where cap defaults to 100. A never-recalled memory scores 0.0. |
Default Weights
Section titled “Default Weights”| Weight | Default | Effect |
|---|---|---|
w_relevance | 0.5 | Relevance contributes half the score |
w_recency | 0.2 | Recent memories rank higher |
w_importance | 0.2 | High-importance memories rank higher |
w_reinforcement | 0.1 | Frequently recalled memories rank higher |
With these defaults, the theoretical maximum score for a brand-new, never-recalled memory with default importance (0.5) is:
0.5 × 1.0 + 0.2 × 1.0 + 0.2 × 0.5 + 0.1 × 0.0 = 0.80So a score of 0.67 does not mean weak similarity. The raw cosine similarity is likely 0.85+, blended down by the other signals.
Customizing Weights
Section titled “Customizing Weights”Pass scoring_weights to override the defaults. This works via gRPC, REST, the Python SDK, and the TypeScript SDK.
Pure relevance ranking (ignore recency, importance, reinforcement):
# Pythonresults = await client.recall( "Acme meeting", strategies=["similarity"], scoring_weights={ "w_relevance": 1.0, "w_recency": 0.0, "w_importance": 0.0, "w_reinforcement": 0.0, },)// TypeScriptconst results = await client.recall({ cue: 'Acme meeting', strategies: ['similarity'], scoringWeights: { wRelevance: 1.0, wRecency: 0.0, wImportance: 0.0, wReinforcement: 0.0 },});Recency-biased ranking (prefer recent memories, with relevance as tiebreaker):
# Pythonresults = await client.recall( "Acme meeting", strategies=["similarity"], scoring_weights={ "w_relevance": 0.3, "w_recency": 0.5, "w_importance": 0.1, "w_reinforcement": 0.1, },)// TypeScriptconst results = await client.recall({ cue: 'Acme meeting', strategies: ['similarity'], scoringWeights: { wRelevance: 0.3, wRecency: 0.5, wImportance: 0.1, wReinforcement: 0.1 },});REST equivalent:
curl -X POST http://localhost:6381/v1/memories/recall \ -H "Content-Type: application/json" \ -d '{ "cue": "Acme meeting", "strategies": ["similarity"], "scoring_weights": { "w_relevance": 1.0, "w_recency": 0.0, "w_importance": 0.0, "w_reinforcement": 0.0 } }'Strategy Details
Section titled “Strategy Details”Each result also includes strategy_details with per-strategy metadata. For similarity recall, this includes the raw relevance (cosine similarity) and distance values, so you can inspect the semantic match strength independently of the composite score. These are available in gRPC responses and the REST API.