Building Custom AI Skills with InstructLab Taxonomy
Create domain-specific AI capabilities using InstructLab's taxonomy systemβfrom writing skill definitions to generating synthetic training data and validating fine-tuned models.
An OpenClaw agent without persistent memory loses everything when a session ends or context compacts. By combining four subsystems β memory flush, hybrid search, file-backed notes, and session hooks β you create an agent that remembers across conversations, retrieves relevant context, and builds knowledge over time.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Agent Conversation β
β β
β ββββββββββββββββ ββββββββββββββββ β
β β Memory Search βββββ Session Hook β (on new) β
β β (retrieval) β β (lifecycle) β β
β ββββββββ¬ββββββββ ββββββββ¬ββββββββ β
β β β β
β βΌ βΌ β
β ββββββββββββββββ ββββββββββββββββ β
β β SQLite Index β β Memory Flush β (on compact) β
β β (embeddings) β β (persistence)β β
β ββββββββ¬ββββββββ ββββββββ¬ββββββββ β
β β β β
β ββββββββββ¬ββββββββββββ β
β βΌ β
β ββββββββββββββββ β
β β Notes (*.md) β β
β β File Storage β β
β ββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββThis guide assumes youβre starting from a working OpenClaw Docker Compose deployment on Azure. If you havenβt set that up yet, start with Installing OpenClaw on Azure with Docker.
Create the directory structure and set permissions:
# Create directories
mkdir -p ~/.openclaw/memory/notes
# Set ownership to container's node user (UID 1000)
sudo chown -R 1000:1000 ~/.openclaw/memory
# Set permissions
chmod 770 ~/.openclaw/memory
chmod 770 ~/.openclaw/memory/notesEnable the compaction flush so the agent saves knowledge before context is trimmed:
# Enable the flush
docker compose run --rm openclaw-cli config set \
agents.defaults.compaction.memoryFlush.enabled true
# Set token threshold (flush fires at 4000 tokens before limit)
docker compose run --rm openclaw-cli config set \
agents.defaults.compaction.memoryFlush.softThresholdTokens 4000
# System prompt for the flush agent turn
docker compose run --rm openclaw-cli config set \
agents.defaults.compaction.memoryFlush.systemPrompt \
"Session nearing compaction. Store durable memories now."
# User prompt telling agent what to save and where
docker compose run --rm openclaw-cli config set \
agents.defaults.compaction.memoryFlush.prompt \
"Write any lasting notes to memory/YYYY-MM-DD.md; reply with NO_REPLY if nothing to store."Set up the local embedding model and search parameters:
# Use local embeddings (no external API)
docker compose run --rm openclaw-cli config set \
agents.defaults.memorySearch.provider local
# Embedding model
docker compose run --rm openclaw-cli config set \
agents.defaults.memorySearch.model all-MiniLM-L6-v2
docker compose run --rm openclaw-cli config set \
agents.defaults.memorySearch.local.modelPath \
sentence-transformers/all-MiniLM-L6-v2
# Enable hybrid search
docker compose run --rm openclaw-cli config set \
agents.defaults.memorySearch.query.hybrid.enabled true
# Search weights: 70% semantic, 30% keyword
docker compose run --rm openclaw-cli config set \
agents.defaults.memorySearch.query.hybrid.vectorWeight 0.7
docker compose run --rm openclaw-cli config set \
agents.defaults.memorySearch.query.hybrid.textWeight 0.3
# Candidate multiplier for better recall
docker compose run --rm openclaw-cli config set \
agents.defaults.memorySearch.query.hybrid.candidateMultiplier 4
# Enable embedding cache
docker compose run --rm openclaw-cli config set \
agents.defaults.memorySearch.cache.enabled true
docker compose run --rm openclaw-cli config set \
agents.defaults.memorySearch.cache.maxEntries 50000Give the agent initial knowledge to bootstrap memory search:
cat > ~/.openclaw/memory/notes/system-context.md <<'EOF'
# System Context
## Deployment
- OpenClaw v2026.2.25 on Azure B2s VM
- Docker Compose deployment
- Gateway port: 18789, Control UI: 18790
- Discord channel integration active
## Configuration
- Local embeddings: all-MiniLM-L6-v2
- Hybrid search: 70/30 vector/text split
- Memory flush: 4000 token threshold
- Embedding cache: 50K entries
EOF# Restart to apply all changes
docker compose restart openclaw-gateway
# Verify hook registration
docker logs openclaw-openclaw-gateway-1 | grep "hooks:loader"
# Expected: Registered hook: session-memory -> command:new, command:reset
# Verify config reloads
docker logs openclaw-openclaw-gateway-1 | grep "reload"
# Expected: Multiple "config change applied" entries
# Verify SQLite created
find ~/.openclaw/memory -name "*.sqlite" -ls
# Expected: main.sqlite file
# Test write access
docker exec -it openclaw-openclaw-gateway-1 sh -lc '
echo test > /home/node/.openclaw/memory/._test && \
echo OK && rm -f /home/node/.openclaw/memory/._test
'
# Expected: OKAfter all phases, the relevant config section:
{
"agents": {
"defaults": {
"compaction": {
"memoryFlush": {
"enabled": true,
"softThresholdTokens": 4000,
"systemPrompt": "Session nearing compaction. Store durable memories now.",
"prompt": "Write any lasting notes to memory/YYYY-MM-DD.md; reply with NO_REPLY if nothing to store."
}
},
"memorySearch": {
"provider": "local",
"model": "all-MiniLM-L6-v2",
"local": {
"modelPath": "sentence-transformers/all-MiniLM-L6-v2"
},
"query": {
"hybrid": {
"enabled": true,
"vectorWeight": 0.7,
"textWeight": 0.3,
"candidateMultiplier": 4
}
},
"cache": {
"enabled": true,
"maxEntries": 50000
}
}
}
}
}Hereβs what happens during a real agent conversation:
session-memory hook fires (command:new)memory/YYYY-MM-DD.mdNO_REPLY or confirms savesession-memory hook fires (command:reset)| Component | RAM | CPU Impact |
|---|---|---|
| OpenClaw Gateway | ~200 MB | Low |
| MiniLM-L6-v2 Model | ~80 MB | Spikes on embedding |
| Embedding Cache (50K) | ~73 MB | None |
| SQLite Index | ~10-50 MB | Low (I/O bound) |
| Notes Storage | < 1 MB | None |
| Total Memory System | ~363-403 MB | Moderate |
The B2s VM has 4 GB RAM β the memory system uses about 10% of available memory. Monitor with:
docker stats openclaw-openclaw-gateway-1# Check hook is registered
docker logs --tail=50 openclaw-openclaw-gateway-1 | grep "session-memory"
# Count memory notes
ls -la ~/.openclaw/memory/notes/ | wc -l
# Check SQLite size
ls -lh ~/.openclaw/memory/main.sqlite
# Check disk usage
du -sh ~/.openclaw/memory/# Reindex memory (after manual note edits)
docker compose run --rm openclaw-cli memory reindex
# Review agent-generated notes
cat ~/.openclaw/memory/notes/$(date +%Y-%m-%d).md
# Backup memory
tar czf ~/backup/openclaw-memory-$(date +%Y%m%d).tar.gz \
~/.openclaw/memory/Problem: Agent doesn't remember previous sessions
β
ββ Check: Hook registered?
β ββ No β Verify memoryFlush + memorySearch config
β
ββ Check: Notes exist?
β ββ No β Test write permissions, check flush config
β
ββ Check: SQLite has data?
β ββ No β Run `memory reindex`
β
ββ Check: Search returns results?
β ββ No β Verify model + hybrid config
β
ββ Check: Notes are relevant?
ββ No β Tune search weights or improve flush prompts# Increase soft threshold proportionally
docker compose run --rm openclaw-cli config set \
agents.defaults.compaction.memoryFlush.softThresholdTokens 8000# Increase candidate multiplier
docker compose run --rm openclaw-cli config set \
agents.defaults.memorySearch.query.hybrid.candidateMultiplier 8
# Increase cache
docker compose run --rm openclaw-cli config set \
agents.defaults.memorySearch.cache.maxEntries 100000# Shift toward vector search
docker compose run --rm openclaw-cli config set \
agents.defaults.memorySearch.query.hybrid.vectorWeight 0.85
docker compose run --rm openclaw-cli config set \
agents.defaults.memorySearch.query.hybrid.textWeight 0.15This is Part 25 of the OpenClaw series β the capstone article tying together memory flush, hybrid search, file storage, and session hooks into a production-ready persistent memory architecture.
AI & Cloud Advisor with 18+ years experience. Author of 8 technical books, creator of Ansible Pilot. Speaker at KubeCon EU & Red Hat Summit 2026.
Create domain-specific AI capabilities using InstructLab's taxonomy systemβfrom writing skill definitions to generating synthetic training data and validating fine-tuned models.
How to access the OpenClaw Control UI dashboard from an Azure VM β via SSH tunnel (secure) or public IP. Covers device pairing, dashboard authentication, and the browser-based management interface.
Deep dive into OpenClaw gateway bind modes (loopback, lan, tailnet, auto, custom), Control UI origin enforcement, and the allowedOrigins vs dangerouslyAllowHostHeaderOriginFallback trade-off.