# Skill 技能模組

## 什麼是 Skill？

Skill（技能）是 MaiAgent 平台中用於封裝 AI 助理專業能力的模組化機制。與 Function Calling 讓 LLM 能呼叫單一工具不同，Skill 將一組**指令（Instructions）**、\*\*工具（Tools）**與**資源檔案（Resources）\*\*封裝為一個可重複使用的能力單元，使 AI 助理能夠在對話過程中動態展開完整的任務執行流程。

簡而言之：

* **Function Calling / 工具**：LLM 呼叫單一 API 或函式
* **Skill**：LLM 展開一整套 SOP 指令，並在流程中按需調用多個工具

<figure><img src="/files/wFffRsR5PnJG3Ih3agSF" alt=""><figcaption><p>技能（Skill）= 指令（Instructions）+ 工具（Tools）+ 資源（Resources）</p></figcaption></figure>

***

## Skill 的運作原理

### 運作流程

```
使用者提問
    │
    ▼
AI 助理接收訊息
    │
    ▼
LLM 分析意圖，比對已綁定技能的描述
    │
    ├─ 匹配到技能 → 呼叫 SkillExpandTool
    │                    │
    │                    ▼
    │              展開技能的完整指令內容
    │              + 列出可用的附加工具
    │                    │
    │                    ▼
    │              LLM 依指令逐步執行
    │              按需呼叫 LoadSkillTool 載入工具
    │                    │
    │                    ▼
    │              工具執行結果回傳 LLM
    │                    │
    │                    ▼
    │              LLM 依指令格式生成回覆
    │
    └─ 未匹配 → 一般對話回覆
```

### 1. 技能展開（Skill Expansion）

當 AI 助理判斷使用者的問題應由某個技能處理時，系統會呼叫 `SkillExpandTool`：

* **輸入**：技能名稱（`skill_name`）
* **處理**：根據名稱查詢技能，取得完整指令內容與附加工具列表
* **輸出**：Markdown 格式的指令內容 + 可用工具清單

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

### 2. 工具動態載入（Tool Loading）

技能展開後，LLM 在執行指令過程中若需要調用工具，會透過 `LoadSkillTool` 動態載入：

* **輸入**：工具名稱（`tool_name`）
* **處理**：查詢工具（支援 MCP 工具與 API 工具，名稱不區分大小寫）
* **輸出**：工具的 ID、名稱、描述與可用狀態

這種動態載入機制讓技能的工具不需要預先全部載入對話上下文，降低 Token 消耗。

***

## SKILL.md 規格

Skill 的核心定義檔案為 `SKILL.md`，使用 YAML Frontmatter + Markdown 內容格式：

```markdown
---
name: 技能名稱
description: 技能描述（決定 AI 何時觸發此技能）
---

# 技能標題

## 觸發條件
使用者詢問 XXX 相關問題時觸發。

## 執行步驟

### Step 1：確認資訊
引導使用者提供必要資訊...

### Step 2：查詢資料
使用 retrieve_text_nodes 搜尋知識庫...

### Step 3：產出回覆
依照以下格式回覆：
- ① 適用法規
- ② 計算結果
- ③ 參考範例
```

### Frontmatter 欄位

| 欄位            | 必填 | 說明                   |
| ------------- | -- | -------------------- |
| `name`        | 是  | 技能名稱，組織內不可重複         |
| `description` | 是  | 技能描述，LLM 用於判斷是否觸發此技能 |

### 指令內容撰寫建議

1. **觸發條件明確**：在描述和指令中清楚定義「何時觸發」與「何時不觸發」
2. **步驟結構化**：使用編號步驟（Step 1, Step 2...）讓 LLM 能循序執行
3. **工具呼叫指引**：在步驟中明確指出應使用哪個工具與查詢策略
4. **回覆格式定義**：用模板或表格定義最終回覆的格式，確保輸出一致性
5. **防錯清單**：在指令末尾加入檢查清單，讓 LLM 自我驗證結果

***

## 技能包（Skill Package）

### 檔案結構

上傳的 `.skill` 或 `.zip` 檔案應包含以下結構：

```
my-skill.skill (ZIP 格式)
├── SKILL.md          # 必要：技能定義檔
├── reference.pdf     # 選填：參考資料
├── template.xlsx     # 選填：模板檔案
└── examples/         # 選填：範例資料
    └── case1.json
```

### 安全性驗證

系統在解析技能包時會進行以下安全檢查：

* **壓縮比檢查**：最大 100:1，防止 ZIP 炸彈攻擊
* **路徑遍歷防護**：阻擋 `../` 等路徑注入
* **檔案大小限制**：依組織設定的上傳限制（預設 100 MB）
* **SKILL.md 驗證**：必須存在且包含有效的 `name` 和 `description`

***

## API 端點

### Skill CRUD

| 方法       | 端點                     | 說明                 |
| -------- | ---------------------- | ------------------ |
| `GET`    | `/api/v1/skills/`      | 列出組織內所有技能（支援分頁、搜尋） |
| `POST`   | `/api/v1/skills/`      | 手動建立技能             |
| `GET`    | `/api/v1/skills/{id}/` | 取得技能詳情             |
| `PATCH`  | `/api/v1/skills/{id}/` | 更新技能               |
| `DELETE` | `/api/v1/skills/{id}/` | 刪除技能（含 S3 清理）      |

### 技能包操作

| 方法     | 端點                                       | 說明                        |
| ------ | ---------------------------------------- | ------------------------- |
| `POST` | `/api/v1/skills/upload/`                 | 上傳 `.skill` / `.zip` 建立技能 |
| `POST` | `/api/v1/skills/{id}/reupload/`          | 重新上傳替換技能包                 |
| `GET`  | `/api/v1/skills/{id}/export/`            | 匯出技能為 `.skill` 檔案         |
| `GET`  | `/api/v1/skills/{id}/package-structure/` | 查看技能包檔案結構                 |

### 資源管理（巢狀路由）

| 方法       | 端點                                              | 說明             |
| -------- | ----------------------------------------------- | -------------- |
| `GET`    | `/api/v1/skills/{id}/resources/`                | 列出技能資源檔案       |
| `POST`   | `/api/v1/skills/{id}/resources/`                | 上傳資源（僅手動建立的技能） |
| `DELETE` | `/api/v1/skills/{id}/resources/{rid}/`          | 刪除資源（僅手動建立的技能） |
| `GET`    | `/api/v1/skills/{id}/resources/{rid}/download/` | 下載資源檔案         |

### 建立技能範例

**手動建立：**

```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"
  ]
}
```

**上傳技能包：**

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

***

## 技能與 AI 助理的綁定

技能透過 `ChatbotSkill` 中介模型與 AI 助理建立多對多關聯：

* 一個 AI 助理可綁定多個技能
* 一個技能可被多個 AI 助理使用
* 綁定/解綁操作會記錄在 `ChatbotSkillEvent` 歷史追蹤表中

```
AI 助理 A ──┬── 技能：退貨處理
            ├── 技能：產品諮詢
            └── 技能：郵件發送

AI 助理 B ──┬── 技能：產品諮詢  ← 共用
            └── 技能：會議查詢
```

***

## MaiAgent Skill 的獨特優勢

### 1. 指令與工具解耦

技能的指令內容和附加工具是獨立管理的，可以隨時調整指令邏輯而不影響工具設定，反之亦然。這使得技能的維護和迭代更加靈活。

### 2. 動態展開機制

技能指令不會預先載入對話上下文，而是在 LLM 判斷需要時才動態展開。這大幅減少每次對話的 Token 消耗，尤其適用於綁定大量技能的 AI 助理。

### 3. 技能包生態

透過 `.skill` 檔案格式，技能可以在不同組織間分享與匯入。企業可以建立內部技能庫，或將最佳實踐封裝為技能包分發給合作夥伴。

### 4. 完整的版本控管

上傳方式建立的技能支援重新上傳（Reupload），可在不刪除原有技能的情況下更新技能包內容。系統會完整替換技能包與資源檔案，確保版本一致性。

### 5. 權限控管

技能的存取受 `chatbot_skill_access` 權限控制，組織管理員可透過角色權限系統精細管理誰能建立、編輯和刪除技能。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.maiagent.ai/tech/advanced-genai-tech/skill.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
