Entity Memory
Facts about companies, projects, and people.
The Entity Memory Store captures structured knowledge about external entities: companies, people, projects, and systems. It accumulates facts about each entity over time.
| Aspect | Value |
|---|---|
| Scope | Configurable (global, user, or custom namespace) |
| Persistence | Long-term |
| Default mode | Agentic |
| Supported modes | Agentic only |
Setup
pip install agno openai sqlalchemy "psycopg[binary]" pgvector
export OPENAI_API_KEY="your-api-key"The examples use a local PostgreSQL database on port 5532. With Docker running, start it using:
Run PgVector
docker run -d \
-e POSTGRES_DB=ai \
-e POSTGRES_USER=ai \
-e POSTGRES_PASSWORD=ai \
-e PGDATA=/var/lib/postgresql \
-v pgvolume:/var/lib/postgresql \
-p 5532:5432 \
--name pgvector \
agnohq/pgvector:18Later configuration fragments reuse the imports and db from the first complete example.
Basic Usage
from agno.agent import Agent
from agno.db.postgres import PostgresDb
from agno.learn import LearningMachine
from agno.models.openai import OpenAIResponses
db = PostgresDb(db_url="postgresql+psycopg://ai:ai@localhost:5532/ai")
agent = Agent(
model=OpenAIResponses(id="gpt-5.2"),
db=db,
learning=LearningMachine(entity_memory=True),
)
# The agent can record entities through its tools
agent.print_response(
"Just met with Acme Corp. They're a fintech startup in SF, "
"50 employees. CEO is Jane Smith. They use Python and Postgres.",
user_id="sales@example.com",
session_id="session_1",
)
# Later, entity knowledge is recalled
agent.print_response(
"What do we know about Acme Corp?",
user_id="sales@example.com",
session_id="session_2",
)Three Types of Knowledge
Facts
Current facts that may later be replaced: "Uses PostgreSQL", "Headquarters in San Francisco", "50 employees"
Events
Time-bound occurrences: "Launched v2.0 on January 15", "Closed $50M Series B", "Had 4-hour outage"
Relationships
Entity connections: Jane Smith → CEO → Acme Corp, Acme Corp → competitor_of → Beta Inc
Updating Facts
Entity memory has no automatic extraction pass. remember_about creates or updates an entity by name, recording facts, dated events, a description, and an optional pointer to a note file. A model judgment can retire an older fact when a new fact contradicts it; the default supersession_threshold is 0.8. This can add a model call during a write.
Agentic Mode
The agent receives tools to manage entities explicitly.
from agno.learn import LearningMachine, LearningMode, EntityMemoryConfig
agent = Agent(
model=OpenAIResponses(id="gpt-5.2"),
db=db,
learning=LearningMachine(
entity_memory=EntityMemoryConfig(mode=LearningMode.AGENTIC),
),
)
agent.print_response(
"Create an entry for Acme Corp - they're a fintech startup with 50 employees.",
user_id="sales@example.com",
)| Tool | Purpose |
|---|---|
remember_about | Record an entity by name with facts, events, description, or a note pointer |
link_entities | Link two named entities with a relationship |
search_entities | Search matching entities, or omit the query to browse by recency |
forget | Retire a fact or archive an entire entity |
Archiving excludes an entity from default search and context. Low-level search can include archived records with include_archived=True.
Data Model
| Field | Description |
|---|---|
entity_id | Unique identifier (e.g., "acme_corp") |
entity_type | Category: "company", "person", "project" |
name | Display name |
description | Brief description |
properties | Key-value metadata |
facts | Current and retired facts, with IDs and time information |
events | Time-bound occurrences |
relationships | Connections to other entities |
Accessing Entity Memory
lm = agent.learning_machine
# Search for entities
entities = lm.entity_memory_store.search(
query="acme",
entity_type="company",
limit=10
)
for entity in entities:
print(f"{entity.name}: {entity.facts}")
# Debug output
lm.entity_memory_store.print(entity_id="acme_corp", entity_type="company")Context Injection
The system context includes a bounded directory of entities and expanded records relevant to the current input. Archived entities are excluded. Configure the rendering limits on EntityMemoryConfig:
| Parameter | Default |
|---|---|
max_entities_in_directory | 50 |
max_entities_in_context | 5 |
max_facts_per_entity | 10 live facts |
max_events_per_entity | 5 recent events |
Truncation is visible in the rendered context. Facts include dates so the agent can distinguish current information from older observations.
Namespaces
Control who can access entity data:
from agno.learn import EntityMemoryConfig
# Global: shared with everyone (default)
entity_memory=EntityMemoryConfig(namespace="global")
# User: private per user
entity_memory=EntityMemoryConfig(namespace="user")
# Custom: explicit grouping
entity_memory=EntityMemoryConfig(namespace="sales_team")An explicit operation namespace overrides the store configuration. Otherwise, the store uses EntityMemoryConfig.namespace; a config still using the "global" default inherits a non-global LearningMachine.namespace. Setting EntityMemoryConfig(namespace="user") is sufficient for user-scoped runtime tools and recall. Supply the trusted user_id on every such run.
Facts vs Events
| Use facts for | Use events for |
|---|---|
| Tech stack | Product launches |
| Headquarters location | Funding rounds |
| Employee count | Outages or incidents |
| Industry/domain | Partnerships announced |
| Pricing model | Key meetings |
Relationship Types
Common patterns for linking entities:
- People:
CEO,CTO,engineer_at,founder,reports_to - Companies:
competitor_of,partner_of,acquired_by,subsidiary_of - Projects:
uses,depends_on,integrates_with,owned_by