symfonic.memory.retrieval.spreading¶
spreading ¶
SpreadingActivation -- expands semantic hits with graph neighbor nodes.
When a query matches a semantic node (e.g. "Marinos"), this component fetches connected nodes (e.g. "Pescado", "Ribeye") via the graph store. Results are scored by importance and deduplicated against already-retrieved entries.
Two traversal modes:
- 1-hop concurrent gather (default,
max_hops == 0): preserves v6.1.x behaviour byte-for-byte --get_neighborsis called once per hit node viaasyncio.gather. - N-hop BFS (v7.0 T08,
max_hops >= 1): traverses the graph up tomax_hopsaway viaGraphTraversal.bfswhich routes throughGraphMemoryStore.bump_spreading(bumpingspreading_access_counton every traversal hit -- see v6.2 T02). A per-hop decay (base_decay ** hop) dampens activation score with distance, and amax_total_nodesceiling guards hydration latency on densely-connected graphs.
Neighbor fetches in the 1-hop path run concurrently so hydration latency stays O(1) round-trips rather than O(n).
LinkedNeighbor
dataclass
¶
LinkedNeighbor(
node: MemoryNode,
source_node: MemoryNode,
relationship: str = "",
hop_distance: int = 1,
activation_score: float = 1.0,
)
A neighbor node discovered via spreading activation.
hop_distance and activation_score are v7.0 T08 additions;
they default to 1 / 1.0 for 1-hop results so existing
consumers reading only node / source_node / relationship
continue to work byte-for-byte.
SpreadingActivation ¶
SpreadingActivation(
graph_store: GraphMemoryStore,
max_neighbors_per_node: int = 5,
min_importance: float = 0.0,
min_hit_importance: float = 0.0,
*,
max_hops: int = 0,
base_decay: float = 0.5,
max_total_nodes: int = 50,
)
Expand semantic hits with graph-neighbor context.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
graph_store
|
GraphMemoryStore
|
The graph store to query for neighbors. |
required |
max_neighbors_per_node
|
int
|
Cap on neighbors fetched per hit node in
the 1-hop path. Ignored on the N-hop BFS path (the
|
5
|
min_importance
|
float
|
Skip neighbors below this importance threshold. |
0.0
|
min_hit_importance
|
float
|
v6.1.8 hydration threshold -- skip initial
hit nodes whose importance is below this value. Default
0.0 preserves pre-v6.1.8 behaviour (every semantic hit is
injected). Caller typically wires this from
|
0.0
|
max_hops
|
int
|
v7.0 T08 BFS depth. |
0
|
base_decay
|
float
|
Per-hop multiplicative decay applied to the
activation score when |
0.5
|
max_total_nodes
|
int
|
Hard ceiling on total neighbours returned by the N-hop path. Guards hydration latency on densely- connected graphs. |
50
|
Source code in src/symfonic/memory/retrieval/spreading.py
expand
async
¶
expand(
scope: TenantScope,
hit_nodes: list[MemoryNode],
already_seen_ids: set[str] | None = None,
) -> list[LinkedNeighbor]
Fetch neighbor nodes for each hit node.
Returns:
| Type | Description |
|---|---|
list[LinkedNeighbor]
|
List of LinkedNeighbor objects, deduplicated and sorted by |
list[LinkedNeighbor]
|
importance descending. On the N-hop path, per-hop decay is |
list[LinkedNeighbor]
|
already folded into |
list[LinkedNeighbor]
|
rank by |