Skip to main content

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:

TierImportanceDescription
Hot>= 0.8Critical knowledge, prioritized in search results
Warm0.4 -- 0.8Standard memories, the default tier
Cold< 0.4Low-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
info

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

TypeExamples
personTeam members, stakeholders, authors
organizationCompanies, teams, departments
technologyLanguages, frameworks, tools, services
projectRepositories, products, initiatives
conceptDesign 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

  1. Create or get-or-create a session when an interaction begins
  2. Store memories with the session ID to associate them
  3. End the session when the interaction completes, optionally with a summary
  4. 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
tip

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

StatusMeaning
activeCurrently in effect, should be followed
supersededReplaced by a newer decision
revertedRolled 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

  1. Create a pattern when you discover a useful approach
  2. Search for patterns relevant to your current task
  3. Adopt a pattern for a specific project
  4. 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")
info

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