# Skill Module

## What is Skill?

Skill is a modular mechanism in the MaiAgent platform for encapsulating AI assistant professional capabilities. Unlike Function Calling which allows LLMs to call a single tool, Skill packages a set of **Instructions**, **Tools**, and **Resources** into a reusable capability unit, enabling AI assistants to dynamically unfold complete task execution workflows during conversations.

In simple terms:

* **Function Calling / Tools**: LLM calls a single API or function
* **Skill**: LLM unfolds a complete set of SOP instructions and calls multiple tools as needed during the process

```
┌─────────────────────────────────┐
│           Skill                 │
│                                 │
│  ┌───────────────────────┐      │
│  │  Instructions (SOP)   │      │
│  │  - Trigger conditions │      │
│  │  - Execution steps    │      │
│  │  - Response format    │      │
│  └───────────────────────┘      │
│                                 │
│  ┌──────┐ ┌──────┐ ┌──────┐    │
│  │Tool A│ │Tool B│ │Tool C│    │
│  └──────┘ └──────┘ └──────┘    │
│                                 │
│  ┌───────────────────────┐      │
│  │  Resources (files)    │      │
│  └───────────────────────┘      │
└─────────────────────────────────┘
```

***

## How Skill Works

### Overall Architecture

The operation of Skill in the MaiAgent system involves the following core components:

| Component           | Description                                                                                        |
| ------------------- | -------------------------------------------------------------------------------------------------- |
| **Skill Model**     | Stores skill name, description, instruction content, and attached tool associations                |
| **ChatbotSkill**    | Many-to-many association between AI assistants and Skills (Junction Model)                         |
| **SkillExpandTool** | Built-in system tool responsible for dynamically expanding skill instructions during conversations |
| **LoadSkillTool**   | Built-in system tool responsible for dynamically loading skill-attached tools                      |
| **SkillFileParser** | Parses uploaded `.skill` / `.zip` files, extracts SKILL.md and resources                           |

### Workflow

```
User inquiry
    │
    ▼
AI assistant receives message
    │
    ▼
LLM analyzes intent, matches descriptions of bound skills
    │
    ├─ Skill matched → Call SkillExpandTool
    │                    │
    │                    ▼
    │              Expand complete skill instruction content
    │              + List available attached tools
    │                    │
    │                    ▼
    │              LLM executes step by step according to instructions
    │              Calls LoadSkillTool to load tools as needed
    │                    │
    │                    ▼
    │              Tool execution results returned to LLM
    │                    │
    │                    ▼
    │              LLM generates response according to instruction format
    │
    └─ Not matched → Regular conversation response
```

### 1. Skill Expansion

When an AI assistant determines that a user's question should be handled by a particular skill, the system calls `SkillExpandTool`:

* **Input**: Skill name (`skill_name`)
* **Processing**: Query skill by name, retrieve complete instruction content and attached tool list
* **Output**: Instruction content in Markdown format + available tool list

```json
{
  "name": "expand_skill",
  "arguments": {
    "skill_name": "休假天數計算"
  }
}
```

### 2. Tool Dynamic Loading

After skill expansion, when the LLM needs to call tools during instruction execution, it dynamically loads them via `LoadSkillTool`:

* **Input**: Tool name (`tool_name`)
* **Processing**: Query tool (supports MCP tools and API tools, case-insensitive)
* **Output**: Tool's ID, name, description, and availability status

This dynamic loading mechanism ensures that skill tools don't need to be fully loaded into the conversation context in advance, reducing token consumption.

***

## SKILL.md Specification

The core definition file for Skill is `SKILL.md`, using YAML Frontmatter + Markdown content format:

```markdown
---
name: Skill name
description: Skill description (determines when AI triggers this skill)
---

# Skill title

## Trigger Conditions
Triggered when user asks XXX related questions.

## Execution Steps

### Step 1: Confirm Information
Guide user to provide necessary information...

### Step 2: Query Data
Use retrieve_text_nodes to search knowledge base...

### Step 3: Generate Response
Reply according to the following format:
- ① Applicable regulations
- ② Calculation results
- ③ Reference examples
```

### Frontmatter Fields

| Field         | Required | Description                                                               |
| ------------- | -------- | ------------------------------------------------------------------------- |
| `name`        | Yes      | Skill name, must be unique within organization                            |
| `description` | Yes      | Skill description, used by LLM to determine whether to trigger this skill |

### Instruction Writing Guidelines

1. **Clear trigger conditions**: Clearly define "when to trigger" and "when not to trigger" in description and instructions
2. **Structured steps**: Use numbered steps (Step 1, Step 2...) for LLM to execute sequentially
3. **Tool call guidance**: Explicitly specify which tool to use and query strategy in steps
4. **Response format definition**: Define final response format using templates or tables to ensure output consistency
5. **Error prevention checklist**: Add checklist at end of instructions for LLM self-verification

***

## Skill Package

### File Structure

Uploaded `.skill` or `.zip` files should contain the following structure:

```
my-skill.skill (ZIP format)
├── SKILL.md          # Required: Skill definition file
├── reference.pdf     # Optional: Reference materials
├── template.xlsx     # Optional: Template files
└── examples/         # Optional: Example data
    └── case1.json
```

### Security Validation

The system performs the following security checks when parsing skill packages:

* **Compression ratio check**: Maximum 100:1 to prevent ZIP bomb attacks
* **Path traversal protection**: Block `../` and other path injection attempts
* **File size limit**: Based on organization's upload limit (default 100 MB)
* **SKILL.md validation**: Must exist and contain valid `name` and `description`

### Storage Architecture

```
S3 storage path:
media/skills/{organization_id}/{skill_id}/package.zip    # Skill package
media/skills/{organization_id}/{skill_id}/resources/     # Resource files
```

***

## API Endpoints

### Skill CRUD

| Method   | Endpoint               | Description                                                   |
| -------- | ---------------------- | ------------------------------------------------------------- |
| `GET`    | `/api/v1/skills/`      | List all skills in organization (supports pagination, search) |
| `POST`   | `/api/v1/skills/`      | Manually create skill                                         |
| `GET`    | `/api/v1/skills/{id}/` | Get skill details                                             |
| `PATCH`  | `/api/v1/skills/{id}/` | Update skill                                                  |
| `DELETE` | `/api/v1/skills/{id}/` | Delete skill (includes S3 cleanup)                            |

### Skill Package Operations

| Method | Endpoint                                 | Description                              |
| ------ | ---------------------------------------- | ---------------------------------------- |
| `POST` | `/api/v1/skills/upload/`                 | Upload `.skill` / `.zip` to create skill |
| `POST` | `/api/v1/skills/{id}/reupload/`          | Re-upload to replace skill package       |
| `GET`  | `/api/v1/skills/{id}/export/`            | Export skill as `.skill` file            |
| `GET`  | `/api/v1/skills/{id}/package-structure/` | View skill package file structure        |

### Resource Management (Nested Routes)

| Method   | Endpoint                                        | Description                                    |
| -------- | ----------------------------------------------- | ---------------------------------------------- |
| `GET`    | `/api/v1/skills/{id}/resources/`                | List skill resource files                      |
| `POST`   | `/api/v1/skills/{id}/resources/`                | Upload resource (manually created skills only) |
| `DELETE` | `/api/v1/skills/{id}/resources/{rid}/`          | Delete resource (manually created skills only) |
| `GET`    | `/api/v1/skills/{id}/resources/{rid}/download/` | Download resource file                         |

### Skill Creation Examples

**Manual creation:**

```json
POST /api/v1/skills/
{
  "name": "退貨處理流程",
  "description": "當客戶要求退貨、換貨時觸發。查詢訂單、確認退貨資格、建立退貨單。",
  "instructions": "# 退貨處理\n\n## Step 1：查詢訂單\n...",
  "attached_tool_ids": [
    "uuid-of-order-query-tool",
    "uuid-of-return-api-tool"
  ]
}
```

**Upload skill package:**

```bash
curl -X POST /api/v1/skills/upload/ \
  -F "file=@my-skill.skill" \
  -F "attached_tool_ids=[\"uuid-1\",\"uuid-2\"]"
```

***

## Binding Skills to AI Assistants

Skills establish many-to-many associations with AI assistants through the `ChatbotSkill` junction model:

* One AI assistant can bind multiple skills
* One skill can be used by multiple AI assistants
* Bind/unbind operations are recorded in the `ChatbotSkillEvent` history tracking table

```
AI Assistant A ──┬── Skill: Return Processing
                 ├── Skill: Product Consultation
                 └── Skill: Email Sending

AI Assistant B ──┬── Skill: Product Consultation  ← Shared
                 └── Skill: Meeting Query
```

***

## Unique Advantages of MaiAgent Skill

### 1. Instruction and Tool Decoupling

Skill instructions and attached tools are managed independently, allowing instruction logic to be adjusted at any time without affecting tool settings, and vice versa. This makes skill maintenance and iteration more flexible.

### 2. Dynamic Expansion Mechanism

Skill instructions are not preloaded into conversation context but are dynamically expanded when the LLM determines they are needed. This significantly reduces token consumption per conversation, especially suitable for AI assistants with numerous bound skills.

### 3. Skill Package Ecosystem

Through the `.skill` file format, skills can be shared and imported between different organizations. Enterprises can build internal skill libraries or package best practices as skill packages for distribution to partners.

### 4. Complete Version Control

Skills created via upload support re-upload (Reupload), allowing skill package content to be updated without deleting the original skill. The system completely replaces the skill package and resource files to ensure version consistency.

### 5. Permission Control

Skill access is controlled by the `chatbot_skill_access` permission. Organization administrators can precisely manage who can create, edit, and delete skills through the role permission system.
