實作第一個 Agent Skill
在了解了設計原則後,這篇文章將帶你從零開始,實際動手寫出一個可運作的 Agent Skill。
許多開發者剛接觸 AI 工具開發時,常常不知道該從何下手:「我該建立哪些檔案?」「檔案內容的格式長什麼樣子?」為了解決這個問題,業界逐漸形成了一些標準化的規範。這裡我們將以廣泛支援 Claude 與各式 Agent 的 agentskills.io 規範為基礎,並結合 ChatGPT 自訂動作 (Custom Actions) 的概念,為你詳細拆解技能的開發步驟。
標準化技能的資料夾結構
一個結構良好的 Agent Skill 不應該只是一段散落的提示詞 (Prompt),而是一個具備完整封裝的模組。根據標準規範,一個完整的技能通常包含以下資料夾結構:
my-web-scraper-skill/ # 技能的根目錄(資料夾名稱通常等於技能名稱)
├── SKILL.md # 【必填】核心設定檔:包含技能的元資料與執行指令
├── scripts/ # 【選填】可執行的腳本程式碼(如 Python, Node.js, Bash)
├── references/ # 【選填】參考文件(如 API 文件、Schema 定義)
└── assets/ # 【選填】靜態資源(如輸出格式的範本檔)
這種結構的好處是「漸進式揭露」。Agent 在初始化時只會讀取 SKILL.md 的頭部資訊;直到它確定要使用這個技能時,才會進一步讀取底下的 scripts/ 或 references/,大幅節省 Token 的消耗。
核心檔案:SKILL.md 的撰寫格式
SKILL.md 是整個技能的大腦。它由兩個部分組成:上方的 YAML Front Matter (用來定義元資料),以及下方的 Markdown 本文 (用來撰寫給 AI 看的指令)。
1. 定義元資料 (Front Matter)
這部分是寫給 Agent 的「大腦」看的,讓它知道什麼時候該呼叫這個工具。
---
name: web-scraper-skill
description: 從指定的網址擷取網頁內容,並轉換為乾淨的 Markdown 格式。當使用者要求「讀取網頁」、「總結文章」或提供一個 HTTP 網址時,請使用這個技能。
compatibility: 需要 Python 3.10+ 與 BeautifulSoup 函式庫
---
name: 技能的唯一識別碼(只能使用小寫字母與連字號,且必須與資料夾名稱相同)。description: 最重要的一環!你必須在這裡寫下「這個技能的作用」以及「觸發的時機」。ChatGPT 或 Claude 都是依靠這段文字來決定是否執行此工具。
2. 撰寫執行指令 (Instructions)
在 Front Matter 之後,你要用自然語言加上 Markdown 語法,明確告訴 Agent 觸發技能後該做哪些事。
當你需要讀取網頁內容時,請嚴格遵守以下步驟:
1. 檢查使用者提供的網址是否為有效的 HTTP/HTTPS 連結。
2. 在終端機中執行我們的爬蟲腳本:
```bash
python scripts/fetch.py "<目標網址>"
```
3. 腳本會將結果輸出為 Markdown。請讀取輸出結果,並根據使用者的原始需求進行總結或回答。
**注意事項 (Gotchas):**
- 如果遇到 403 Forbidden 錯誤,請告訴使用者該網站可能阻擋了爬蟲,請勿嘗試重複請求。
在這段指令中,我們清楚定義了 Agent 的操作步驟,甚至把可能遇到的錯誤處理方式都寫進去了。
實戰範例:結合 Scripts 打造網頁擷取技能
為了讓 Agent 能穩定執行任務,我們不應該讓 AI 自己去「猜」怎麼寫爬蟲程式,而是預先寫好一支腳本放在 scripts/ 資料夾中。
以下是 scripts/fetch.py 的簡單範例:
# scripts/fetch.py
import sys
import requests
from bs4 import BeautifulSoup
def fetch_url(url):
try:
# 實作簡單的網頁擷取邏輯
headers = {'User-Agent': 'Mozilla/5.0'}
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status()
soup = BeautifulSoup(response.text, 'html.parser')
# 提取文字並印出
print(soup.get_text(separator='\n', strip=True)[:2000]) # 限制輸出長度
except Exception as e:
print(f"Error fetching URL: {str(e)}", file=sys.stderr)
if __name__ == "__main__":
if len(sys.argv) > 1:
fetch_url(sys.argv[1])
else:
print("請提供目標網址", file=sys.stderr)
這樣設計為什麼好? 當 Claude (例如在 Claude Code 環境下) 收到「幫我總結 https://example.com 的內容」時:
- 它會配對到
web-scraper-skill的 description。 - 閱讀
SKILL.md的指令,得知需要執行python scripts/fetch.py "https://example.com"。 - Agent 在背景執行該腳本,拿回乾淨的文字內容。
- Agent 將文字內容結合自己的語言能力,生成最終總結給使用者。
在 Claude 與 ChatGPT 上的實務差異
雖然上述的 SKILL.md 資料夾結構是針對支援本地開發環境的 Agent(如 Claude Code 或 VS Code Agent)所設計,但背後的開發邏輯與線上平台的設定是完全相通的。
如果你是要在 ChatGPT 上開發 Custom GPTs,或是撰寫 Claude 的 Tool Schema:
SKILL.md裡的description,就等同於你在平台上填寫的 "Description" 欄位。SKILL.md裡的指令與腳本邏輯,則會轉換為提供給平台的 OpenAPI Schema (定義 API 端點、參數格式),而實際的scripts/fetch.py邏輯則會部署在你自己的後端伺服器上。
掌握了如何切割模組、撰寫精準的 Description 以及規劃防呆指令後,無論你使用的是哪一種 AI 平台,都能寫出高穩定性的 Agent Skills!