How Semantica's AgnoSharedContext Manages Multi-Agent Shared Context: Architecture and Implementation
The AgnoSharedContext class coordinates multi-agent teams by instantiating a single shared ContextGraph and VectorStore, then providing thread-safe, role-scoped memory views to each agent through the bind_agent() method.
Managing shared knowledge across multiple AI agents requires careful coordination to prevent race conditions while preserving individual agent perspectives. In the semantica-agi/semantica repository, the Agno integration solves this through a centralized shared context architecture. This article examines how AgnoSharedContext enables concurrent agents to read from and write to a unified knowledge base while maintaining isolated, role-specific memory scopes.
Core Architecture of AgnoSharedContext
Located in [integrations/agno/shared_context.py](https://github.com/semantica-agi/semantica/blob/main/integrations/agno/shared_context.py), the AgnoSharedContext class serves as the central coordinator for Agno agent teams. It eliminates data silos by ensuring all agents operate on the same underlying knowledge structures rather than maintaining separate memory instances.
Single Shared Knowledge Graph
During initialization, AgnoSharedContext creates exactly one ContextGraph instance (or accepts a user-provided one) and stores it as self._knowledge_graph. This graph is wrapped in a shared AgentContext object (self._context) that every bound agent references.
By funneling all memory operations through this single AgentContext, Semantica guarantees that agent discoveries, decisions, and retrieved facts persist in a common state accessible to the entire team. The vector store operates similarly—one VectorStore instance backs all agents, enabling semantic search across the collective memory pool.
Thread-Safe Coordination with RLock
Concurrent multi-agent systems risk race conditions when multiple agents simultaneously update shared state. AgnoSharedContext protects all mutations with a re-entrant lock initialized as self._lock = threading.RLock().
This locking mechanism serializes critical operations including agent binding, memory upserts, and decision recording. Agents can safely execute in parallel without corrupting the shared knowledge graph or losing decision history, as the lock ensures atomic updates to the underlying ContextGraph and VectorStore.
Role-Scoped Memory Views
While agents share a single knowledge base, they require isolated perspectives to prevent contradictory actions and maintain clear audit trails. Semantica implements this through scoped memory stores that tag entries by agent role.
The bind_agent() Method
The bind_agent(role) method creates a role-specific interface to the shared context. When called, it returns an instance of _AgentScopedStore (defined in [integrations/agno/context_store.py](https://github.com/semantica-agi/semantica/blob/main/integrations/agno/context_store.py)), which inherits from AgnoContextStore.
Each scoped store receives the parent AgentContext (self._context = shared._context) but modifies its session_id by prefixing it with the agent's role using the format f"{shared.session_id}::{role}". This tagging mechanism ensures that while all agents write to the same physical storage, every memory entry carries metadata identifying its originator.
_AgentScopedStore Implementation
The _AgentScopedStore class delegates all memory operations (upsert_memory, read_memories, delete_memory) to the shared context while automatically appending role labels. When the researcher agent upserts a memory, the store tags it with the researcher role; when the analyst queries memories, it can retrieve the full shared pool including entries from other agents.
This architecture prevents agents from overwriting each other's work while still allowing cross-agent context retrieval. The scoped store maintains a reference to the parent shared context (self._shared), enabling agents to access self._shared._shared_memories for global insights when needed.
Decision Tracking and Graph Analytics
Beyond raw memory storage, AgnoSharedContext provides sophisticated decision tracking and graph traversal capabilities that enhance multi-agent coordination.
Automatic Decision Recording
When initialized with decision_tracking=True, the shared context automatically logs every memory operation as a structured decision. Each call to upsert_memory triggers self._context.record_decision with a category label formatted as f"memory:{self._role}", creating an immutable audit trail of which agent contributed what knowledge and when.
The shared context also exposes a global record_decision method that agents can call directly to log high-level strategic choices, optionally specifying an explicit agent_role parameter for team-wide decision tracking.
Graph Expansion for Context Retrieval
Setting graph_expansion=True enables one-hop neighbor retrieval in the knowledge graph. When an agent calls read_memories, the underlying AgnoContextStore enriches vector search results with related entities from the ContextGraph, providing context-aware retrieval that surfaces connections the agent might not have explicitly queried.
This feature allows agents to benefit from the team's collective reasoning—even if one agent stores a fact and another asks a related question later, the graph expansion surfaces the connection automatically.
Practical Implementation Example
The following example demonstrates initializing a shared context for a research team and binding role-scoped stores:
from semantica.vector_store import VectorStore
from semantica.context import ContextGraph
from integrations.agno import AgnoSharedContext, AgnoKGToolkit, AgnoDecisionKit
# Initialize shared infrastructure
shared = AgnoSharedContext(
vector_store=VectorStore(backend="faiss"),
knowledge_graph=ContextGraph(advanced_analytics=True),
decision_tracking=True,
graph_expansion=True,
)
# Create role-scoped memory interfaces
researcher_mem = shared.bind_agent("researcher")
analyst_mem = shared.bind_agent("analyst")
# Configure agents with shared context
from agno.agent import Agent
from agno.team import Team
researcher = Agent(
name="Researcher",
memory=researcher_mem,
tools=[AgnoKGToolkit(context=shared)],
)
analyst = Agent(
name="Analyst",
memory=analyst_mem,
tools=[AgnoDecisionKit(context=shared)],
)
team = Team(agents=[researcher, analyst], mode="coordinate")
Upserting memories automatically records decisions with role attribution:
researcher_mem.upsert_memory({"memory": "Quantum computing breakthroughs in 2024"})
# Stored with category="memory:researcher" in shared graph
Retrieving shared insights across all agents:
insights = shared.get_shared_insights()
print(insights) # Analytics over full decision graph
Reading combined memories from the shared pool:
all_memories = analyst_mem.read_memories(limit=10)
for m in all_memories:
print(m.memory) # Includes entries from both researcher and analyst
Summary
AgnoSharedContextacts as a central coordinator inintegrations/agno/shared_context.py, maintaining oneContextGraphandVectorStorefor the entire agent team.- Thread safety is enforced through
threading.RLock(), allowing concurrent agent operations without race conditions. - Role isolation is achieved via
bind_agent(), which returns_AgentScopedStoreinstances that tag memories with agent roles while writing to shared storage. - Decision tracking automatically logs memory operations and explicit decisions with role labels when
decision_tracking=True. - Graph expansion enriches retrievals with one-hop neighbors from the shared knowledge graph for context-aware responses.
- Analytics methods like
get_shared_insights()andfind_precedents()expose the full decision graph for debugging and higher-level reasoning.
Frequently Asked Questions
How does AgnoSharedContext prevent agents from overwriting each other's memories?
AgnoSharedContext uses the _AgentScopedStore class to tag every memory entry with the agent's role via the session_id prefix format f"{shared.session_id}::{role}". While all agents write to the same physical VectorStore and ContextGraph, the role metadata preserves attribution and prevents logical overwrites. The underlying storage appends rather than replaces entries, maintaining a complete history of each agent's contributions to the shared knowledge base.
Can multiple agents safely write to the shared context simultaneously?
Yes. The AgnoSharedContext class initializes self._lock = threading.RLock() in its constructor, protecting all mutation operations including bind_agent(), upsert_memory(), and record_decision(). This re-entrant lock ensures that even when agents execute concurrently in separate threads, updates to the shared ContextGraph and VectorStore occur atomically without data corruption or lost writes.
What is the difference between AgnoSharedContext and AgnoContextStore?
AgnoSharedContext (in shared_context.py) is the high-level coordinator that owns the shared AgentContext, ContextGraph, and VectorStore. AgnoContextStore (in context_store.py) implements the Agno MemoryDb protocol for individual agent memory operations. AgnoSharedContext creates scoped instances of _AgentScopedStore (a subclass of AgnoContextStore) via bind_agent(), allowing multiple agents to share infrastructure while maintaining distinct memory views.
How does graph expansion improve multi-agent collaboration?
When graph_expansion=True, the read_memories method in AgnoContextStore retrieves not only vector-similar memories but also one-hop neighbors from the shared ContextGraph. This means if the researcher agent stores a fact about "quantum computing" and the analyst later queries "qubits," the graph expansion surfaces the connection even if the analyst's query doesn't vector-match the researcher's exact wording. This feature enables implicit knowledge sharing where agents benefit from each other's contributions without explicit cross-referencing.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →