Wood Chen

A Deep Dive into Tencent Cloud's memory-tencentdb: What Does It Add to OpenClaw?

0 comments272 views2.5k words

This post was translated from Chinese by AI. If anything reads oddly, the Chinese original is authoritative. 中文原文

@tencentdb-agent-memory/memory-tencentdb is an OpenClaw long-term memory plugin built by the Tencent Cloud team.

It looks like “an extra layer of memory for AI,” but what really deserves a closer look is its runtime requirements: the Node version, the limitations of node:sqlite, whether SQLite FTS5 is available, and whether it merely “stores chat logs” or implements a more complete long-term memory system.

After working through it, I felt this plugin was worth a post. Installing it isn't simply a matter of “adding a new feature.” It addresses a very real problem:

AI seems to know everything during a chat, but once you move across sessions, days, or contexts, its memory starts to break down.

Essentially, memory-tencentdb adds that missing capability to OpenClaw.


Bottom line: what does this plugin do?

In short, it's a local long-term memory plugin for OpenClaw.

Rather than simply saving chat logs, it gradually turns conversations into information that's easier to use later. The basic approach is:

  1. Record the raw conversations
  2. Extract “information worth remembering” from them
  3. Organize that information by context
  4. Build a more stable user profile and long-term memory
  5. Retrieve relevant memories before the next conversation starts

So it's less a “chat archiving tool” and more a local memory pipeline.


How is it different from our existing file-based memory?

I had the same question at first.

We already had a similar memory setup:

  • MEMORY.md
  • memory/客观事实.md
  • memory/偏好和观点.md
  • memory/实体/*.md
  • memory/daily/*.md

That setup was already working, with clear advantages:

  • Readable
  • Editable
  • Auditable
  • Clear places to store rules and facts

But it leans toward explicit maintenance. Someone has to write down important information and organize the structure, so memory quality depends heavily on maintenance habits.

memory-tencentdb takes a different approach: automatic capture, automatic distillation, and automatic retrieval.

We had actually already made quite a few improvements to the old setup. It wasn't entirely manual.

For example, we previously used two approaches:

  • Periodically process JSONL through cron: archive and organize the previous day's conversations and runtime artifacts, then extract important information into designated memory files
  • Use AGENTS.md to enforce routine writes: require the agent to write important information such as rules, preferences, corrections, and decisions into that day's memory during conversations, rather than leaving it only in the session context

In other words, the original approach was more like this:

  • Start with raw material
  • Organize it through scheduled tasks
  • Use rules to ensure key information is captured in md files

This method was already quite practical, with clear strengths: stable, readable, controllable, and easy to correct manually.

What memory-tencentdb really adds isn't “memory where there was none.” It takes that workflow a step further: turning organization that previously relied on cron and rules into finer-grained automatic capture, distillation, and retrieval.

More precisely, it doesn't invent an entirely new concept of “memory” from scratch. It adds another layer of automation alongside the existing file-based memory.

To put the distinction plainly:

  • File-based memory is like a knowledge base you organize yourself
  • memory-tencentdb is like an assistant that automatically takes meeting notes, organizes material by topic, and builds profiles of people

Their goals overlap, but their methods differ.


How does it work internally?

The plugin's README divides it into four layers, and I think that breakdown makes sense.

L0: Raw conversation layer

The lowest layer does something straightforward: record the conversations.

It saves each conversation turn locally, usually writing to both:

  • JSONL files
  • A SQLite database

This layer is like a raw activity log. It makes few judgments and focuses on preserving the facts first.

L1: Structured memory layer

Once the raw conversations are available, the plugin calls a model to extract “information worth keeping long term.”

For example:

  • The user likes concise, direct replies
  • The user prefers confirming capability limits before choosing a fix
  • A conversation ended with a decision to switch the runtime to Node 24
  • A particular plugin must support FTS5, rather than simply skipping it as a fallback

This is no longer “recording.” It's “distillation.”

L2: Context synthesis layer

As L1 memory entries accumulate, the plugin abstracts them further, organizing scattered facts into contextual blocks.

For example:

  • Fixing OpenClaw plugin compatibility
  • Reworking the memory system
  • International logistics content production and publishing workflows

Later retrieval can then bring back a reasonably complete context, rather than just isolated sentences.

L3: User profile layer

The next level is a more stable user profile.

This layer isn't concerned with individual messages. It focuses on the habits, preferences, working methods, and decision-making style a person demonstrates over time.

For example:

  • Values finding the real root cause over superficial fixes
  • Prefers minimally invasive solutions with rollback and fallback options
  • Communicates concisely and directly
  • Verifies capability limits before proceeding with changes

At this point, it's getting quite close to a “long-term cognitive model.”


Why is it more than just “remembering chat logs”?

Because truly useful memory has never been about “piling up every message forever.”

Simply archiving chat logs has value, of course, but the problems are clear:

  • A large volume of information
  • High retrieval costs
  • Much of the content isn't worth keeping long term
  • When you need it, finding the useful parts quickly is difficult

The value of memory-tencentdb is that it doesn't just store the original text. It builds a pipeline:

Original text → Structured memory → Context → User profile → Automatic retrieval

In other words, it isn't just “storing more.” It tries to turn stored information into context that can actually help later.


How do you install it?

The installation command is straightforward:

openclaw plugins install @tencentdb-agent-memory/memory-tencentdb

After installation, restart the gateway:

openclaw gateway restart

If you only read the README, that seems to be all there is to it.

But in my actual installation, the problem appeared right after this seemingly routine step.


The real catch: the plugin installs, but FTS5 is unavailable

After I first installed the plugin, a key message appeared in the logs, roughly saying:

  • FTS5 tables NOT available
  • no such module: fts5

This meant the plugin had started, but the SQLite FTS5 full-text search capability it depended on wasn't actually available.

For context, FTS5 is SQLite's full-text search module.

Without it, the plugin isn't completely unusable, but much of its keyword search and full-text search functionality is limited, making the memory system considerably less effective.

The key question isn't “does SQLite exist?” It's:

Does the node:sqlite bundled with the current Node runtime actually have FTS5 compiled in?

This is where the troubleshooting got more involved.


Why does the Node version affect SQLite FTS5?

Many people assume SQLite is a system-level component: once installed, it's available.

But in Node, things aren't that simple.

memory-tencentdb uses node:sqlite. This means it depends not just on whether the system has SQLite, but on the SQLite capabilities bundled with or bound into Node itself.

My tests under Node 23 showed:

  • sqlite_compileoption_used('ENABLE_FTS5') = 0
  • CREATE VIRTUAL TABLE ... USING fts5 failed immediately

In other words, the problem wasn't incorrect SQL in the plugin or a bad configuration. The node:sqlite in this Node 23 runtime simply didn't have FTS5.

A further round of research confirmed this: Node 23 didn't work here; Node 24 did.


What does this plugin depend on?

Looking at its current dependencies, there are three core components:

1) node:sqlite

This is the foundation of all local memory storage.

It handles:

  • The local SQLite database
  • Memory and conversation indexes
  • FTS5 full-text search

To get this working reliably now, Node 24 is effectively a requirement.

2) sqlite-vec

This is a vector search extension for SQLite.

It enables semantic similarity search: finding content not just by keywords, but by similarity in meaning.

If embeddings are configured later, this becomes especially important.

3) node-llama-cpp

This dependency supports local models.

It's mainly used for capabilities such as local embeddings and offline vectorization.

Judging by the plugin's design, it is clearly moving toward “keeping as much as possible local and minimizing reliance on external APIs.”

Where the local vectors come from

During my testing, I triggered a warmup and confirmed that it really does start a local model.

  • Model name: embeddinggemma-300m
  • Default model path: hf:ggml-org/embeddinggemma-300m-qat-q8_0-GGUF/embeddinggemma-300m-qat-Q8_0.gguf
  • Download location: ~/.node-llama-cpp/models/hf_ggml-org_embeddinggemma-300m-qat-Q8_0.gguf
  • Vector dimensions: 768
  • Context window: 256 tokens (the code conservatively truncates input to 512 characters)

On my machine, the first warmup went like this:

  • It first downloaded a model of about 328.58MB
  • The download took about 9 seconds
  • Including loading and creating the embedding context, it was ready in around 15 seconds

This also shows that it isn't “hardcoded to do keyword search only.” It can convert text into vectors locally, then pass them to sqlite-vec for retrieval.

Is it configurable?

There are two layers to this:

  • Configuration currently exposed to users: mainly remote embedding (apiKey / baseUrl / model / dimensions)
  • Local embedding model path and cache directory: you can change modelPath / modelCacheDir in the code, but the default configuration doesn't directly expose these local settings

So for most users, the simplest way to understand it is:

  • No remote embedding configured → uses local node-llama-cpp by default
  • Want to switch local models → for now, you need to change the defaults in the code, or wait for the local parameters to be exposed

Another important detail: we ended up tightening the plugin's Node version requirement to:

"engines": {
  "node": ">=24.0.0"
}

This isn't just for show. We had already verified that:

  • Node 23: FTS5 was unavailable
  • Node 24: node:sqlite + FTS5 worked properly

Once the actual compatibility boundary is clear, there's no reason to pretend that “22+ is all roughly the same.”


How does this plugin integrate with OpenClaw now?

Looking at the plugin code, it hooks into two key points:

1) before_prompt_build

Before the model starts answering, it automatically recalls memories.

That means it:

  • Reads the current user input
  • Searches for relevant memories
  • Injects the retrieved results into the context for this turn

This step determines whether the AI can “remember what it needs to before answering.”

2) agent_end

After a conversation ends, it automatically captures memories.

That means it:

  • Records the raw L0 conversation
  • Notifies the scheduler
  • Triggers L1 / L2 / L3 processing later when the conditions are met

I think this design makes sense because it separates “recall” from “consolidation”:

  • Recall happens before the answer
  • Consolidation happens after the answer

That's much cleaner than cramming everything into a single hook.


What does it actually bring to OpenClaw?

Talking only about concepts would be too abstract. I'd rather describe the practical effects.

First, stronger continuity across sessions

Previously, if you didn't manually write information into memory files, the next conversation might not pick it up.

Now the plugin can automatically consolidate some of that content, making later retrieval and recall much more natural.

Second, raw conversations are no longer “seen once, then gone”

Many systems can only remember conclusions you've manually organized, while the raw conversations themselves are hard to reuse.

This plugin preserves L0, effectively retaining the raw source material and evidence layer.

Third, memory is no longer just “a pile of keywords”

With file-based memory alone, you often know the information is there, but you have to organize its structure yourself.

This plugin adds a few more distillation steps, pushing it toward “long-term memory that can be used automatically.”

Fourth, it leaves room for future automation

Things like embedding, vector search, scene block, and persona may not feel especially impactful at first, but they determine whether the system can keep evolving.


Does it have limits? Of course

I don't think installing this kind of plugin magically solves everything.

It has several very real limitations.

1) Automatic extraction doesn't guarantee accuracy

When models distill memories, there will always be noise, bias, and overgeneralization.

So no matter how powerful an automated memory system is, it can't fully replace structured memory under manual control.

2) More recall isn't necessarily better

The biggest risk for a memory system isn't “forgetting,” but “recalling the wrong things.”

If retrieval isn't selective, outdated, tangential, and irrelevant information can all slip in and contaminate the context.

3) You can't pretend underlying capability limits don't exist

FTS5 was the clearest example this time.

Often, the problem isn't something you can fix by tweaking the configuration—the underlying capability simply isn't available.

If you don't establish that first, all subsequent optimization is just cosmetic.


My honest assessment after all this tinkering

If I had to give memory-tencentdb a balanced assessment right now, I'd put it this way:

It isn't an essential foundation for getting OpenClaw from 0 to 1, but it is a key enhancement layer that takes OpenClaw from “having memory” to “having an automated long-term memory pipeline.”

In other words:

  • Without it, the system isn't completely without memory
  • But with it, memory takes a big step from “manually maintained” toward “automatically consolidated and recalled”

The prerequisite is getting the runtime environment right first.

For this version in particular, the conclusion is clear:

  • If you want FTS5 to work properly, stop wasting time on Node 23
  • Go straight to Node 24
  • Confirm that node:sqlite really supports FTS5
  • Then start the gateway

That's the time-saving route.


If you want to install it too, here's the shortest route

Based on my experience this time, the shortest route is:

Step 1: Check your Node version

First, make sure you're not on an old environment. Go straight to at least Node 24.

Step 2: Install the plugin

openclaw plugins install @tencentdb-agent-memory/memory-tencentdb

Step 3: Restart the gateway

openclaw gateway restart

Step 4: Check the logs

Don't just check for errors. Look for key information like:

  • Whether it uses node:sqlite
  • Whether it shows FTS5 available
  • Whether the FTS5 tables were initialized successfully

If these checks don't pass, many features will only “look installed.”


One final thought

I'm increasingly convinced that the hard part is never really “adding a memory plugin to AI.” It's this:

  • You need to know what it remembers
  • You need to know how it remembers
  • You also need to know when it hasn't actually remembered anything at all

memory-tencentdb is worth installing, but don't treat it as a plugin that “automatically makes the system smarter once installed.”

It's more like a set of memory infrastructure.

The real value of infrastructure often doesn't become apparent when you first install it, but after you've run it for many days and notice that the system is finally starting to “keep up with the context.”

Related posts

Comments 0