Skip to main content

Memory Overview

BindAI Memory provides a provider-based system for storing, retrieving, searching, and managing application memory. Memory is separate from ordinary conversation history. Conversation state belongs to an agent’s conversational execution, while Memory provides an explicit storage and retrieval layer for records that can persist beyond an individual interaction. The same Memory abstraction can work with different storage implementations, allowing applications to change providers without changing the basic memory API.

What is Memory?

A Memory object provides access to stored MemoryRecord objects. A basic example is:
A memory record can contain a key and value together with additional information such as:
  • Namespace
  • Memory type
  • Metadata
  • Importance
  • Access information
  • Expiration
  • Embeddings
  • Tags
  • Source information
  • Relationships
  • Timestamps

Memory Architecture

BindAI separates the memory interface from its storage implementation. Conceptually:
The application interacts primarily with Memory. The configured MemoryProvider determines how records are stored and retrieved.

Attaching Memory to an Agent

Memory can be explicitly configured on an agent. Using the current builder API:
Memory can also be attached through the agent’s memory configuration API where supported:
Memory is therefore an explicit agent capability rather than something tied to a particular model provider.

Memory Providers

BindAI currently provides multiple memory storage implementations. The current provider set includes:
  • InMemoryProvider
  • SQLiteMemoryProvider
  • PostgreSQLMemoryProvider
  • VectorMemoryProvider
  • PineconeMemoryProvider
  • ChromaMemoryProvider
The common provider abstraction is represented by MemoryProvider. The purpose of the provider abstraction is to allow the same memory operations to work across different storage systems.

In-Memory Storage

InMemoryProvider stores records in the running Python process.
In-memory storage is useful when:
  • Persistence is not required.
  • Tests need isolated storage.
  • An application only needs memory for its current process.
  • Fast local storage is more important than durability.
The records are lost when the process and its in-memory state are discarded.

SQLite Storage

SQLiteMemoryProvider provides file-backed memory storage using SQLite.
SQLite is useful for applications that need local persistence without running a separate database service. Typical use cases include:
  • Local applications
  • Development environments
  • Prototypes
  • Small deployments
  • Persistent test environments

PostgreSQL Storage

BindAI also provides PostgreSQLMemoryProvider. PostgreSQL is appropriate when memory needs to be stored in a shared relational database environment. A provider can be configured for a PostgreSQL-backed application using the provider’s connection configuration. Conceptually:
PostgreSQL is particularly useful when multiple application processes need access to the same persistent memory store. Connection details should be managed securely through application configuration or environment variables rather than being hard-coded into source code.

Vector Memory

VectorMemoryProvider provides memory operations that can work with vector representations.
Vector memory is useful when applications need similarity-oriented memory retrieval in addition to ordinary record storage. The exact search behavior depends on the configured vector-memory implementation and its embedding configuration.

Pinecone Memory

BindAI includes PineconeMemoryProvider for Pinecone-backed memory storage. Pinecone is useful when memory needs to be stored in a managed vector database. Conceptually:
Pinecone configuration should be supplied through secure application configuration. Vector dimensions and embedding configuration must be compatible with the Pinecone index being used.

Chroma Memory

BindAI also provides ChromaMemoryProvider. Chroma can be used for vector-oriented memory storage in applications that want a dedicated vector database implementation. Conceptually:
The appropriate configuration depends on whether Chroma is being used locally or through a configured service.

Choosing a Provider

The appropriate memory provider depends on the application’s requirements. Provider choice should consider:
  • Persistence requirements
  • Deployment environment
  • Search requirements
  • Scale
  • Operational complexity
  • Existing infrastructure

Memory Records

The fundamental unit of memory is MemoryRecord. A record requires:
  • key
  • value
It also supports additional fields such as:
  • namespace
  • type
  • metadata
  • importance
  • access_count
  • last_accessed
  • expires_at
  • embedding
  • score
  • tags
  • source
  • relationships
  • related_keys
  • created_at
  • updated_at
For example:
A record can therefore represent both simple key-value memory and richer application memory.

Namespaces

Memory records can be organized into namespaces.
Memory operations can specify the namespace:
Namespaces help separate logically different collections of memory. For example:
The exact namespace strategy is application-specific.

Memory Types

Memory records have a memory type. The default type is long_term. For example:
BindAI exposes MemoryType for representing memory categories. Applications can use memory types to distinguish different classes of stored information where appropriate.

Storing Memory

Use set() to store a MemoryRecord.
The operation returns a MemoryResult. The provider determines how the record is persisted.

Retrieving Memory

Use get() to retrieve a record by key.
A namespace can also be specified:
Applications should handle the result according to the configured memory provider and result state.

Searching Memory

Memory supports search operations. A basic search is:
Additional parameters can be supplied:
Metadata can also be supplied where supported:
Search behavior depends on the configured provider. In particular, vector-backed providers can use embeddings and similarity-oriented retrieval, while other providers may use different search mechanisms.

Checking for Memory

Use exists() to determine whether a record exists.
A namespace can also be specified:
This is useful when an application needs to check for a record before creating or updating it.

Deleting Memory

Use delete() to remove a specific record.
A namespace can be specified when necessary:
Deletion behavior ultimately depends on the configured provider.

Clearing Memory

Use clear() to remove records from a logical memory collection.
This can be useful for resetting a namespace or clearing test data. Use clearing operations carefully in production applications because they can remove multiple records at once.

Memory Results

Memory operations use MemoryResult for result handling. Conceptually:
The memory result abstraction is separate from:
  • AgentResult
  • ToolResult
Do not assume that the fields of one result type are identical to another.

Memory Lifecycle Management

BindAI includes MemoryManager for managing memory-record lifecycle information.
The manager provides lifecycle operations including:
  • touch()
  • reinforce()
  • weaken()
  • decay()
  • promote()
  • forget()
  • should_promote()
  • should_forget()
  • set_expiration()
  • clear_expiration()
These operations allow applications to implement memory lifecycle policies without putting all lifecycle logic directly into storage providers.

Importance

Memory records contain an importance value. For example:
The memory manager can adjust the importance of a record. To reinforce a memory:
To weaken it:
A decay operation can also be applied:
The exact lifecycle policy is determined by the memory-management implementation and application requirements.

Promotion and Forgetting

The memory manager can determine whether a record should be promoted or forgotten. For example:
Similarly:
These operations provide a foundation for memory lifecycle policies. Applications can use them to decide which memories should become more persistent or which should eventually be removed.

Expiration

Memory records support expiration. For example:
Expiration can later be removed:
Records also expose an expires_at field. Expiration is useful for information that should only remain relevant for a limited period. Examples include:
  • Temporary preferences
  • Session-related information
  • Short-lived application state
  • Time-sensitive records

Access Tracking

Memory records track access information. Relevant fields include:
A record can be touched explicitly:
The memory manager also provides:
This allows applications to track how frequently memories are accessed and when they were last used. Access information can be useful when designing promotion, decay, or forgetting strategies.

Tags

Memory records support tags. For example:
Tags can be checked:
and removed:
Tags provide a lightweight classification mechanism for memory records.

Relationships

Memory records can represent relationships with other records. For example:
Relationships can be retrieved:
Records also provide convenience operations for managing relationships. Relationships are useful when memory records represent connected application concepts rather than isolated values.

Metadata

Memory records support arbitrary metadata. For example:
Metadata can provide additional information about where a memory came from or how it should be interpreted. Metadata can also participate in search filtering where supported by the configured provider.

Embeddings

MemoryRecord supports an optional embedding field. For example:
Vector-oriented providers can use embeddings as part of similarity-based search. Embedding dimensions must be compatible with the vector storage and embedding configuration used by the application.

Serialization

Memory records can be converted to dictionaries.
They can also be reconstructed:
This makes records easier to:
  • Serialize
  • Inspect
  • Test
  • Store in other systems
  • Move between application boundaries
Serialization is particularly useful when memory records need to cross process or storage boundaries.

Memory Registry

BindAI provides a MemoryRegistry abstraction for registering and resolving memory providers. Conceptually, a registry maps provider names to provider implementations:
A custom provider can be registered by name when using the registry API:
It can then be resolved by name:
Available providers can be inspected through the registry API. Provider registration is useful when applications need to extend the supported memory implementations with their own provider types.

Memory and Execution Context

Memory and execution context represent different kinds of state. Use Memory for information that belongs in the application’s memory system. Use execution context for temporary information needed while an operation is running. They should not be treated as interchangeable storage mechanisms.

Memory vs Conversation History

Memory is also different from conversation history. Conversation history represents messages exchanged during a conversational interaction. Memory stores explicit records that can be retrieved independently. Conceptually:
An agent can use both conversation history and memory.

Memory vs Knowledge

Memory and Knowledge are separate BindAI concepts. Memory stores application memory records. Knowledge is primarily concerned with external information ingestion and retrieval. For example:
An agent can use both systems in the same application.

Memory with Agents

Memory can be combined with the other major agent capabilities. For example:
Memory provides stored application information. Knowledge provides retrieved external information. Tools provide executable capabilities. The agent can coordinate these capabilities during execution.

Memory with Workflows

Memory can also be used alongside workflows. A workflow can read memory, perform operations, and write updated records. Conceptually:
This is useful for applications where workflow execution needs to persist information between runs.

Memory with Multi-Agent Systems

Multiple agents can use memory as part of a larger application architecture. For example:
The exact memory-sharing model should be chosen deliberately. Applications should consider whether agents should share:
  • A common namespace
  • Separate namespaces
  • Separate memory providers
  • Different record types
  • Different authorization boundaries
Shared memory should not automatically imply unrestricted access between agents.

Resource Management

Memory supports closing its underlying provider.
Memory can also be used as a context manager:
This is useful for providers that own resources such as database connections or other external resources. Applications should close memory providers when they are no longer needed.

Provider Selection Guidelines

A practical provider-selection approach is:

Use in-memory storage when

  • Persistence is unnecessary.
  • You are writing tests.
  • The application is short-lived.
  • Local simplicity is the priority.

Use SQLite when

  • Persistent local storage is required.
  • A separate database service is unnecessary.
  • The application is relatively small.

Use PostgreSQL when

  • Multiple processes need shared persistent memory.
  • The application already uses PostgreSQL.
  • Relational database infrastructure is available.

Use vector-oriented providers when

  • Similarity search is important.
  • Memory needs semantic retrieval.
  • The application has an embedding pipeline.
  • Vector storage infrastructure is appropriate.

Best Practices

  • Choose a memory provider appropriate for the application’s persistence and retrieval requirements.
  • Use namespaces to separate logical memory collections.
  • Use MemoryRecord as the standard memory representation.
  • Add metadata when records need additional context.
  • Use tags to classify records.
  • Use relationships when records need explicit links.
  • Use expiration for temporary information.
  • Use MemoryManager for lifecycle operations.
  • Track access when memory lifecycle depends on usage.
  • Use SQLite when local file-backed persistence is appropriate.
  • Use PostgreSQL for shared relational persistence.
  • Use vector providers when semantic similarity is required.
  • Keep embedding configuration compatible with the selected vector store.
  • Protect memory operations with appropriate authorization.
  • Do not treat memory as an implicit execution-context store.
  • Close providers when they own external resources.
  • Test memory behavior independently from model-provider behavior.

Complete Example

The following example uses the current Agent.builder() API:
The example separates persistent memory from the agent itself. The memory provider controls storage. The Memory abstraction provides access to the records. The agent receives the memory capability through its configuration.

Summary

BindAI Memory is a provider-based system for storing and retrieving MemoryRecord objects. The current implementation includes:
  • Memory
  • MemoryProvider
  • InMemoryProvider
  • SQLiteMemoryProvider
  • PostgreSQLMemoryProvider
  • VectorMemoryProvider
  • PineconeMemoryProvider
  • ChromaMemoryProvider
  • MemoryRecord
  • MemoryResult
  • MemoryManager
  • MemoryRegistry
Memory supports:
  • Key-based retrieval
  • Search
  • Namespaces
  • Memory types
  • Metadata
  • Tags
  • Relationships
  • Embeddings
  • Expiration
  • Access tracking
  • Lifecycle management
  • Serialization
Agents can explicitly configure memory through the current builder API:
Memory is deliberately separated from conversation history, execution context, tools, and knowledge retrieval. This separation allows applications to choose an appropriate storage provider while keeping their application-level memory logic consistent.