# How the Skill Module Handles CRUD Operations and Fast Retrieval in TencentDB-Agent-Memory

> Learn how the Skill Module handles CRUD operations using the SkillClient SDK and achieves sub-millisecond retrieval with its in-memory fast-path matcher in TencentDB-Agent-Memory.

- Repository: [Tencent Cloud/TencentDB-Agent-Memory](https://github.com/TencentCloud/TencentDB-Agent-Memory)
- Tags: how-to-guide
- Published: 2026-08-22

---

**The Skill Module implements atomic CRUD operations through the `SkillClient` SDK while delivering sub-millisecond retrieval performance via an in-memory fast-path matcher that prioritizes exact name matches before BM25 ranking.**

The Skill Module serves as the knowledge-base core within the TencentCloud/TencentDB-Agent-Memory repository, providing persistent storage, versioning, and hybrid search capabilities for agent skills. This architecture separates API handling from storage logic while maintaining a specialized fast-retrieval channel for instant name-based lookups. Understanding how the module orchestrates these layers reveals a system optimized for both data integrity and retrieval speed.

## Architecture Overview

The Skill Module operates through three distinct architectural layers that handle requests from HTTP ingress to persistent storage.

- **API Client Layer**: The `SkillClient` class in [`sdk/memory-core/typescript/src/v3/skill-client.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/sdk/memory-core/typescript/src/v3/skill-client.ts) wraps 15 `/v3/skill/*` HTTP endpoints, managing default isolation fields (`teamId`, `agentId`, `userId`, `taskId`) and request construction.

- **Storage Layer**: `SqliteSkillStore` in [`MemoryCore/src/core/skill/skill-store.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/MemoryCore/src/core/skill/skill-store.ts) manages SQLite persistence with multi-version rows, head-row flags, FTS5 full-text indexing, and optional vector tables for embedding-based search.

- **Fast-Path Layer**: The `nameMatchFastPath` function in [`MemoryCore/src/core/skill/skill-fast-path.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/MemoryCore/src/core/skill/skill-fast-path.ts) provides pure in-memory substring matching that operates in parallel to the main search pipeline.

The `SkillCore` class in [`MemoryCore/src/core/skill/skill-core.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/MemoryCore/src/core/skill/skill-core.ts) orchestrates these layers, handling business logic for versioning, permission checks, and result merging between fast-path and standard search channels.

## CRUD Operations Implementation

All CRUD operations flow through the `SkillClient` SDK, which constructs request bodies by merging per-call parameters with client-wide defaults. The server returns specific error codes (`40001`, `40301`, `40302`) for missing or invalid IDs rather than throwing client-side exceptions.

### Creating and Versioning Skills

The **Create** operation initializes a skill at version 1 with `is_head=true`. When invoked via `SkillClient.create()`, the method builds a request body containing name, content, resources, and metadata:

```typescript
create(params: SkillCreateRequest): Promise<SkillSummary> {
    const body = stripUndefined({
        ...this.ids(params),
        name: params.name,
        content: params.content,
        resources: params.resources,
        metadata: params.metadata,
    });
    return this.http.post(`${V3}/create`, body);
}

```

At the storage layer, `SqliteSkillStore.appendVersion()` in [`MemoryCore/src/core/skill/skill-store.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/MemoryCore/src/core/skill/skill-store.ts) executes three atomic operations within a single transaction: inserting the new row with `is_head=1`, updating the previous head to `is_head=0`, and triggering FTS5 synchronization.

### Reading and Listing Skills

The **Get** operation retrieves either the current head row or a specific historical version through `SkillClient.get()`, executing SQL queries that filter by `skill_id` and either `version` or `is_head=1`.

The **List** operation (`SkillClient.list()`) returns paginated head rows for a team using `SELECT * FROM skills WHERE is_head=1 AND team_id=?`. For full-text retrieval, `SkillClient.search()` invokes `SkillStore.searchSkills()` to perform BM25 ranking, optionally combining results with vector similarity searches when embedding dimensions are configured.

### Updating and Patching Skills

Two distinct update mechanisms handle different modification patterns:

- **Update** (`SkillClient.update()`): Replaces the entire skill markdown content and bumps the version number, invoking `appendVersion()` with the complete new content.

- **Patch** (`SkillClient.patch()`): Applies string-replacement edits (such as `s/Python/JS/g`) to the existing content before creating a new version through the same `appendVersion` store method.

Both operations maintain immutable history by creating new rows rather than modifying existing records, ensuring full audit trails through the versioning system.

### Deletion and Archival

The **Delete** operation (`SkillClient.delete()`) performs a soft archive rather than hard deletion. It marks the head row with `status='archived'` without bumping the version number, preserving the skill's history while removing it from active listings and search results.

## The Fast-Path Retrieval Mechanism

The fast-path channel addresses latency requirements for name-explicit skill recall, processing queries in under 5 milliseconds for datasets containing 80,000 skills.

### In-Memory Substring Matching

The `nameMatchFastPath` function in [`MemoryCore/src/core/skill/skill-fast-path.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/MemoryCore/src/core/skill/skill-fast-path.ts) implements a lightweight filter over the in-memory array of skill heads:

```typescript
export function nameMatchFastPath(
  query: string,
  skills: Skill[],
  minLength: number = DEFAULT_NAME_MATCH_MIN_LENGTH,
): Skill[] {
  const q = (query ?? "").toLowerCase().trim();
  if (q === "") return [];
  return skills.filter(
    (s) => s.name.length >= minLength && q.includes(s.name.toLowerCase()),
  );
}

```

This function performs no I/O operations, executing entirely within RAM to check if the lowercase query string contains the lowercase skill name.

### Parallel Search and Result Merging

When `SkillClient.listing()` is invoked, `SkillCore.handleListing` executes two operations concurrently:

1. **Standard Search**: Queries the SQLite store using BM25 full-text search via `SqliteSkillStore.searchSkills()`.
2. **Fast-Path Execution**: Runs `nameMatchFastPath` against the cached head rows in memory.

The results merge with fast-path hits positioned at the front of the result set, followed by deduplicated BM25 and embedding-based results. This merged list renders into an `<available_skills>` block suitable for downstream LLM prompt injection, ensuring immediate recall for exact name matches while preserving semantic search capabilities for broader queries.

## Working with the Skill Module SDK

### Complete CRUD Workflow

The following TypeScript example demonstrates the full lifecycle using the SDK:

```typescript
import { SkillClient } from "tencentdb-agent-memory";

const skills = new SkillClient({
  endpoint: "https://memory.tencentyun.com",
  apiKey: "sk-REPLACE_WITH_KEY",
  serviceId: "mem-abc",
  teamId: "team-1",
  agentId: "agent-coder",
  userId: "user-42",
});

// Create
const created = await skills.create({
  name: "py-tips",
  content: "---\nname: py-tips\nsummary: Python best-practices\n---\n",
});

// Update (full replacement)
const updated = await skills.update({
  skill_id: created.skill_id,
  name: "py-tips",
  content: "---\nname: py-tips\nsummary: Updated Python tricks\n---\n",
});

// Patch (string replacement)
await skills.patch({
  skill_id: created.skill_id,
  patch: "s/Python/JS/g",
});

// Delete (soft archive)
await skills.delete({ skill_id: created.skill_id });

```

### Fast Retrieval Integration

To leverage the fast-path optimization when fetching skills for prompt context:

```typescript
const listing = await skills.listing({
  pagination: { limit: 20 },
});

console.log(listing.listing_block); // Pre-formatted <available_skills> block

```

### Direct Store Access

For advanced use cases requiring direct database interaction:

```typescript
import { SqliteSkillStore } from "./MemoryCore/src/core/skill/skill-store";
import { openSync } from "sqlite3";

const db = openSync(":memory:");
const store = new SqliteSkillStore({ db, dimensions: 0 });
store.init(); // Creates tables and FTS5 index

await store.appendVersion({
  skill_id: "skill-123",
  name: "demo-skill",
  content: "Hello world",
  user_id: "u1",
  owner_agent_id: "a1",
  team_id: "t1",
  task_id: "",
});

```

## Summary

- **Atomic Versioning**: All write operations (create, update, patch) invoke `SqliteSkillStore.appendVersion()` to create immutable historical records with automatic head-row management.

- **Soft Deletion**: The delete operation sets `status='archived'` without removing data or incrementing versions, preserving complete audit trails.

- **Dual-Channel Search**: The system combines BM25 full-text search with an in-memory fast-path matcher to prioritize exact name matches while maintaining semantic search capabilities.

- **Sub-Millisecond Fast-Path**: The `nameMatchFastPath` function executes entirely in RAM, filtering 80,000 skills in under 5 milliseconds by performing substring matches against skill names.

- **Schema Isolation**: The `SkillClient` automatically injects `teamId`, `agentId`, `userId`, and `taskId` into all requests, enforcing multi-tenant data isolation at the API layer.

## Frequently Asked Questions

### What is the difference between Update and Patch operations in the Skill Module?

**Update** replaces the entire skill markdown content and metadata with new values, while **Patch** applies a string-replacement transformation (such as regex substitution) to the existing content before saving. Both operations create new version rows through `SqliteSkillStore.appendVersion()`, but Patch allows surgical edits without resubmitting the full document.

### How does the fast-path retrieval achieve sub-millisecond performance?

The fast-path operates entirely in memory through the `nameMatchFastPath` function in [`MemoryCore/src/core/skill/skill-fast-path.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/MemoryCore/src/core/skill/skill-fast-path.ts), performing simple lowercase substring checks against cached skill names without database I/O. Because it avoids SQLite queries and runs as a pure JavaScript filter operation, it processes tens of thousands of skills in under 5 milliseconds.

### Does deleting a skill permanently remove it from the database?

No. The `SkillClient.delete()` method performs a soft deletion by updating the head row's `status` field to `'archived'` in [`MemoryCore/src/core/skill/skill-store.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/MemoryCore/src/core/skill/skill-store.ts). The historical versions remain intact, and the version number does not increment, allowing for potential unarchival while immediately excluding the skill from search and listing results.

### How are search results ranked when both fast-path and BM25 results exist?

`SkillCore.handleListing` merges the two result sets by placing fast-path matches at the beginning of the response array, followed by BM25 and embedding-based results. The system deduplicates entries to prevent double-listing, ensuring that name-explicit matches receive top priority in the final `<available_skills>` block while preserving the semantic relevance ordering of traditional search results.