How TencentDB Agent Memory Works with L0-L3 Chat Memory Layers

TencentDB Agent Memory stores conversational context in a four-layer hierarchy where raw messages (L0) are progressively distilled into atomic facts (L1), scene indexes (L2), and core personas (L3), with each layer optimized for different retrieval patterns and token budgets.

The TencentDB Agent Memory repository implements a sophisticated layered memory architecture that separates transient conversation history from long-term agent knowledge. This system organizes data across four distinct tiers—L0 through L3—enabling efficient context management through progressive distillation and selective injection. Understanding how these TencentDB Agent Memory L0-L3 layers interact is critical for developers building AI agents that maintain coherent, long-term interactions without exceeding token limits.

Understanding the Four-Layer Memory Hierarchy

The architecture defines four distinct layers, each with specific storage characteristics and access patterns.

L0: Raw Conversation Messages

L0 maintains the unprocessed turn-by-turn history between users and assistants. This layer captures the complete verbatim conversation as imported from the UI or API.

  • Storage content: Complete JSON arrays of user/assistant message pairs
  • Production method: Direct import via /chat-memory/layer endpoint with layer: 'L0' as defined in MemoryPanel/web/src/lib/api/chat-memory.ts
  • Access pattern: Retrieved on-demand via the tdai_conversation_search tool (/v3/atomic/search)

L1: Atomic Memory Items

L1 contains distilled key-value facts, user preferences, and operational rules extracted from raw conversations.

  • Storage content: Structured metadata items including facts, preferences, and behavioral rules
  • Production method: Automatic distillation from L0 via the "offload" service background job
  • Access pattern: Queried on-demand using tdai_memory_search (/v3/atomic/search)

L2: Scene Index

L2 maintains a navigable index of long-term scenario documentation, storing only metadata and paths rather than full content.

  • Storage content: List of paths to Markdown files describing extended scenarios, plus optional summaries
  • Production method: Generated by the scenario service (/v3/scenario/ls) after L0→L1 distillation
  • Access pattern: Not injected directly; the LLM reads specific scenes via tdai_read_scene (/v3/scenario/read) when needed

L3: Core Persona Memory

L3 represents the agent's stable long-term character, containing principles, decision templates, and persistent identity traits.

  • Storage content: Concise, stable persona snapshot defining agent behavior and principles
  • Production method: Generated once per agent after initial L0 import, stored via /v3/core/read and /v3/core/write
  • Access pattern: Directly injected into the system prompt by TdaiProfileMemoryInjector without requiring tool calls

How the Memory Layers Interact

The system processes memory through a deterministic pipeline: import, distillation, injection, and runtime retrieval.

Layer Import and Background Distillation

When users import memory through the UI, the frontend sends a POST request to /chat-memory/layer as defined in MemoryPanel/web/src/lib/api/chat-memory.ts, specifying layer: 'L0'. The backend stores raw messages and triggers the offload service to run a compacting pipeline that produces the higher layers:

  1. L1 generation: Writes atomic items to the metadata store
  2. L2 generation: Creates scene indexes (paths + summaries) via the scenario service
  3. L3 generation: Produces core persona content stored via core service endpoints

Memory Injection at Session Start

During session initialization, the TdaiProfileMemoryInjector (located in MemoryProxy/src/injection/injectors/tdai-profile-memory-injector.ts) retrieves L3 and L2 data exactly once per agent:

// Retrieve L3 core memory
const l3 = await client.readL3ForCtx(ctx);
// Retrieve L2 scene index (paths only)
const l2Entries = await client.listL2ForCtx(ctx);

The injector constructs a specialized system prompt block:

<tdai_profile_memory>
以下是 TDAI 为当前 agent 维护的长期工作记忆(自有 + 借入分段;L2 仅给索引,按需用工具读全文):
<agent name="…" role="self" agent_id="…">
<l3_core_memory> … </l3_core_memory>
<l2_scene_index>
- `path/to/scene1.md` — Summary …
- `path/to/scene2.md`
</l2_scene_index>
</agent>
</tdai_profile_memory>

Following this injection, the LLM receives a memory-tools-guide paragraph instructing it how to invoke tdai_memory_search, tdai_conversation_search, and tdai_read_scene.

Runtime Tool-Based Retrieval

During conversation, the LLM decides when to query specific layers based on the Memory Usage Rules:

  • For specific facts (e.g., "What's my preferred IDE?"): The LLM calls tdai_memory_search, which the proxy forwards to /v3/atomic/search targeting L1 metadata
  • For historical conversations (e.g., "What did I say yesterday?"): The LLM uses tdai_conversation_search against L0 raw messages
  • For scenario details (e.g., "Tell me about the onboarding scenario"): The LLM first consults the injected L2 index, then calls tdai_read_scene (/v3/scenario/read) to fetch full Markdown content

ACL and Fallback Mechanisms

All TD-AI calls respect ACL checks via TdaiClient.checkAcl. If the injection path is disabled or TD-AI services are unavailable, the injector falls back to injecting only the tools guide, ensuring the LLM never answers without explicit memory lookup.

Implementation Details and Code Examples

Core Client Layer Access

The MemoryProxy/src/tdai/client.ts file implements the primary interface for reading L2 and L3 memory:

import { TdaiClient } from '@tencentdb/agent-memory';
const client = new TdaiClient({ endpoint: 'https://tdai.example.com', apiKey: '…' });
const l3 = await client.readL3ForCtx({ teamId: 'team1', userId: 'u123', agentId: 'a42' });
console.log(l3?.content);   // → persona description

Prompt Injection Implementation

The TdaiProfileMemoryInjector assembles the memory block dynamically:

const client = new TdaiClient(baseConfig);
const groups = await Promise.all(ctxs.map(c => loadAgentProfile(client, c)));

const lines = ['<tdai_profile_memory>'];
for (const g of groups) {
  lines.push(`<agent name=${JSON.stringify(g.ctx.agentName)} role=${JSON.stringify(g.ctx.isSelf ? 'self' : 'imported_from')} agent_id=${JSON.stringify(g.ctx.agentId)}>`);
  if (g.l3?.content) lines.push('<l3_core_memory>', truncate(g.l3.content, 6000), '</l3_core_memory>');
  if (g.l2Entries.length) {
    lines.push('<l2_scene_index>');
    for (const e of g.l2Entries) lines.push(`- \`${e.path}\` ${e.summary ? '— ' + truncate(e.summary, 200) : ''}`);
    lines.push('</l2_scene_index>');
  }
  lines.push('</agent>');
}
lines.push('</tdai_profile_memory>', MEMORY_TOOLS_GUIDE);

Direct API Access via cURL

For L0 conversation search, direct HTTP access follows this pattern:

curl -sfk -X POST https://proxy.example.com/atomic/search \
  -H 'Content-Type: application/json' -H 'x-conversation-id: $SID' \
  -d '{"query":"我之前说过的项目名称","limit":5}'

Type Definitions

The layer enumeration is defined in MemoryPanel/web/src/pages/ChatMemoryPage/constants/types.ts:

type MemoryLayer = 'L0' | 'L1' | 'L2' | 'L3';

Core memory TypeScript SDK types reside in sdk/memory-core/typescript/src/v3/types.ts, declaring CoreReadRequest, CoreWriteRequest, and CoreFile interfaces for L3 operations.

Summary

  • TencentDB Agent Memory implements a four-tier hierarchy (L0-L3) balancing token efficiency with comprehensive context retention
  • L0 (Raw) and L1 (Atomic) remain in cold storage, accessed on-demand via search tools (tdai_conversation_search, tdai_memory_search)
  • L2 (Scene Index) provides lightweight navigation to long-term scenarios, with full content fetched via tdai_read_scene only when referenced
  • L3 (Core Persona) injects directly into system prompts through TdaiProfileMemoryInjector, ensuring immediate access to stable agent characteristics
  • The distillation pipeline automatically processes L0 imports to generate L1-L3, while ACL checks and fallback mechanisms ensure reliable operation

Frequently Asked Questions

What is the difference between L2 and L3 memory access in TencentDB Agent Memory?

L3 core memory is directly injected into the system prompt at session start, making it immediately available without tool calls. L2 scene memory is not injected; only file paths and optional summaries appear in the prompt. When the LLM needs L2 content, it must explicitly call tdai_read_scene to retrieve the full Markdown file. This distinction preserves token budget while maintaining access to extensive scenario documentation.

How does the memory distillation process work when importing L0 data?

When you import L0 raw messages via /chat-memory/layer, the system triggers the offload service background job. This service runs a compacting pipeline that extracts atomic facts for L1 (stored in metadata), creates file path indexes for L2 (stored in the scenario service), and generates a stable persona snapshot for L3 (stored in the core service). This process happens asynchronously after the initial L0 storage.

Which tool should the LLM use to retrieve specific user preferences from memory?

For specific facts, preferences, or rules stored as atomic items, the LLM should use tdai_memory_search. This tool queries the L1 layer through the /v3/atomic/search endpoint. For raw conversation history, use tdai_conversation_search (L0). For detailed scenario documentation, use tdai_read_scene (L2) after consulting the L2 index.

What happens if the TD-AI memory service is unavailable during prompt injection?

If TdaiProfileMemoryInjector detects that TD-AI services are unavailable or ACL checks fail, it implements a graceful fallback. Rather than failing silently or omitting memory capabilities entirely, it injects only the memory-tools-guide paragraph. This ensures the LLM understands that memory tools exist but cannot answer based on cached persona data, forcing explicit tool usage when services recover or maintaining transparency about memory limitations.

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 →