| name | tencentdb-agent-memory |
| description | Local-first long-term memory for AI agents with symbolic short-term memory and layered long-term recall via a 4-tier progressive pipeline |
| triggers | ["add agent memory to my project","implement long-term memory for my AI agent","set up TencentDB Agent Memory","configure agent memory with symbolic compression","enable memory layering for my agent","integrate agent memory with OpenClaw","reduce token usage with memory offloading","add persona and scenario memory"] |
tencentdb-agent-memory
Skill by ara.so โ AI Agent Skills collection.
What It Does
TencentDB Agent Memory provides fully local long-term memory for AI agents through a 4-tier progressive pipeline:
- L0 Conversation: Raw dialogue logs
- L1 Atom: Atomic facts extracted from conversations
- L2 Scenario: Scene blocks aggregated from atoms
- L3 Persona: User profile distilled from scenarios
It combines symbolic short-term memory (Mermaid canvas offloading) with layered long-term memory (persona/scenario pyramid) to:
- Cut token usage by up to 61.38% (WideSearch benchmark)
- Improve task success by up to 51.52% relative (WideSearch)
- Boost PersonaMem accuracy from 48% to 76%
Zero external API dependencies โ runs entirely on local SQLite + sqlite-vec.
Installation
For OpenClaw
openclaw plugins install @tencentdb-agent-memory/memory-tencentdb
openclaw gateway restart
For Hermes (Docker)
docker build -f Dockerfile.hermes -t hermes-memory .
docker run -d \
--name hermes-memory \
--restart unless-stopped \
-p 8420:8420 \
-e MODEL_API_KEY="${YOUR_API_KEY}" \
-e MODEL_BASE_URL="https://api.lkeap.cloud.tencent.com/v1" \
-e MODEL_NAME="deepseek-v3.2" \
-e MODEL_PROVIDER="custom" \
-v hermes_data:/opt/data \
hermes-memory
As a Standalone Library
npm install @tencentdb-agent-memory/memory-tencentdb
import { TencentDBMemory } from '@tencentdb-agent-memory/memory-tencentdb';
const memory = new TencentDBMemory({
storage: {
type: 'sqlite',
dbPath: './data/memory.db'
}
});
await memory.initialize();
Configuration
OpenClaw Zero-Config (Minimal)
{
"memory-tencentdb": {
"enabled": true
}
}
Enable Short-Term Compression
{
"memory-tencentdb": {
"enabled": true,
"config": {
"offload": {
"enabled": true
}
}
},
"plugins": {
"slots": {
"contextEngine": "openclaw-context-offload"
}
}
}
Then apply the runtime patch:
bash scripts/openclaw-after-tool-call-messages.patch.sh
Full Configuration Schema
{
"memory-tencentdb": {
"enabled": true,
"config": {
"storage": {
"type": "sqlite",
"dbPath": "./data/memory.db",
},
"llm": {
"provider": "custom",
"apiKey": "${LLM_API_KEY}",
"baseURL": "https://api.lkeap.cloud.tencent.com/v1",
"model": "deepseek-v3.2"
}
Core Concepts
Memory Layers
L3 Persona (user profile, preferences)
โ aggregates from
L2 Scenario (scene blocks, common patterns)
โ extracts from
L1 Atom (atomic facts)
โ distills from
L0 Conversation (raw dialogue)
Symbolic Memory (Mermaid Canvas)
Long tool outputs are:
- Offloaded to external files (
refs/*.md)
- Compressed into Mermaid graph nodes with
node_id
- Recalled via
node_id lookup when needed
graph LR
A["Search Results (50k tokens)"] -->|offload| B[("refs/search-001.md")]
A -->|symbolize| C["node_1234<br/>type: search<br/>summary: 3 key findings"]
C -.recall via node_id.-> B
Usage Examples
Store a Conversation
import { TencentDBMemory } from '@tencentdb-agent-memory/memory-tencentdb';
const memory = new TencentDBMemory({
storage: { type: 'sqlite', dbPath: './memory.db' }
});
await memory.initialize();
await memory.storeConversation({
sessionId: 'session-123',
userId: 'user-456',
messages: [
{ role: 'user', content: 'I prefer tabs over spaces' },
{ role: 'assistant', content: 'Got it, I'll use tabs in code.' }
],
metadata: { topic: 'coding-preferences' }
});
Extract Atoms and Update Persona
await memory.extractAtoms('session-123');
const atoms = await memory.getAtoms('user-456', { limit: 10 });
console.log(atoms);
const persona = await memory.getPersona('user-456');
console.log(persona);
Recall Relevant Memories
const recalled = await memory.recall({
userId: 'user-456',
query: 'how should I format this code?',
topK: 5,
includePersona: true,
includeScenarios: true
});
console.log(recalled);
Offload Tool Output (Short-Term Memory)
const toolOutput = {
tool: 'search',
result: '...(50,000 tokens of search results)...'
};
const offloaded = await memory.offloadContext({
sessionId: 'session-123',
content: toolOutput.result,
metadata: { tool: 'search', timestamp: Date.now() }
});
console.log(offloaded);
const recovered = await memory.recoverContext('node-1234');
console.log(recovered.content);
Query Scenarios
const scenarios = await memory.getScenarios('user-456', {
topic: 'debugging',
limit: 3
});
console.log(scenarios);
Common Patterns
Agent Loop with Memory
async function agentLoop(userId: string, userMessage: string) {
const sessionId = `session-${Date.now()}`;
const memory = await memorySystem.recall({
userId,
query: userMessage,
topK: 5
});
const systemPrompt = `
User Profile: ${memory.persona?.profile || 'No profile yet'}
Relevant memories:
${memory.atoms.map(a => `- ${a.content}`).join('\n')}
Recent scenarios:
${memory.scenarios.map(s => `- ${s.title}: ${s.pattern}`).join('\n')}
`.trim();
const response = await llm.chat({
messages: [
{ role: 'system', content: systemPrompt },
{ role: 'user', content: userMessage }
]
});
await memorySystem.storeConversation({
sessionId,
userId,
messages: [
{ : , : userMessage },
{ : , : response }
]
});
response;
}
Periodic Persona Refresh
async function refreshPersonas() {
const users = await memory.getAllUsers();
for (const userId of users) {
const atomCount = await memory.getAtomCount(userId);
if (atomCount >= 50) {
await memory.updatePersona(userId);
console.log(`Updated persona for ${userId}`);
}
}
}
Offload Long Tool Outputs
async function handleToolCall(tool: string, args: any) {
const result = await executeTool(tool, args);
const tokenCount = estimateTokens(result);
if (tokenCount > 10000) {
const offloaded = await memory.offloadContext({
sessionId: currentSession,
content: result,
metadata: { tool, args }
});
return {
summary: offloaded.summary,
nodeId: offloaded.nodeId,
mermaid: offloaded.mermaidNode
};
}
return result;
}
Troubleshooting
Memory not extracting
Check extraction interval:
{
"memory": {
"autoExtract": true,
"extractInterval": 10
}
}
Manually trigger:
await memory.extractAtoms('session-id');
Persona not updating
Check threshold:
{
"memory": {
"personaUpdateThreshold": 50
}
}
Force update:
await memory.updatePersona('user-id');
Low recall quality
Tune similarity threshold:
{
"recall": {
"topK": 10,
"similarityThreshold": 0.5
}
}
Check embedding model:
{
"embedding": {
"provider": "openai",
"model": "text-embedding-3-small"
}
}
Offload not compressing
Verify offload is enabled:
{
"offload": {
"enabled": true,
"maxContextTokens": 100000
}
}
For OpenClaw, check slot registration:
{
"plugins": {
"slots": {
"contextEngine": "openclaw-context-offload"
}
}
}
Apply runtime patch:
bash scripts/openclaw-after-tool-call-messages.patch.sh
Database errors
SQLite locked:
- Ensure only one process accesses the DB
- Check file permissions on
dbPath
PostgreSQL connection failed:
- Verify credentials and network access
- Check
storage.host, storage.port, storage.database
High memory usage
Reduce embedding dimension:
{
"embedding": {
"model": "Xenova/all-MiniLM-L6-v2",
"dimension": 384
}
}
Limit recall scope:
{
"recall": {
"topK": 3,
"includeScenarios": false
}
}
Environment Variables
LLM_API_KEY=your-api-key-here
POSTGRES_PASSWORD=your-db-password
OPENAI_API_KEY=your-openai-key
Learn More
Key Takeaway: TencentDB Agent Memory lets agents remember user preferences, task context, and solution patterns across sessions โ without dumping everything into context. Use symbolic compression for short-term overload and layered memory for long-term knowledge.