# How TencentDB Agent Memory Architecture Decouples Storage, Routing, and Team Management

> Discover how TencentDB Agent Memory architecture decouples storage, routing, and team management using orthogonal layers for pluggable persistence, data-driven routing, and protocol-agnostic session binding.

- Repository: [Tencent Cloud/TencentDB-Agent-Memory](https://github.com/TencentCloud/TencentDB-Agent-Memory)
- Tags: architecture
- Published: 2026-08-28

---

**TencentDB Agent Memory decouples storage, routing, and team management through three orthogonal layers: the `IStorageBackend` interface for pluggable persistence, the `ProxyConfig` object for data-driven request routing, and the `handleSessionInit` state machine for protocol-agnostic session binding.**

The TencentCloud/TencentDB-Agent-Memory repository implements a modular AI memory system where each architectural layer depends only on well-defined interfaces rather than concrete implementations. This separation allows developers to swap storage backends, adjust routing strategies, or onboard new agent teams without modifying unrelated codebase components.

## The Three-Layer Architectural Model

TencentDB Agent Memory organizes functionality into distinct concerns that communicate through narrow contracts:

- **Storage Layer** – Handles persistence for scene files, persona markdown, and L0/L1 records via the `IStorageBackend` abstraction
- **Routing Layer** – Directs traffic to appropriate LLM endpoints while applying cost-guard and request-splitting rules through configuration objects
- **Team Management Layer** – Binds user sessions to specific teams/agents and manages asset injection through the session initialization state machine

Each layer imports interfaces from lower layers but never concrete implementations, ensuring changes remain isolated.

## Storage Decoupling via the IStorageBackend Interface

All persistence operations in TencentDB Agent Memory flow through a single abstraction defined in [`MemoryCore/src/core/storage/types.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/MemoryCore/src/core/storage/types.ts). Upper-layer modules like `MemoryCore`, `MemoryKnowledge`, and `MemoryProxy` import only this interface, never touching the COS SDK or Node.js `fs` module directly.

### Core Storage Contract

The `IStorageBackend` interface standardizes operations across local filesystem and cloud object storage:

```typescript
// MemoryCore/src/core/storage/types.ts
export interface IStorageBackend {
  readonly type: "local" | "cos";
  putObject(key: string, content: string|Buffer, opts?: PutObjectOptions): Promise<void>;
  appendObject(key: string, content: string|Buffer): Promise<void>;
  getObject(key: string): Promise<StorageObject | null>;
  exists(key: string): Promise<boolean>;
  listObjects(prefix: string, opts?: ListObjectsOptions): Promise<ListResult>;
  deleteObject(key: string): Promise<void>;
  deleteByPrefix(prefix: string): Promise<number>;
}

```

Concrete implementations reside in [`local-backend.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/local-backend.ts) and [`cos-backend.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/cos-backend.ts), selected at runtime via the `StorageBackendConfig` type. Adding Amazon S3 or MinIO support requires only implementing these seven methods and updating the configuration parser—no changes needed to memory management or routing logic.

### Storage Usage Example

```typescript
import { createStorageBackend } from "./core/storage/factory.js";

// Configure COS backend
const cfg = { type: "cos", credentialProvider: myProvider };
const storage = await createStorageBackend(cfg);

// Persist a markdown scene block
await storage.putObject(
  "scenes/my-scene.md",
  "# My Scene\nHello world",

  { contentType: "text/markdown" }
);

```

## Routing Decoupling via ProxyConfig

Request routing decisions in TencentDB Agent Memory derive entirely from the `ProxyConfig` interface defined in [`MemoryProxy/src/types.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/MemoryProxy/src/types.ts). The proxy never hard-codes upstream URLs; instead, it constructs targets from configuration objects enabling dynamic routing without code redeployment.

### Centralized Routing Configuration

The `ProxyConfig` interface encapsulates all routing concerns:

```typescript
// MemoryProxy/src/types.ts
export interface ProxyConfig {
  server: { host: string; port: number; forwardTimeoutMs?: number };
  upstream: {
    url: string;           // Global upstream endpoint
    apiKey: string;
    agents: Record<string, AgentUpstreamEntry>;
  };
  costGuard: CostGuardConfig;
  ccRequestRouting: CcRequestRoutingConfig;
  workbuddyRequestRouting: WorkbuddyRequestRoutingConfig;
}

```

**Per-agent routing** allows specific teams to target dedicated infrastructure:

```typescript
export interface AgentUpstreamEntry {
  url: string;
  apiKey?: string; // Falls back to global key if omitted
}

```

The `forwardToUpstream` function extracts these entries at runtime. For example, workbuddy requests resolve through `config.upstream.agents.workbuddy` while default traffic routes through the global URL.

### Cost-Guard and Request Splitting

The architecture treats **cost-guard** and **CC-request splitting** as pure functions within the routing layer. `CostGuardConfig` toggles private forwarding extensions, while `CcRequestRoutingConfig` enables three-way traffic segmentation (main/fork/side-query) based on `cache_control` markers. These decisions return routing plans without mutating request bodies, preserving separation between routing logic and business logic.

### Dynamic Routing Configuration

```typescript
import { loadConfig } from "./config/loader.js";

const cfg = await loadConfig("./proxy.yaml");

// Enable cost-guard for specific models only
cfg.costGuard.enabled = true;
cfg.costGuard.agentProfile = "gemini";

// Route workbuddy traffic to isolated endpoint
cfg.upstream.agents.workbuddy = {
  url: "https://workbuddy.api.example.com/v1",
  apiKey: "wb-secret-key"
};

```

## Team and Agent Management Decoupling

Team management operates through a protocol-agnostic session initialization layer that binds user contexts to specific agents without coupling to HTTP transport details.

### Session Initialization State Machine

The `handleSessionInit` function exported from [`MemoryProxy/src/session/index.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/MemoryProxy/src/session/index.ts) drives the entire onboarding flow. It accepts minimal input—primarily a `messages[]` array—and returns `SessionInitResult` containing:

- `sessionInfo` – Bound team/agent/task identifiers
- `bypassed` – User opt-out status for "Plan" mode
- `justRegistered` – Session creation flag for pre-warming

All client types (codex, anthropic, workbuddy) reuse this single state machine, ensuring consistent team binding logic across protocols.

### Workbuddy-Specific Session Handling

While sharing the core state machine, workbuddy requests maintain isolated session state through the `WorkbuddySessionState` interface defined in [`MemoryProxy/src/workbuddyHandler.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/MemoryProxy/src/workbuddyHandler.ts):

```typescript
export interface WorkbuddySessionState {
  status: "initialized" | "pending";
  bypassed?: boolean;
  sessionInfo?: Record<string, unknown> | null;
}

```

After successful binding, the `injectWorkbuddyAssets` function constructs injection blocks containing skills and knowledge assets. This function shallow-copies request bodies to ensure other agents' pipelines remain unaffected by workbuddy-specific asset injection.

### Team Binding Workflow

1. **Initial Request** – `handleSessionInit` detects missing `sessionInfo` and returns a form response via `buildCodexFormResponse`
2. **User Selection** – Client submits team, agent, and optional task selections
3. **Persistence** – [`MemoryProxy/src/session/store.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/MemoryProxy/src/session/store.ts) persists the binding under a session key
4. **Asset Injection** – Subsequent requests retrieve bindings and trigger `injectWorkbuddyAssets` for the first message only

### Programmatic Team Assignment

```typescript
import { getSessionStore } from "./session/store.js";

const store = getSessionStore();
const key = "workbuddy:abcd1234";

// Bind session to specific team and agent
await store.bind(key, {
  userId: "user-5678",
  agentSource: "workbuddy",
  sessionId: "abcd1234",
  spaceId: "team-42",
  team_id: "team-42",
  agent_id: "code-assistant"
});

// Retrieve binding for asset injection
const state = await store.get(key);
console.log(state.sessionInfo?.team_id); // "team-42"

```

## Summary

TencentDB Agent Memory achieves architectural decoupling through three key design patterns:

- **Storage abstraction** via `IStorageBackend` enables swapping between local filesystem, Tencent COS, or future backends without touching memory or routing code
- **Configuration-driven routing** through `ProxyConfig` consolidates upstream selection, cost-guard logic, and request splitting into data structures rather than conditional code
- **Protocol-agnostic session management** using `handleSessionInit` and the session store separates team binding logic from transport-specific handlers like [`workbuddyHandler.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/workbuddyHandler.ts)

This separation allows independent scaling and modification of storage infrastructure, routing policies, and team onboarding flows while maintaining system stability.

## Frequently Asked Questions

### How does the storage layer handle backend selection at runtime?

The system uses a factory pattern in [`MemoryCore/src/core/storage/factory.js`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/MemoryCore/src/core/storage/factory.js) that instantiates either `LocalBackend` or `CosBackend` based on the `type` property in `StorageBackendConfig`. Both classes implement the identical `IStorageBackend` contract, allowing the factory to return the appropriate implementation without upstream modules knowing which persistence mechanism is active.

### Can routing rules be changed without restarting the proxy?

Yes. Since `ProxyConfig` is loaded from YAML and referenced throughout the request lifecycle, updating the configuration file and triggering a hot-reload (or restarting the process) immediately applies new routing rules. All routing decisions—including per-agent upstream selection and cost-guard toggles—are pure data transformations from the config object.

### What prevents team management logic from leaking into the routing layer?

The session initialization state machine in `handleSessionInit` operates solely on session metadata and returns results through the `SessionStore` interface. The routing layer ([`workbuddyHandler.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/workbuddyHandler.ts)) checks for existing `sessionInfo` but never contains logic for team selection forms or asset injection—that responsibility remains in the dedicated session management module, accessed only after routing decisions are complete.

### How does the architecture support adding new agent types?

New agents require only three integration points: implementing an `AgentUpstreamEntry` in `ProxyConfig` for routing, potentially extending `SessionStore` bindings for team association, and optionally creating agent-specific injection functions like `injectWorkbuddyAssets`. The storage layer (`IStorageBackend`) and core session state machine require no modifications to support additional agent types.