Skip to main content

Entity Memory

Store named entities and their relationships for structured fact tracking.

Overview​

Entity memory stores structured information about people, organizations, places, concepts, and systems. It enables agents to build a knowledge graph of entities and their relationships, supporting entity-centric queries and relationship traversal.

When to Use​

  • Tracking people, organizations, and systems mentioned in conversations
  • Building knowledge graphs
  • Customer relationship management (CRM) for agents
  • Structured fact storage with relationships
  • Entity extraction from unstructured text

Storage Strategy​

Backend: Vector database (PostgreSQL with pgvector) Why: Entity memory requires:

  • Semantic search to find entities by description
  • Exact lookup by entity name
  • Metadata filtering by entity type
  • Relationship storage in metadata

Entities are embedded for semantic search while metadata enables exact matches and relationship queries.

API Methods​

add_entity​

Add an entity to memory.

async def add_entity(
name: str,
entity_type: str,
description: str,
relationships: list[dict[str, str]] | None = None
) -> str

Parameters:

  • name: Entity name (e.g., "John Smith", "OpenAI", "San Francisco")
  • entity_type: Type ("person", "organization", "location", "concept", "system")
  • description: Description of the entity
  • relationships: Optional list of relationships as dicts with "target" and "type"

Returns: Memory ID

Example:

from memharness import MemoryHarness

async with MemoryHarness("sqlite:///memory.db") as harness:
# Add a person
await harness.add_entity(
name="Anthropic",
entity_type="organization",
description="AI safety company that created Claude",
relationships=[
{"target": "Claude", "type": "created"},
{"target": "San Francisco", "type": "headquartered_in"}
]
)

# Add a concept
await harness.add_entity(
name="Python GIL",
entity_type="concept",
description="Global Interpreter Lock in Python that prevents true parallelism",
relationships=[
{"target": "Python", "type": "part_of"},
{"target": "Threading", "type": "affects"}
]
)

# Add a system
await harness.add_entity(
name="PostgreSQL",
entity_type="system",
description="Open-source relational database system",
relationships=[
{"target": "SQL", "type": "uses_language"}
]
)

search_entity​

Search for entities by semantic similarity or exact match.

async def search_entity(
query: str,
entity_type: str | None = None,
k: int = 5
) -> list[MemoryUnit]

Parameters:

  • query: Search query (entity name or description)
  • entity_type: Optional filter by entity type
  • k: Number of results to return

Returns: List of MemoryUnit objects ordered by relevance

Example:

# Semantic search
people = await harness.search_entity("AI researcher", entity_type="person")

# All organizations
orgs = await harness.search_entity("", entity_type="organization", k=10)

# By description
databases = await harness.search_entity("database management system")

Schema/Metadata Structure​

{
"id": "uuid",
"content": "Anthropic: AI safety company that created Claude",
"memory_type": "entity",
"namespace": ("entity", "organization"),
"metadata": {
"name": "Anthropic",
"entity_type": "organization",
"relationships": [
{"target": "Claude", "type": "created"},
{"target": "San Francisco", "type": "headquartered_in"}
],
# Optional:
"aliases": ["Anthropic AI"],
"properties": {
"founded": "2021",
"employees": "~150"
}
},
"embedding": [0.123, ...],
"created_at": "2026-03-23T10:00:00Z"
}

Best Practices​

1. Entity Extraction Middleware​

Automatically extract entities from conversations:

from memharness.middleware import EntityExtractionMiddleware
from langchain.agents import create_agent

agent = create_agent(
model="anthropic:claude-sonnet-4-6",
tools=[...],
middleware=[
EntityExtractionMiddleware(
harness=harness,
model="anthropic:claude-haiku-4" # Fast model for extraction
)
]
)

# Entities are automatically extracted and stored

2. Relationship Management​

Build a knowledge graph by tracking relationships:

# Add entity with relationships
await harness.add_entity(
name="Alice",
entity_type="person",
description="Software engineer specializing in Python",
relationships=[
{"target": "Python", "type": "specializes_in"},
{"target": "TechCorp", "type": "works_at"},
{"target": "Bob", "type": "colleague_of"}
]
)

# Query by relationship (search for it)
python_experts = await harness.search_entity("specializes in Python")

3. Entity Deduplication​

Merge similar entities:

# Search for potential duplicates
similar = await harness.search_entity("John Smith", entity_type="person")

if len(similar) > 1:
# Merge logic: consolidate relationships, update description
await consolidate_entities(similar)

4. Entity Types Taxonomy​

Use consistent entity types:

ENTITY_TYPES = {
"person": ["individual", "user", "customer"],
"organization": ["company", "institution", "team"],
"location": ["place", "city", "country", "address"],
"concept": ["idea", "theory", "methodology"],
"product": ["service", "tool", "platform"],
"system": ["software", "infrastructure", "technology"]
}

5. Rich Entity Properties​

Store additional properties in metadata:

await harness.add_entity(
name="Claude",
entity_type="product",
description="AI assistant developed by Anthropic",
relationships=[...],
metadata={
"properties": {
"versions": ["claude-3-opus", "claude-sonnet-4-6"],
"release_date": "2023-03-14",
"capabilities": ["text", "vision", "code"]
}
}
)

Automatic Entity Extraction​

Using the extraction middleware:

from memharness.middleware import EntityExtractionMiddleware

# Configure extraction
extractor = EntityExtractionMiddleware(
harness=harness,
model="anthropic:claude-haiku-4",
entity_types=["person", "organization", "location", "concept"]
)

# Entities extracted from:
# - User messages
# - AI responses
# - Knowledge base additions

Next Steps​