Chat Memory Layers (L0-L3) in TencentDB Agent Memory: Architecture and Implementation

TencentDB Agent Memory implements a four-tier Chat Memory hierarchy (L0-L3) that progresses from raw dialogue storage to persistent knowledge graphs, enabling both short-term context retention and long-term cross-session learning.

The TencentCloud/TencentDB-Agent-Memory repository provides a hierarchical memory system for conversational AI agents. This architecture separates immediate conversation history from distilled knowledge using four distinct Chat Memory layers (L0-L3) that optimize for retrieval speed, storage efficiency, and knowledge reuse.

The Four Layers of Chat Memory

The architecture divides memory into four logical tiers, each with distinct storage characteristics and retention policies.

L0 – Raw Turns

L0 stores every user-assistant message pair exactly as it arrives. This layer guarantees a faithful replay of the original dialogue by maintaining an immutable log of the conversation. Raw turns are kept for the entire session lifetime and are pruned only when the session terminates. In the source code, this queue logic resides in MemoryCore/src/utils/serial-queue.ts.

L1 – Turn-Level Embeddings

L1 contains vector embeddings of each turn, produced by the underlying LLM. These embeddings enable fast similarity search to retrieve the most relevant prior turns based on semantic meaning. This layer uses an in-memory vector store with a configurable time-to-live (TTL), typically expiring after 24 hours. The embedding generation and vector storage are also managed within MemoryCore/src/utils/serial-queue.ts.

L2 – Session Summaries

L2 maintains aggregated, concise summaries of the conversation generated periodically by the LLM. This layer provides a compact long-term view of the session that preserves continuity without loading the full turn history from L0. Summaries are updated every N turns (default approximately 20) and are retained for the lifetime of the session. The summarization pipeline is implemented in MemoryCore/src/utils/stateful-pipeline-manager.ts.

L3 – Global Knowledge Graph

L3 represents structured knowledge extracted from many sessions, including entities, relations, and facts stored in a shared graph database. This layer allows cross-session reuse of learned facts, enabling the agent to "remember" information across distinct users or sessions. Data persists indefinitely and is backed by SQLite or TS-based stores. The graph service logic is found in MemoryKnowledge/src/store/code-graph-service.ts.

How the Layers Interact

When a new turn arrives, the system processes it through the hierarchy in a specific pipeline:

  1. Ingestion: The raw message pair appends to L0 immediately.
  2. Vectorization: The turn embeds and indexes into L1 for similarity-based retrieval.
  3. Summarization: After a configurable threshold, the system synthesizes an L2 summary that compresses older L0 data, keeping short-term memory lightweight.
  4. Knowledge Extraction: Periodically or via explicit calls, salient facts promote from L2 into the L3 knowledge graph, making them available to future sessions.

This flow is documented in the repository diagram assets/images/chat_memory.png and detailed in MemoryCore/v3-api-memorycore-doc.md.

Source Code Implementation

The implementation maps directly to specific source files within the repository:

Layer Source File Purpose
L0 / L1 MemoryCore/src/utils/serial-queue.ts Implements the turn-level queue and in-memory vector store
L2 MemoryCore/src/utils/stateful-pipeline-manager.ts Handles periodic session summarization
L3 MemoryKnowledge/src/store/code-graph-service.ts Manages the persistent knowledge graph
API MemoryCore/v3-api-memorycore-doc.md Documents the public API for layer manipulation

Working with Chat Memory: Practical Example

The following TypeScript example demonstrates how to interact with each layer using the MemoryCore API:

import { MemoryCore } from '@tencentdb/memory-core';

// 1️⃣ Store a new turn (writes to L0 and L1)
await MemoryCore.appendTurn({
  sessionId: 'sess-123',
  role: 'user',
  content: 'What is the capital of France?',
});

// 2️⃣ Retrieve relevant prior turns (queries L1)
const similar = await MemoryCore.searchTurns({
  sessionId: 'sess-123',
  query: 'France capital',
  topK: 5,
});

// 3️⃣ Get current session summary (reads L2)
const summary = await MemoryCore.getSessionSummary('sess-123');

// 4️⃣ Query global knowledge graph (accesses L3)
const facts = await MemoryCore.queryKnowledgeGraph({
  entity: 'France',
  predicate: 'capital',
});

All four methods operate as thin wrappers around the underlying layered stores described in the source files.

Summary

  • L0 provides immutable raw turn storage for session fidelity.
  • L1 enables fast semantic retrieval through vector embeddings.
  • L2 compresses history into summaries for efficient long-context windows.
  • L3 persists structured knowledge across sessions in a graph database.
  • The architecture balances immediate context needs (L0-L2) with long-term learning (L3) through explicit promotion workflows implemented in MemoryCore and MemoryKnowledge modules.

Frequently Asked Questions

How does data flow from L0 to L3?

Data flows sequentially through the layers as conversation volume increases. New turns enter L0 and generate L1 embeddings immediately. After a configurable number of turns (default ~20), the system creates or updates an L2 summary. Finally, explicit extraction calls or periodic background jobs promote salient facts from L2 into the permanent L3 knowledge graph.

What storage backends support each layer?

L0 and L1 utilize in-memory storage with TTL-based expiration for performance. L2 summaries persist in session-scoped storage for the duration of the conversation. L3 uses durable SQLite or TS-based stores according to the implementation in MemoryKnowledge/src/store/code-graph-service.ts, ensuring cross-session durability.

Can I configure the summarization threshold for L2?

Yes. The summarization trigger is configurable via the parameters exposed in MemoryCore/src/utils/stateful-pipeline-manager.ts. The default processes approximately every 20 turns, but this value adjusts based on token limits, conversation density, or explicit API configuration passed to the stateful pipeline manager.

When should I query L3 instead of searching L1?

Query L3 when seeking established facts, entities, or relationships that may have originated in previous sessions or earlier in the current session. Query L1 when retrieving specific verbatim dialogue turns or recent context that requires semantic similarity matching rather than structured knowledge lookup.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →