openclaw - 💡(How to fix) Fix [Feature]: Memory importance scoring + time decay for long-term memory [1 participants]

Official PRs (…)
ON THIS PAGE

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#57307Fetched 2026-04-08 01:51:13
View on GitHub
Comments
0
Participants
1
Timeline
2
Reactions
1
Author
Participants
Timeline (top)
labeled ×1subscribed ×1

Add importance scoring (1-10) at memory write time and Weibull time-decay so that old/trivial memories fade while important ones persist, improving retrieval quality for long-running assistants.

Root Cause

Add importance scoring (1-10) at memory write time and Weibull time-decay so that old/trivial memories fade while important ones persist, improving retrieval quality for long-running assistants.

Code Example

import math

def decay_importance(original, days_since_update, days_since_access):
    half_life = 14  # configurable
    decay = math.exp(-0.693 * (days_since_update / half_life) ** 1.5)
    access_boost = 1.0 if days_since_access < 3 else 0.8 if days_since_access < 7 else 0.5
    return max(1, round(original * decay * access_boost))
RAW_BUFFERClick to expand / collapse

Summary

Add importance scoring (1-10) at memory write time and Weibull time-decay so that old/trivial memories fade while important ones persist, improving retrieval quality for long-running assistants.

Problem to solve

All memory entries have equal weight regardless of age or content significance. A note about "weather was nice today" has the same retrieval priority as "user accepted a $500K contract."

After months of use, memory becomes cluttered with low-value entries that dilute search quality. This affects both QMD and builtin backends neither has a mechanism to:

  1. Score initial importance when a memory is created
  2. Decay importance over time (old entries never lose relevance)
  3. Boost on access (frequently recalled memories should stay relevant longer)

For QMD L0/L1/L2 injection, this is especially impactful the limited token budget gets spent on stale trivia instead of high-value facts.

Proposed solution

A three-part importance system:

Part 1: Initial scoring at write time When a memory entry is created, score importance 1-10 using the model (nano tier is sufficient):

  • 1-3: trivial (small talk, weather)
  • 4-6: useful context (preferences, general facts)
  • 7-8: important (decisions, milestones, project info)
  • 9-10: critical (contracts, security, life events)

Part 2: Time decay (Weibull distribution) Periodic recalculation:

import math

def decay_importance(original, days_since_update, days_since_access):
    half_life = 14  # configurable
    decay = math.exp(-0.693 * (days_since_update / half_life) ** 1.5)
    access_boost = 1.0 if days_since_access < 3 else 0.8 if days_since_access < 7 else 0.5
    return max(1, round(original * decay * access_boost))

Weibull (shape=1.5) drops fast in the first week, then plateaus - matching how human memory works.

Part 3: Importance-weighted retrieval Search results ranked by similarity * importance instead of similarity alone.

Alternatives considered

  1. Manual pinning only (pinned: true/false) - too coarse, binary instead of continuous. User must manually manage pins. Importance scoring is the continuous extension of pinning.

  2. Recency-only sorting - penalizes old-but-important facts ("user's birthday", "API key location"). Importance scoring preserves high-value memories regardless of age.

  3. LLM-based filtering at retrieval time - adds latency to every search query. Scoring at write time is O(1) per entry, filtering at read time is O(n).

Impact

Affected: All users with long-running assistants (months of accumulated memory) Severity: Medium - search quality degrades gradually over time Frequency: Always - every memory recall searches unweighted entries Consequence: Irrelevant results returned instead of important ones; wasted token budget on stale context injection

Evidence/examples

I've implemented this as an external overlay (PostgreSQL + hourly APScheduler cron) in my OpenClaw deployment with 3 Telegram agents. Results after 2 weeks:

  • "Meeting with investor tomorrow at 15:00" -> importance 7 (LLM scored correctly)
  • "test message" in group chat -> importance 2 (trivial, scored low)
  • "Budget approved for Q2" -> importance 7
  • After 14 days without access, importance 7 -> 4 (natural decay)
  • After being recalled, importance boosts back (access_boost)

The pinned field already exists in memory entries - this is a natural extension from binary to continuous importance.

Additional information

  • Backward-compatible: entries without importance default to 5 (current implicit behavior)
  • QMD reranking layer could incorporate importance as an additional signal alongside BM25/vector scores
  • The Weibull half_life (default 14 days) should be configurable per-deployment
  • Happy to contribute a PR if there's interest in this direction

extent analysis

Fix Plan

To implement the importance scoring system, follow these steps:

  • Step 1: Update the database schema to include an importance field in the memory entries table.
  • Step 2: Implement initial scoring at write time using a model to score importance 1-10.
  • Step 3: Implement time decay using Weibull distribution with a periodic recalculation function.

Example code for the decay_importance function:

import math

def decay_importance(original, days_since_update, days_since_access):
    half_life = 14  # configurable
    decay = math.exp(-0.693 * (days_since_update / half_life) ** 1.5)
    access_boost = 1.0 if days_since_access < 3 else 0.8 if days_since_access < 7 else 0.5
    return max(1, round(original * decay * access_boost))
  • Step 4: Update the retrieval function to rank search results by similarity * importance instead of similarity alone.

Example code for the retrieval function:

def retrieve_memories(query):
    memories = fetch_memories_from_db(query)
    ranked_memories = sorted(memories, key=lambda x: x.similarity * x.importance, reverse=True)
    return ranked_memories

Verification

To verify that the fix worked, test the following scenarios:

  • Create a new memory entry with a high importance score and verify that it is ranked higher in search results.
  • Create a new memory entry with a low importance score and verify that it is ranked lower in search results.
  • Update a memory entry and verify that its importance score decays over time.
  • Access a memory entry and verify that its importance score boosts back up.

Extra Tips

  • Make sure to configure the half_life parameter according to your deployment needs.
  • Consider adding a pinned field to the memory entries table to allow users to manually pin important memories.
  • Use a scheduling library like APScheduler to periodically recalculate the importance scores.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING