Overview
Hindsight is a biomimetic memory system for AI agents. It provides three core operations — retain, recall, reflect — modeled on how human memory stores, retrieves, and consolidates information.
Core Operations
Retain
Store a memory item with metadata:
from hindsight import HindsightClient
client = HindsightClient(api_url="http://localhost:8765")
client.retain(
content="User prefers dark mode and vim keybindings",
tags=["preference", "ui", "user:alice"],
mission="user-preferences",
source="conversation",
)
Recall
Retrieve relevant memories via semantic search:
results = client.recall(
query="what does the user prefer for editor settings",
mission="user-preferences",
limit=5,
)
for memory in results.memories:
print(f"[{memory.score:.2f}] {memory.content}")
Reflect
Consolidate and summarize a set of memories into higher-level insights:
reflection = client.reflect(
mission="user-preferences",
prompt="Summarize the user's core preferences across all sessions",
)
print(reflection.summary)
Deployment Modes
| Mode | When | Setup |
|------|------|-------|
| Local | Development, single machine | pip install hindsight-all |
| Self-hosted | Production, own infra | Docker compose |
| Cloud | Managed, multi-agent | api.hindsight.vectorize.io |
Local Setup
pip install hindsight-all
# Start the server
hindsight serve --port 8765
# Verify
curl http://localhost:8765/health
Docker (Self-Hosted)
# docker-compose.yml
services:
hindsight:
image: hindsight/server:latest
ports:
- "8765:8765"
volumes:
- ./data:/data
environment:
- HINDSIGHT_DB_PATH=/data/memories.db
Cloud
client = HindsightClient(
api_url="https://api.hindsight.vectorize.io",
api_key=os.environ["HINDSIGHT_API_KEY"],
)
Memory Bank Design
Memory banks are logical partitions. Design them around access patterns, not data types.
# Good: partition by agent role
client.retain(content="...", mission="user-profile")
client.retain(content="...", mission="project-context")
client.retain(content="...", mission="agent-decisions")
# Bad: one giant bank for everything
client.retain(content="...", mission="everything")
Mission Naming Conventions
| Pattern | Example | Use |
|---------|---------|-----|
| {role}-{domain} | agent-preferences | Agent-specific knowledge |
| {user}-{session} | alice-2026-05 | User session memories |
| {project}-context | clawcontrol-context | Project state |
| {agent}-decisions | merlin-decisions | Decision log |
Tag Schema
Tags enable filtered retrieval. Use a consistent taxonomy:
# Entity tags
tags=["user:alice", "project:clawcontrol", "agent:merlin"]
# Type tags
tags=["preference", "decision", "fact", "error", "success"]
# Domain tags
tags=["ui", "api", "deployment", "security", "database"]
# Combined example
client.retain(
content="Merlin decided to use Convex over Supabase for real-time features",
tags=["decision", "database", "agent:merlin", "project:clawcontrol"],
mission="agent-decisions",
)
Retrieval Strategies
Hindsight supports multiple retrieval modes:
| Strategy | When to Use | |----------|-------------| | Semantic (default) | Natural language queries, concept matching | | BM25 | Exact keyword matching, technical terms | | Graph | Related entity traversal | | Temporal | Recent memories, time-ordered recall | | Hybrid | Production default — semantic + BM25 fused |
# Hybrid retrieval (recommended for production)
results = client.recall(
query="database architecture decisions",
strategy="hybrid",
mission="agent-decisions",
limit=10,
)
OpenClaw Integration
# ~/.openclaw/workspace/skills/hindsight.md
---
name: hindsight
description: Store and retrieve memories from Hindsight memory bank
---
POST http://localhost:8765/memories/retain
content: {the thing to remember}
tags: [relevant, tags]
mission: agent-memory
POST http://localhost:8765/memories/recall
query: {what to look for}
mission: agent-memory
limit: 5
Node.js SDK
import { HindsightClient } from "@hindsight/client";
const client = new HindsightClient({
apiUrl: process.env.HINDSIGHT_API_URL!,
apiKey: process.env.HINDSIGHT_API_KEY,
});
await client.retain({
content: "User prefers TypeScript over JavaScript",
tags: ["preference", "code"],
mission: "user-profile",
});
const { memories } = await client.recall({
query: "programming language preferences",
mission: "user-profile",
limit: 3,
});
Best Practices
- Write at conversation end: retain at session close, not every turn
- Be specific in missions: vague missions produce noisy recall
- Cap tag count: 3–6 tags per memory; more dilutes filtering precision
- Reflect periodically: run reflect weekly to compress growing memory banks
- Index frequently-queried missions: check Hindsight config for explicit indexing options on hot paths