Core Concepts
MemoryRelay organizes AI agent knowledge into a set of interconnected primitives. Understanding these concepts will help you design effective memory strategies for your agents.
Memories
A memory is the fundamental unit of storage. Each memory contains:
- Content -- Natural language text describing what the agent learned, observed, or decided
- Metadata -- Arbitrary JSON for structured data (source, confidence, tags, timestamps)
- Vector Embedding -- A 384-dimensional vector generated automatically from the content, used for semantic search
Memories are retrieved by meaning, not by keywords. When you search for "How does authentication work?", MemoryRelay returns memories about JWT tokens, API keys, and login flows -- even if those memories never contain the word "authentication."
from memoryrelay import MemoryCreate
memory = client.memories.create(MemoryCreate(
agent_id="agent-123",
content="The payment service uses Stripe webhooks for async event processing. "
"Events are verified using the webhook signing secret before processing.",
metadata={
"source": "code_review",
"file": "payment/webhooks.py",
"confidence": 0.9
}
))
Memory Tiers
Memories are organized into importance tiers that affect retrieval priority:
| Tier | Importance | Description |
|---|---|---|
| Hot | >= 0.8 | Critical knowledge, prioritized in search results |
| Warm | 0.4 -- 0.8 | Standard memories, the default tier |
| Cold | < 0.4 | Low-priority memories, may be demoted during maintenance |
You can promote a memory's importance explicitly:
client.memories.promote(memory.id, importance=0.9) # promotes to hot tier
Batch Operations
Store up to 100 memories in a single request:
from memoryrelay import BatchMemoryRequest, BatchMemoryItem
response = client.memories.batch_create(BatchMemoryRequest(
memories=[
BatchMemoryItem(agent_id="agent-123", content="First observation..."),
BatchMemoryItem(agent_id="agent-123", content="Second observation..."),
]
))
Context Building
Build a pre-formatted context window from relevant memories, useful for injecting into LLM prompts:
from memoryrelay import MemoryContextRequest
context = client.memories.context(MemoryContextRequest(
query="What do we know about the payment system?",
agent_id="agent-123",
max_tokens=2000
))
print(context.context) # formatted string ready for a prompt
Agents
An agent is the isolation boundary for memories. Each agent has its own namespace -- memories stored under one agent are invisible to others unless explicitly shared.
Use agents to separate concerns:
- One agent per AI assistant instance
- One agent per environment (development, staging, production)
- One agent per team or department
# Create separate agents for different concerns
code_agent = client.agents.create(name="code-reviewer")
ops_agent = client.agents.create(name="ops-assistant")
# Memories are isolated
client.memories.create(MemoryCreate(
agent_id=code_agent.id,
content="Prefer composition over inheritance in this codebase."
))
# This memory is only visible when searching with code_agent.id
Agents belong to a user account. Your API key determines which user's agents you can access. You cannot access agents owned by another user.
Entities
Entities are named things extracted from memories -- people, organizations, technologies, projects, and concepts. MemoryRelay identifies entities automatically and links them to the memories where they appear.
Entity Types
| Type | Examples |
|---|---|
person | Team members, stakeholders, authors |
organization | Companies, teams, departments |
technology | Languages, frameworks, tools, services |
project | Repositories, products, initiatives |
concept | Design patterns, architectural styles, methodologies |
Automatic Extraction
When you store a memory, you can trigger entity extraction:
memory = client.memories.create(MemoryCreate(
agent_id=agent.id,
content="Sarah from the platform team recommended switching from REST to gRPC "
"for the inter-service communication in the billing microservice."
))
# Trigger extraction
client.memories.extract_entities(memory.id)
# Extracted entities: Sarah (person), platform team (organization),
# REST (technology), gRPC (technology), billing microservice (project)
Knowledge Graph
Entities form nodes in a knowledge graph. Relationships between entities create edges:
- Sarah works_on billing microservice
- billing microservice uses gRPC
- gRPC replaced REST (in this context)
Query the graph to answer questions like "What technologies does the billing team use?" or "Who has worked on the payment system?"
# List entities for an agent
entities = client.entities.list(agent_id=agent.id)
# Link entities to memories
from memoryrelay import EntityLinkCreate
client.entities.link(EntityLinkCreate(
memory_id=memory.id,
entity_id=entity.id,
relationship="mentions"
))
Sessions
A session represents a bounded interaction period -- a single conversation, a code review, a debugging session. Sessions group related memories together and provide temporal context.
from memoryrelay import SessionCreate
session = client.sessions.create(SessionCreate(
agent_id=agent.id,
project="billing-service",
metadata={"trigger": "user_request", "topic": "performance_optimization"}
))
Session Lifecycle
- Create or get-or-create a session when an interaction begins
- Store memories with the session ID to associate them
- End the session when the interaction completes, optionally with a summary
- Summarize a session to generate a compressed record
from memoryrelay import SessionEnd
# End the session with a summary
client.sessions.end(session.id, SessionEnd(
summary="Investigated billing service latency. Root cause was N+1 queries "
"in the invoice generation endpoint. Fixed by adding eager loading."
))
Session Summaries
Generate AI-powered summaries of sessions to create compressed records:
summary = client.sessions.summarize(session.id)
print(summary) # condensed account of what happened during the session
Sessions are optional. You can store memories without associating them to a session. Use sessions when temporal grouping adds value -- debugging sessions, code reviews, planning meetings.
Decisions
A decision records an architectural or design choice with its rationale, status, and lifecycle. Decisions help agents avoid re-debating settled questions and understand why things are the way they are.
from memoryrelay import DecisionCreate
decision = client.decisions.create(DecisionCreate(
agent_id=agent.id,
title="Use PostgreSQL for primary data store",
rationale="Need ACID transactions, complex queries, and pgvector for "
"semantic search. SQLite insufficient for concurrent writes.",
project="memory-service",
tags=["database", "infrastructure"]
))
Decision Status
| Status | Meaning |
|---|---|
active | Currently in effect, should be followed |
superseded | Replaced by a newer decision |
reverted | Rolled back, no longer applies |
Superseding Decisions
When a decision is replaced, link the old and new decisions:
from memoryrelay import DecisionSupersedeRequest
new_decision = client.decisions.supersede(
old_decision.id,
DecisionSupersedeRequest(
title="Migrate from PostgreSQL to CockroachDB",
rationale="Need multi-region support for global deployment. "
"CockroachDB is wire-compatible with PostgreSQL.",
tags=["database", "infrastructure", "migration"]
)
)
# old_decision.status is now "superseded"
Decision Checking
Before making a new decision, check if a relevant one already exists:
check = client.decisions.check(
query="What database should we use?",
project="memory-service"
)
for result in check.results:
print(f"[{result.similarity:.2f}] {result.decision.title} ({result.decision.status})")
Patterns
A pattern is a reusable practice or approach discovered across projects. Patterns capture "how we do things" and can be shared and adopted across different codebases.
from memoryrelay import PatternCreate
pattern = client.patterns.create(PatternCreate(
name="Repository Pattern for Data Access",
description="Wrap database queries in repository classes that return "
"domain objects. Keeps SQL out of business logic and makes "
"testing easier with mock repositories.",
category="architecture",
tags=["data-access", "testing", "separation-of-concerns"]
))
Pattern Lifecycle
- Create a pattern when you discover a useful approach
- Search for patterns relevant to your current task
- Adopt a pattern for a specific project
- Suggest patterns for a project based on its context
# Search for relevant patterns
results = client.patterns.search(query="how to structure database queries")
# Adopt a pattern for a project
client.patterns.adopt(pattern.id, project="billing-service")
# Get suggestions for a project
suggestions = client.patterns.suggest(project="billing-service")
Patterns have a scope field that determines visibility. Patterns can be scoped to a specific project or shared globally across your account.
Projects
A project represents a codebase, service, or initiative. Projects provide multi-project context management with dependency tracking.
from memoryrelay import ProjectCreate
project = client.projects.create(ProjectCreate(
name="Billing Service",
slug="billing-service",
description="Handles invoicing, payments, and subscription management.",
tech_stack=["python", "fastapi", "postgresql", "stripe"]
))
Project Relationships
Track dependencies between projects:
from memoryrelay import ProjectRelationshipCreate
client.projects.add_relationship("billing-service", ProjectRelationshipCreate(
target_slug="user-service",
relationship_type="depends_on",
description="Billing service calls user-service for customer data."
))
Impact Analysis
Understand the ripple effects of changes:
from memoryrelay import ImpactAnalysisRequest
impact = client.projects.impact_analysis(ImpactAnalysisRequest(
project_slug="user-service",
change_description="Changing the user ID format from integer to UUID"
))
# Shows which dependent projects would be affected
Shared Patterns
Discover patterns used across two projects:
shared = client.projects.shared_patterns("billing-service", "user-service")
# Returns patterns adopted by both projects
How Everything Connects
erDiagram
AGENT ||--o{ MEMORY : contains
AGENT ||--o{ SESSION : tracks
MEMORY ||--o{ ENTITY : mentions
ENTITY ||--o{ ENTITY : "relates to"
SESSION ||--o{ MEMORY : groups
AGENT ||--o{ DECISION : records
PROJECT ||--o{ PATTERN : adopts
PROJECT ||--o{ PROJECT : "depends on"
DECISION }o--o{ DECISION : supersedes
- Agents own memories, sessions, and decisions
- Memories reference entities and optionally belong to sessions
- Entities link to each other forming a knowledge graph
- Decisions track their own lifecycle and supersession chain
- Projects adopt patterns and declare dependencies on other projects
- Patterns are shared across projects and discovered by semantic search