symfonic.capabilities.memory.vector_recall¶
vector_recall ¶
The vector half of recall: what is embedded, searched, and merged back.
Composed vector backend and embedder add semantic recall to the graph store. Metadata rides with each vector and is reconstructed into a memory record. Every hit is checked against graph visibility after backend selection.
VectorRecall ¶
The embedder and the vector backend, as one collaborator of the store.
Together rather than separately, because neither is useful alone: an embedder with nowhere to put a vector writes nothing, and a vector backend with no embedder cannot be queried. Composing them as a pair is what makes "this deployment does semantic recall" a single yes or no.
Source code in src/symfonic/capabilities/memory/vector_recall.py
forget
async
¶
Remove vector copies for record_ids under scope.
search
async
¶
Semantically similar memories for query, and whether it degraded.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
visible
|
Any
|
a predicate answering whether a record's scope is one this query may read. Passed in rather than recomputed, so the vector path and the graph path apply one isolation rule -- two copies of that rule is how they start to disagree. |
required |
Returns ((), True) when the backend or the embedder could not be
reached. Degraded, and reported as such, rather than an empty answer
that reads like "nothing is similar".
Source code in src/symfonic/capabilities/memory/vector_recall.py
merge ¶
merge(graph: tuple[RetrievedMemory, ...], vector: tuple[RetrievedMemory, ...]) -> tuple[tuple[RetrievedMemory, ...], int]
One memory per record_id, under :data:MERGE_RULE.
Returns the merged candidates and how many were the same memory seen twice. A memory the graph holds and the vector index also holds is one memory: emitting it twice would spend two lines of a budgeted block on one fact and let a duplicate outrank a distinct memory beneath it.
Source code in src/symfonic/capabilities/memory/vector_recall.py
vector_metadata ¶
Everything about a record that has to survive the round trip.
Named fields rather than a blob: a reader of a stored row can tell what the capability meant by each, and a field the capability stops using disappears from new rows instead of lingering as an uninterpreted key.
metadata is nested under its own key so a producer's vocabulary can
never collide with the capability's -- a record whose metadata had an
origin key would otherwise silently overwrite the record's.