feat: sigmoid recency decay as configurable alternative to linear#2292
Open
garyd9 wants to merge 1 commit into
Open
feat: sigmoid recency decay as configurable alternative to linear#2292garyd9 wants to merge 1 commit into
garyd9 wants to merge 1 commit into
Conversation
Replace linear recency decay (1.0 - days/365) with a sigmoid curve: - Flat top for ~6 weeks (memories stay sharp) - Crosses neutral at ~79 days - Floor at 0.60 after ~9 months Submitted in monkey-patch form for discussion. A maintainer should properly integrate the sigmoid parameters into the config system (env vars, hierarchical config) before merging. Signed-off-by: garyd9 <garyd9@users.noreply.github.com>
Author
|
Stupid mimo-v2.5-pro doesn't seem to understand "submit this as a monkey patch." No, it had to actually patch the source and submit that. Sorry. I think the PR is still usable. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR: Add configurable sigmoid recency decay as alternative to linear
Summary
Replace the linear recency decay in
apply_combined_scoringwith an optional sigmoid curve that keeps memories sharp for ~6 weeks, then gradually demotes them — crossing neutral around 79 days and flooring at ~9 months.Note: This PR is submitted in monkey-patch form (currently deployed via a plugin override file). The author is not deeply familiar with Hindsight's internals and is submitting this for discussion. A maintainer should properly integrate this into the config system (env vars, hierarchical config, etc.) before merging.
Problem
The current linear recency decay in
engine/search/reranking.pypenalizes all memories uniformly as they age:This means a memory from 1 day ago and a memory from 30 days ago are treated very differently, even though both are recent enough to be highly relevant. Meanwhile, a memory from 6 months ago and one from 11 months ago are both deeply penalized, even though the 6-month memory may still be useful.
Real memories don't work like that. They stay sharp for a while, then fade — not linearly, but in an S-curve. A memory from last week is just as vivid as one from yesterday. A memory from a year ago is essentially gone. The transition between "sharp" and "gone" is where the interesting behavior happens.
What the sigmoid does
The sigmoid curve:
0.60 + 0.50 / (1 + exp(-0.03 * (125 - days_ago)))The key property: recent memories are treated equally (the flat top), and the decay curve matches how human memory actually works — not a straight line, but a sigmoid.
Why this matters
For agent memory systems, the retrieval scoring directly controls what gets injected into the agent's context. With linear decay, a 2-week-old memory that's still highly relevant gets penalized at the same rate as semantic relevance changes. The sigmoid lets recent-but-relevant memories compete fairly with brand-new ones, while still suppressing genuinely stale content.
In practice: operational memories from last month stay useful. Operational memories from 6 months ago fade. The agent doesn't have to fight its own memory system to surface the right context.
Current implementation (monkey-patch)
The patch is applied as a monkey-patch in the Hermes agent's Hindsight plugin override file (
~/.hermes/plugins/memory/hindsight/__init__.py). It:hindsight_api.engine.search.rerankingat runtimeapply_combined_scoringcombined_scoreandweightThis means everything about the existing scoring is preserved — the sigmoid only replaces the
sr.recencylinear decay and therecency_boostmultiplicative factor.Diff (as currently deployed)
Suggested integration path (for maintainers)
The sigmoid parameters (floor, ceiling, midpoint, steepness) should be exposed as env vars following Hindsight's existing pattern:
HINDSIGHT_API_RECENCY_DECAY_FUNCTION"linear""linear"(current) or"sigmoid"(new)HINDSIGHT_API_RECENCY_SIGMOID_FLOOR0.60HINDSIGHT_API_RECENCY_SIGMOID_CEILING1.10HINDSIGHT_API_RECENCY_SIGMOID_MIDPOINT79HINDSIGHT_API_RECENCY_SIGMOID_STEEPNESS0.03These would go in
HindsightConfigas hierarchical fields (bank-configurable), withapply_combined_scoringreading them viaget_config()or receiving them as parameters.The monkey-patch approach was necessary because the Hermes plugin loads after Hindsight is installed, and
apply_combined_scoringis called directly frommemory_engine.py:4557without any config parameter passthrough for the decay function.Testing
This patch has been running in production on a Hermes agent instance for ~3 weeks (since May 31, 2026) with no issues. The sigmoid correctly suppresses stale operational memories (~6 weeks old) while preserving recent context.
Submitted by garyd (discord: Pinched-Nerve) via the Hermes agent integration. Happy to discuss the approach but unlikely to be the right person to properly integrate this into the config system.