Skip to content

feat(memory): add hotness scoring for cold/hot memory lifecycle (#296)#297

Merged
MaojiaSheng merged 1 commit intovolcengine:mainfrom
r266-tech:feat/memory-lifecycle-296
Feb 26, 2026
Merged

feat(memory): add hotness scoring for cold/hot memory lifecycle (#296)#297
MaojiaSheng merged 1 commit intovolcengine:mainfrom
r266-tech:feat/memory-lifecycle-296

Conversation

@r266-tech
Copy link
Contributor

Summary

Implements cold/hot memory lifecycle management as requested in #296.

Adds a hotness score that combines access frequency and recency to boost frequently-used, recently-updated contexts in search results.

Changes

New: openviking/retrieve/memory_lifecycle.py

  • hotness_score(active_count, updated_at, now, half_life_days)float [0.0, 1.0]
  • Formula: sigmoid(log1p(active_count)) * exp_decay(age, half_life=7d)
  • Pure function, no side effects, fully testable

Modified: openviking/retrieve/hierarchical_retriever.py

  • Blends hotness score with semantic similarity in _convert_to_matched_contexts()
  • final_score = (1 - alpha) * semantic_score + alpha * hotness_score
  • HOTNESS_ALPHA = 0.2 (class constant, easily configurable)
  • Re-sorts results after blending

New: tests/test_memory_lifecycle.py

  • 13 test cases covering:
    • Boundary conditions (zero count, None updated_at, old/recent memories)
    • Monotonicity (higher count → higher score, more recent → higher score)
    • Half-life correctness
    • Blending behavior (alpha=0 preserves order, default alpha preserves semantic dominance)

Backward Compatibility

  • No schema changes — leverages existing active_count and updated_at fields on Context
  • No Context class modifications
  • alpha=0 produces identical behavior to the current codebase
  • Pure additive change: 1 new file + minimal retriever modification

Design Decisions

  • sigmoid(log1p(x)) for frequency: sublinear growth prevents runaway scores from very high access counts
  • Exponential decay with 7-day half-life for recency: memories lose ~50% relevance per week of inactivity
  • alpha=0.2 default: mild boost that won't override strong semantic matches, but enough to surface hot memories when semantic scores are close

Closes #296

…engine#296)

Add a hotness_score() function that combines access frequency (sigmoid of
log1p(active_count)) with time-based recency decay (exponential, 7-day
half-life) to produce a 0.0-1.0 score for each context.

The hierarchical retriever now blends this hotness score with the semantic
similarity score: final = (1 - alpha) * semantic + alpha * hotness, where
alpha defaults to 0.2 (HOTNESS_ALPHA class constant).

Key properties:
- alpha=0 preserves existing behavior exactly (backward compatible)
- Default alpha=0.2 gives a mild boost without overriding semantic relevance
- No schema changes, no Context class modifications
- Pure additive: new file + minimal retriever modification

Closes volcengine#296
@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@MaojiaSheng
Copy link
Collaborator

we will review soon

@MaojiaSheng MaojiaSheng merged commit a88207f into volcengine:main Feb 26, 2026
1 check was pending
@github-project-automation github-project-automation bot moved this from Backlog to Done in OpenViking project Feb 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

[Feature]: 记录检索信息管理

3 participants