Class: Engram::UseCases::Recall
- Inherits:
-
Object
- Object
- Engram::UseCases::Recall
- Defined in:
- lib/engram/use_cases/recall.rb
Overview
Embed a query and fetch the most relevant memories for a scope.
By default this is pure vector similarity (the store’s own ordering). When importance_weight or recency_weight are non-zero, it fetches a larger candidate pool and re-ranks by a composite score: similarity + importance + recency. With both weights at zero (the default) behaviour is identical to plain similarity search.
Constant Summary collapse
- DEFAULT_HALFLIFE =
30 days, in seconds
30 * 24 * 60 * 60
- DEFAULT_POOL_FACTOR =
4
Instance Method Summary collapse
-
#call(query, scope:, limit: Engram.config.default_limit, kinds: nil) ⇒ Object
Returns Array<Record>, most relevant first.
-
#initialize(store:, embedder:, importance_weight: 0.0, recency_weight: 0.0, recency_halflife: DEFAULT_HALFLIFE, pool_factor: DEFAULT_POOL_FACTOR, touch: false) ⇒ Recall
constructor
A new instance of Recall.
Constructor Details
#initialize(store:, embedder:, importance_weight: 0.0, recency_weight: 0.0, recency_halflife: DEFAULT_HALFLIFE, pool_factor: DEFAULT_POOL_FACTOR, touch: false) ⇒ Recall
Returns a new instance of Recall.
15 16 17 18 19 20 21 22 23 24 |
# File 'lib/engram/use_cases/recall.rb', line 15 def initialize(store:, embedder:, importance_weight: 0.0, recency_weight: 0.0, recency_halflife: DEFAULT_HALFLIFE, pool_factor: DEFAULT_POOL_FACTOR, touch: false) @store = store @embedder = @importance_weight = importance_weight.to_f @recency_weight = recency_weight.to_f @recency_halflife = recency_halflife.to_f @pool_factor = pool_factor @touch = touch end |
Instance Method Details
#call(query, scope:, limit: Engram.config.default_limit, kinds: nil) ⇒ Object
Returns Array<Record>, most relevant first.
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/engram/use_cases/recall.rb', line 27 def call(query, scope:, limit: Engram.config.default_limit, kinds: nil) raise ArgumentError, "query must be a non-empty string" if query.to_s.strip.empty? payload = Engram::Instrumentation.payload( scope: scope, store: @store, limit: limit, kinds: Array(kinds).map(&:to_s), reranking: reranking? ) Engram::Instrumentation.instrument("recall", payload) do = @embedder.(query) pool_limit = reranking? ? limit * @pool_factor : limit pool = @store.search(embedding: , scope: scope, limit: pool_limit, kinds: kinds) results = (reranking? ? rerank(pool, ) : pool).first(limit) touch(results) if @touch payload[:result_count] = results.size payload[:candidate_count] = pool.size results end end |