Memory Graph

The Memory Graph is a semantic knowledge graph that provides persistent, structured memory for the agent. It extracts entities, relationships, and facts from conversations and stores them in a queryable database.

Memory vs Memory Graph

GoClaw has two complementary memory systems:

FeatureFile MemoryMemory Graph
StorageMarkdown filesSQLite database
StructureFree-form textEntities & relationships
SearchSemantic searchHybrid search + filters
UpdatesManual editsTool-based CRUD
ContextLoaded at session startDynamically injected
IngestionAutomatic (file read)Requires goclaw graph ingest

Use both systems together:

  • File memory — For notes, logs, and human-readable records. Files in your workspace (MEMORY.md, daily notes) are read directly by the agent.
  • Memory graph — For structured facts and automatic recall. Requires explicit ingestion to process markdown files into the graph.

Overview

The memory graph:

  • Extracts entities — People, places, projects, preferences, facts
  • Tracks relationships — How entities relate to each other
  • Maintains context — Automatically injects relevant memories into conversations
  • Supports queries — Agent can search and retrieve specific memories

How It Works

  1. Live extraction — As conversations happen, the system extracts notable information
  2. Batch ingestion — Markdown files and transcripts are processed via CLI
  3. Entity resolution — New information is merged with existing entities
  4. Embedding generation — Memories are embedded for semantic search
  5. Context injection — Relevant memories are automatically included in the system prompt

CLI Commands

GoClaw provides CLI commands for managing the memory graph. These are essential for ingesting content and inspecting the graph state.

goclaw graph ingest

Ingest content into the memory graph. This is the only way to process markdown files and transcripts into memories.

goclaw graph ingest [flags]
FlagDefaultDescription
--sourceallSource to ingest: markdown, transcript, or all
--userownerUsername to ingest for
--max-age0Maximum age in days for transcripts (0 = no limit)

Examples:

# Ingest everything (markdown + transcripts)
goclaw graph ingest

# Ingest only markdown files
goclaw graph ingest --source markdown

# Ingest transcripts from the last 30 days
goclaw graph ingest --source transcript --max-age 30

# Ingest for a specific user
goclaw graph ingest --user alex

What gets ingested:

  • Markdown — Files in your workspace matching include patterns
  • Transcripts — Conversation history stored in the sessions database

The ingestion process:

  1. Scans sources for new or changed content (content hashing)
  2. Skips items already ingested with matching hash
  3. Extracts memories using the summarization LLM
  4. Stores memories with entity relationships

Ingestion is incremental — Running ingest multiple times only processes new or changed content.

goclaw graph stats

Show memory graph statistics:

goclaw graph stats

Output:

# Memory Graph Statistics

- Total Memories: 211
- Total Associations: 3
- With Embeddings: 0

## By Type
- decision: 20
- fact: 13
- observation: 19
- preference: 22
- event: 81
- goal: 10
- identity: 9
...

## Ingestion
- markdown_sources: 45
- markdown_memories: 28
- transcript_sources: 6971
- transcript_memories: 142
- live_sources: 497
- live_memories: 50

The “Ingestion” section shows how many source items have been processed and how many memories were extracted from each source type.

Search the memory graph from the command line:

goclaw graph search <query> [flags]
FlagDefaultDescription
--userownerUsername to search for
--limit10Maximum results

Examples:

# Search for coffee preferences
goclaw graph search "coffee preferences"

# Search with more results
goclaw graph search "project deadlines" --limit 20

goclaw graph bulletin

Generate memory bulletins — the context summaries injected into agent system prompts.

goclaw graph bulletin <type> [flags]
ArgumentDescription
memoryIdentity, goals, preferences, recent events and decisions
contextPending todos and time-sensitive items
FlagDefaultDescription
--userownerUsername to generate for

Memory bulletin example:

goclaw graph bulletin memory
## Identity
- User's name is Alex
- User's handle is alexdev

## Active Goals
- Research AI agent memory designs
- Improve tool performance for long-running workflows

## Preferences
- Prefers Go programming language over Python
- Active on Twitter with interests in AI agents and tech policy

## Recent Events
- Memory extraction feature went live on 2026-03-06
- Arrived home at 16:44 based on HomeAssistant event

## Recent Decisions
- Include timestamps in message metadata rather than system prompt
- Output facts directly rather than LLM-synthesized summaries

Context bulletin example:

goclaw graph bulletin context
# Context Bulletin for alexdev
Generated: 2026-03-07T21:44:39+02:00

## Pending Todos
- Buy supplies from store tomorrow (March 7th)
- Add uninstall functionality to skills tool

Configuration

Basic Configuration

{
  "memoryGraph": {
    "enabled": true,
    "dbPath": "~/.goclaw/memory-graph.db"
  }
}
FieldTypeDefaultDescription
enabledbooltrueEnable memory graph
dbPathstring~/.goclaw/memory-graph.dbSQLite database path

Ingestion Configuration

Control what files are ingested:

{
  "memoryGraph": {
    "ingestion": {
      "includePatterns": ["*.md", "memory/*.md", "albums/*.md"],
      "excludePatterns": ["skills/**", "ref/**", "goclaw/**", ".*/**"],
      "transcriptBatchSize": 25
    }
  }
}
FieldTypeDefaultDescription
includePatternsarray["*.md", "memory/*.md", "albums/*.md"]Files to include (relative to workspace)
excludePatternsarray["skills/**", "ref/**", "goclaw/**", ".*/**"]Files to exclude (takes priority)
transcriptBatchSizeint25Chunks per LLM call for transcript ingestion

Patterns use glob syntax relative to the workspace directory.

Live Extraction Configuration

Control automatic extraction from conversations:

{
  "memoryGraph": {
    "liveExtraction": {
      "enabled": true,
      "agentExtraction": true,
      "intervalSeconds": 120,
      "minMessages": 5,
      "maxTurns": 10,
      "batchSize": 50,
      "excludeSources": ["heartbeat", "cron", "delivered"]
    }
  }
}
FieldTypeDefaultDescription
enabledbooltrueEnable live extraction
agentExtractionbooltrueAllow agent to store memories via tool
intervalSecondsint120Background check interval
minMessagesint5Minimum messages before extraction
maxTurnsint10Max extraction loop turns
batchSizeint50Max messages per batch
excludeSourcesarray["heartbeat", "cron", "delivered"]Sources to exclude

Bulletin Configuration

Control context bulletin injection:

{
  "memoryGraph": {
    "bulletin": {
      "enabled": true,
      "maxIdentity": 5,
      "maxGoals": 5,
      "maxPreferences": 5,
      "maxEvents": 5,
      "maxDecisions": 5
    }
  }
}

Agent Tools

The agent has access to six tools for managing the memory graph:

memory_graph_recall

Retrieve relevant memories for the current context. This is the primary tool for accessing memories.

{
  "tool": "memory_graph_recall",
  "input": {
    "query": "user's coffee preferences",
    "limit": 5
  }
}

Returns memories ranked by relevance using hybrid search (semantic + keyword).

memory_graph_query

Search and filter memories with more control than recall.

{
  "tool": "memory_graph_query",
  "input": {
    "mode": "typed",
    "memory_type": "todo",
    "happens_within": "7d",
    "sort_by": "scheduled",
    "max_results": 10
  }
}

Supports filtering by memory type, occurred_at date ranges, happens_at windows for scheduled items, and other metadata.

memory_graph_store

Add a new memory to the graph.

{
  "tool": "memory_graph_store",
  "input": {
    "content": "Project deadline for v1 launch",
    "memory_type": "todo",
    "happens_at": "2026-04-01",
    "reasoning": "User set a real deadline that should be queryable and appear in upcoming bulletins"
  }
}
FieldTypeDescription
contentstringThe memory content
memory_typestringEntity type (preference, fact, event, etc.)
reasoningstringWhy the memory is worth storing
occurred_atstringWhen the memory was observed/recorded or when a past event happened
happens_atstringWhen a scheduled event, plan, appointment, or deadline is set to happen
confidencefloatConfidence score (0-1) for pattern-style memories

Use occurred_at for observation or past-event timing, and happens_at for structured scheduling of future events and deadlines. next_trigger_at remains internal to routine and prediction behavior.

memory_graph_update

Modify an existing memory.

{
  "tool": "memory_graph_update",
  "input": {
    "id": "mem_abc123",
    "content": "User now prefers medium roast coffee",
    "confidence": 0.95
  }
}

memory_graph_forget

Remove a memory from the graph.

{
  "tool": "memory_graph_forget",
  "input": {
    "id": "mem_abc123",
    "reason": "User corrected this information"
  }
}

The reason field is optional but helps with audit trails.

memory_graph_skip

Explicitly document why information is not being stored. Used during memory extraction to log skip decisions.

{
  "tool": "memory_graph_skip",
  "input": {
    "content": "User mentioned the weather",
    "reason": "transient, not about user"
  }
}

This tool is primarily used by the automatic extraction process to provide visibility into what was considered but not stored. Useful for debugging extraction behavior.

Context Bulletin

When bulletin injection is enabled, the memory graph automatically generates a context bulletin that’s injected into the system prompt. This includes:

  • Recently accessed memories
  • Memories relevant to the current conversation
  • Important facts about the user
  • Upcoming scheduled events and deadlines driven by happens_at

The bulletin is regenerated periodically and when context changes significantly.

Entity Types

Common entity types used in the memory graph:

TypeDescriptionExamples
identityUser identity informationname, handle, role
preferenceUser preferences“likes dark mode”, “prefers tea”
factFactual information“works at Acme Corp”
eventPast or future events“vacation in June”
decisionDecisions made“chose React over Vue”
goalActive goals“learn Rust this year”
routineRegular patterns“morning coffee at 8am”
observationObserved behaviors“tends to work late”
todoPending tasks“buy groceries”
anomalyUnusual occurrences“power outage on March 1”

For dated event, todo, and goal memories, store machine-readable schedule timing in happens_at instead of relying only on prose in content.

Automatic Extraction

When live extraction is enabled, the system monitors conversations and extracts:

  • Stated preferences (“I prefer…”, “I like…”)
  • Personal facts (“I work at…”, “My birthday is…”)
  • Relationships (“My wife Sarah…”, “My colleague John…”)
  • Events and plans (“Next week I’m…”, “Last month we…”)

Extraction runs in the background and doesn’t interrupt conversations.

Troubleshooting

Memories not being recalled

  1. Check that bulletin injection is enabled
  2. Verify the memory was stored with correct entities
  3. Try a direct memory_graph_recall query to test retrieval

Extraction not working

  1. Verify live extraction is enabled
  2. Check logs for extraction errors
  3. Ensure embedding provider is configured

Markdown files not in graph

Markdown files require explicit ingestion:

goclaw graph ingest --source markdown

Check that your files match the include patterns and aren’t excluded.

Database issues

The memory graph uses SQLite. If corruption occurs:

# Backup current database
cp ~/.goclaw/memory-graph.db ~/.goclaw/memory-graph.db.bak

# Delete and let GoClaw recreate
rm ~/.goclaw/memory-graph.db

See Also