# How Skill Extraction Works and What Triggers Automatic Skill Creation in TencentDB-Agent-Memory

> Understand how skill extraction works in TencentDB-Agent-Memory. Discover what triggers automatic skill creation when conversations end with final answers.

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

---

**Skill extraction triggers automatically when a conversation round ends with a final answer, buffering normalized messages until a threshold is met and then archiving them for the extraction pipeline.**

The **TencentCloud/TencentDB-Agent-Memory** repository implements an intelligent skill extraction system that observes human-to-assistant conversations and automatically generates skills when sufficient context accumulates. Unlike naive turn-level logging, this system uses a **round-level** lifecycle to capture complete problem-solving exchanges while minimizing unnecessary RPC traffic. Understanding the specific triggers and extraction pipeline requires examining the proxy-to-core flow that begins in `MemoryProxy` and culminates in the `SkillExtractor`.

## The Round-Level Trigger Architecture

Skill extraction operates on **conversation rounds** rather than individual HTTP turns to avoid fragmenting tool-use loops into separate archives.

### Detecting Final Answers

The extraction trigger depends on identifying a **final answer**—an assistant message that concludes the current round without pending tool calls. In [`MemoryProxy/src/skill/handler-glue.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/MemoryProxy/src/skill/handler-glue.ts), the `triggerSkillExtractIfReady` function inspects each assistant message using `isFinalAnswer`, which checks for the absence of `tool_use` or `tool_calls` blocks. Only messages meeting this criteria initiate the extraction sequence, ensuring that incomplete tool chains do not prematurely flush the buffer.

### Round Slicing Strategy

Once a final answer is confirmed, the system slices the conversation to isolate the current round. The `findLastFinalAssistant` utility (lines 11-13 of the handler glue) locates the previous final message in the full history. The slice begins immediately after this marker, capturing only the new user-assistant exchange. If no prior final message exists—indicating the first round—the entire conversation is sent instead. This approach guarantees **one archive per human-to-assistant exchange** rather than one per HTTP request, dramatically reducing buffer pressure during multi-turn tool loops.

## The Automatic Skill Creation Pipeline

After slicing, the normalized conversation flows through a three-stage pipeline that culminates in automatic skill generation.

### Entry Point and Capability Checks

The `triggerSkillExtractIfReady` function serves as the central gatekeeper. Before processing, it validates that:

- The user has skill capability enabled via `assetCapabilities: { skill: true }`
- The session and Core-Skill endpoint are available
- The current assistant reply is definitively a final answer

If any check fails, the pipeline aborts silently to prevent disrupting the primary response path.

### Protocol Normalization

The `normalizeConversation` function in [`MemoryProxy/src/skill/normalize-conversation.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/MemoryProxy/src/skill/normalize-conversation.ts) transforms protocol-specific message formats into a unified **5-role schema**: `user`, `assistant`, `tool_call`, `tool_result`, and `system`. This normalization handles Anthropic's block-based content structures and OpenAI's separate `tool_calls` fields, ensuring the core service receives consistent data regardless of the inbound protocol (`anthropic`, `openai`, or `responses`).

### Core Buffering and Archiving

The normalized messages are transmitted to the core Skill service via `SkillClient.addConversation` (defined 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)), which POSTs to `/v3/skill/conversation/add`. The core buffers these messages per-space according to an internal threshold. When the buffer-size limit is reached, the system automatically archives the conversation and invokes the `SkillExtractor` (implemented in [`MemoryCore/src/core/skill/skill-extractor.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/MemoryCore/src/core/skill/skill-extractor.ts)) to generate skill candidates. The gateway handlers in [`MemoryCore/src/gateway/skill-handlers.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/MemoryCore/src/gateway/skill-handlers.ts) manage this buffering logic and return `status: "archived"` when extraction begins.

## Implementation Examples

The following examples demonstrate how to manually invoke the extraction flow and normalize conversation data.

### Triggering Extraction Manually

```typescript
import { triggerSkillExtractIfReady } from
  "./MemoryProxy/src/skill/handler-glue.js";

await triggerSkillExtractIfReady({
  config: proxyConfig,
  sessionKey: "sess-123",
  sessionInfo: {
    user_id: "u1",
    team_id: "t1",
    agent_id: "a1",
    space_id: "s1",
  },
  inputMessages: [{ role: "user", content: "How to list tables?" }],
  assistantMessage: {
    role: "assistant",
    content: "Here is the answer…",   // no tool_use → final answer
  },
  protocol: "openai",
  agentSource: "gpt-4",
  assetCapabilities: { skill: true },
});

```

### Normalizing Protocol-Specific Messages

```typescript
import { normalizeConversation } from
  "./MemoryProxy/src/skill/normalize-conversation.js";

const raw = [
  { role: "user", content: "Write a function." },
  { role: "assistant", tool_calls: [{ /* … */ }] },
  { role: "assistant", content: "Here is the result." },
];
const norm = normalizeConversation(raw, "anthropic", null, "claude-code");
// → [{role:"user",content:"Write a function."},
//    {role:"assistant",content:"Here is the result."}]

```

## Summary

- **Round-level extraction**: The system waits for complete human-to-assistant exchanges rather than logging every HTTP turn, preventing premature buffer saturation during tool loops.
- **Final answer trigger**: Only assistant messages without pending `tool_use` or `tool_calls` initiate the extraction sequence via `triggerSkillExtractIfReady`.
- **Automatic skill creation**: The core service buffers normalized conversations and automatically archives them when thresholds are met, triggering the `SkillExtractor` pipeline without manual intervention.
- **Protocol agnostic**: The `normalizeConversation` utility standardizes Anthropic, OpenAI, and response formats into a unified 5-role schema before transmission.

## Frequently Asked Questions

### What is the difference between round-level and turn-level skill extraction?

**Round-level extraction** captures the complete user-assistant exchange from question to final answer, whereas turn-level extraction would log every individual HTTP request. In TencentDB-Agent-Memory, round-level processing prevents fragmented archives during multi-turn tool-use loops, ensuring that a single human query generates exactly one archive entry regardless of how many internal tool calls occurred.

### How does the system know when to trigger automatic skill creation?

Automatic skill creation triggers when the core service's internal buffer reaches a predefined threshold. The `SkillClient.addConversation` method sends normalized round slices to `/v3/skill/conversation/add`, where the gateway accumulates messages per-space. Once the buffer size limit is met, the conversation is automatically archived and passed to `SkillExtractor` for skill generation, returning `status: "archived"` to the proxy.

### What file handles the protocol normalization for different LLM providers?

The `normalizeConversation` function in [`MemoryProxy/src/skill/normalize-conversation.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/MemoryProxy/src/skill/normalize-conversation.ts) handles normalization. It converts provider-specific formats—such as Anthropic's content blocks or OpenAI's `tool_calls` arrays—into a standardized 5-role schema (`user`, `assistant`, `tool_call`, `tool_result`, `system`) that the core Skill service can process uniformly regardless of the source protocol.

### Why does the extraction only trigger on final answers?

Restricting extraction to final answers (messages without pending tool calls) ensures that the archived conversation represents a complete, meaningful exchange rather than an incomplete intermediate state. This design prevents the core buffer from filling with partial tool-use fragments, which would trigger premature archiving and result in malformed skill candidates that lack resolution context.