自己動手做第一個 Skill
第 14 章講了 Skill 是什麼,第 15 章教你裝別人做好的。這一章帶你自己寫一個——用「拍冰箱照片,AI 幫你盤點食材、建議晚餐」當範例,從空白資料夾一步步做到能在 Pi Agent 裡跑起來。完全不用寫程式,寫的是一份給 AI 看的中文工作手冊。
為什麼要自己寫 skill
裝別人的 skill 很爽——上網搜、貼 URL、按裝,AI 就多一項本事。可是別人做的 skill 通常是「通用型」的,例如「幫使用者管檔案」「幫使用者做網頁」,跟你家的實際需求還有一段距離。
自己寫的好處是:你家獨有的重複勞動可以外包給 AI。舉幾個真實例子:
- 每禮拜都要開冰箱一格一格看有什麼、快過期沒——寫成 skill 之後拍一張照片就搞定。
- 老是想不到晚餐煮什麼——寫個 skill 讓 AI 依冰箱現有材料+家人口味推薦。
- 買菜清單老是漏掉東西——寫個 skill 讓 AI 根據週菜單自動生清單。
- 家裡冷氣、洗碗機、烘乾機各有一本電子說明書——寫個 skill 把 PDF 塞進去,之後問「烘乾機顯示 E5 是什麼」就秒答。
更重要的是:寫 skill 不是寫程式。你只是把「碰到 X 情境時,希望 AI 這樣做」用普通中文寫下來,AI 讀得懂。這一章結束時你會有一個能跑的冰箱盤點 skill,之後想寫別的照這個模板改就好。
Skill 就是一份 Markdown 文件
Pi Agent 的一個 skill,實體上就是一個資料夾+裡面一個叫 SKILL.md 的檔。沒了。就這麼簡單。
資料夾結構長這樣:
fridge-check/
└── SKILL.md ← 唯一必要檔案
選配的話還可以在資料夾裡塞:範例照片、範例輸出、額外的參考文件(例如 PDF 說明書)——但這些都不是必要的。只有 SKILL.md 是強制的。
SKILL.md 用 Markdown 寫。Markdown 是一種「純文字帶排版」的寫法,你在 GitHub、Notion、Obsidian 看到的那種,用 # 表示標題、用 - 表示條列。不會沒關係,其實整份文件就算全部平鋪直敘地寫,AI 也讀得懂。
Pi Agent 在啟動時會掃描 /data/pi-agent/skills/ 這個資料夾,把每一個子資料夾當作一個 skill 讀進來。你只要把 fridge-check/ 這個資料夾放到那裡,它就會在 Skills 面板出現。
SKILL.md 的三個必要元素
一份能用的 SKILL.md 由三塊組成,缺一不可:
| 元素 | 是什麼 | 作用 | 必要? |
|---|---|---|---|
| YAML frontmatter | 檔案最上方兩排 --- 之間的鍵值對,含 name 和 description | 告訴 pi-web「這個 skill 叫什麼、什麼時候要用它」 | 是 |
| 本文說明 | frontmatter 下方的 Markdown 內容,通常有幾個 ## 小節 | 告訴 AI「該用這個 skill 時,具體要怎麼做、要問使用者什麼、輸出長怎樣」 | 是 |
| 附加檔案 | 放在同個資料夾內的其他檔案(範例圖、範本文件、PDF 手冊) | AI 執行時可以參考——例如「照 example_output.md 這個格式輸出」 | 否,加分 |
YAML frontmatter 的樣子
YAML 是一種「鍵值對」的寫法,跟 HA 自動化的 YAML 一模一樣。SKILL.md 的 frontmatter 至少要有這兩個欄位:
---
name: fridge-check
description: 使用者傳冰箱照片時,幫他列出食材、找出臨期的、建議晚餐菜色
---
name:skill 的識別字。用英文小寫+連字號(例如fridge-check、dinner-suggest),跟資料夾名稱一致最好。中文可以嗎?技術上可以,但為了避免作業系統路徑編碼問題,還是英文吧。description:最重要的一欄——這是 AI 用來判斷「這一輪對話要不要啟用這個 skill」的依據。寫得越具體、越提到「使用者說什麼/做什麼」時該用,AI 就越會準確叫出來。這欄的重要性等下第 7 節會再講一次。
--- 一定要在檔案最上方(前面不能有空白行、不能有 BOM)。上下各三個減號、獨佔一行。少一個減號、或者中間夾雜多餘空白行,pi-web 就會判定 frontmatter 無效,這個 skill 就整個不會被載入。本文說明的樣子
frontmatter 下方就是自由 Markdown。慣例上會分幾個小節,用 ## 開頭:
- 什麼時候要用這個——具體情境。使用者說了什麼、做了什麼動作、貼了什麼東西時,該啟用。
- 步驟——AI 要按什麼順序做事。第一步、第二步、第三步。
- 注意——禁止的事情、容易踩到的坑、額外要考量的家庭情境。
不強制要這幾個小節、也不強制順序。重點是「AI 讀完知道要做什麼、怎麼做、不能做什麼」。下一節直接看完整範例會更清楚。
一個能跑的最小範例——冰箱盤點 skill
直接看完整檔案。把下面這段複製到一個叫 SKILL.md 的檔案裡就能用:
---
name: fridge-check
description: 使用者傳冰箱照片時,幫他列出食材、找出臨期的、建議晚餐菜色。也在使用者問「今天煮什麼」「冰箱還有什麼」「幫我看看冰箱」時觸發。
---
# Fridge Check Skill
一個幫忙盤點冰箱、判斷食材新鮮度、推薦晚餐菜色的家用小幫手。
## 什麼時候要用這個
當使用者:
- 把冰箱/冷凍庫的照片貼到對話裡
- 說「幫我看看冰箱」「今天煮什麼」「冰箱還有什麼可以用」
- 提到食材、pantry、剩菜、快過期的東西
## 步驟
1. **先描述你看到的食材**——用「位置+品項+大概數量」的格式,例如「上層左邊有一盒鮮乳、右邊兩顆蛋、中層有半顆高麗菜」。看不清楚的物品直接說「有一個看不清楚的白色包裝」,不要猜。
2. **判斷哪些看起來快過期**——顏色變黃、菜葉發蔫、包裝鼓起、有明顯汁液滲出、生鮮明顯褪色。這些通通標出來,並註明「建議 1-2 天內用掉」。
3. **推薦 1-2 道晚餐菜色**——只用還新鮮的食材。優先消耗快過期的。菜色考量到台灣家庭口味(家常菜為主,避免需要買一堆額外食材的異國料理)。
4. **列出「今晚可以做,明天要用掉」的清單**——把第 2 步標出的臨期食材整理成一句一句的提醒。
## 注意
- **不要杜撰你看不到的食材**。照片裡看不到的東西就不要提。
- **不要診斷食物中毒風險或給醫療建議**。發現明顯壞掉的東西只需說「這個看起來壞了,建議丟掉」即可,不要延伸講細菌、腸胃炎等。
- **考量台灣家庭實際情境**——菜色建議以電鍋、平底鍋、瓦斯爐能做的為主,不要推薦烤箱、氣炸鍋要 30 分鐘以上的。
- **保守估計數量**——「大約 3 顆」比「精確 3 顆」安全,因為照片可能有遮擋。
## 輸出格式範例
```
【冰箱盤點】
- 上層:鮮乳 1 盒、雞蛋約 4 顆、剩菜 1 碗
- 中層:高麗菜半顆、紅蘿蔔 2 條、豆腐 1 盒
- 下層蔬果:菠菜 1 把(葉子有點發黃,建議今晚用掉)
【今晚建議菜色】
1. 菠菜炒蛋——用掉發黃的菠菜和 2 顆蛋
2. 麻婆豆腐——用掉整盒豆腐
【明天要用掉】
- 剩下的鮮乳(保存期看標籤)
- 剩菜(今晚沒吃就明天中午)
```
就這樣。整份文件講白話中文,只有 frontmatter 那三行有點格式感。這就是一個完整、能跑的 skill。
把這個 skill 裝到 Pi Agent
寫好 SKILL.md 之後,要放到 Pi Agent 讀得到的地方它才會生效。有兩條路:本地路徑法(快,適合測試)跟 GitHub 法(正式,適合分享)。
-
在自己電腦上開一個資料夾
先在你熟悉的地方——例如桌面——開一個叫
fridge-check/的空資料夾。名字要跟你SKILL.md裡 frontmatter 的name欄位一致,比較不會搞混。 -
把 SKILL.md 放進去
把上一節那份完整範例貼到一個檔案裡,命名為
SKILL.md(完全大寫的 SKILL、副檔名 .md——大小寫錯的話 pi-web 掃不到)。放到剛剛的fridge-check/資料夾裡。現在你的資料夾長這樣:桌面/ └── fridge-check/ └── SKILL.md -
方案 A:本地路徑法(最快,2 分鐘)
用
scp或 SFTP 客戶端(例如 FileZilla、Cyberduck)連到你的 HA host,把整個fridge-check/資料夾丟到/data/pi-agent/skills/底下。用scp的話指令長這樣(把homeassistant.local換成你 HA 的位址):scp -r ~/Desktop/fridge-check [email protected]:/data/pi-agent/skills/丟完之後回 pi-web,按 F5 重整瀏覽器頁面(第 15 章解釋過為什麼要這樣——pi-web 的 Skills 面板不一定會即時偵測新資料夾),Skills 清單裡就會看到
fridge-check。完成。 -
方案 B:GitHub 法(正式,可分享給朋友)
把
fridge-check/資料夾當一個 git repo 推到 GitHub:cd ~/Desktop/fridge-check git init git add SKILL.md git commit -m "Initial fridge check skill" # 到 GitHub 網站建一個叫 fridge-check 的 public repo git remote add origin https://github.com/你的帳號/fridge-check.git git branch -M main git push -u origin main推完之後回到 Pi Agent 的 Skills 面板,按「Add from URL」(第 15 章教過的欄位),貼上
https://github.com/你的帳號/fridge-check,按裝。Pi Agent 會 clone 進來、掃到SKILL.md、把它列出來。 -
確認 skill 已載入
Skills 面板應該會出現
fridge-check這一列,右邊有開關可以停用/啟用。預設是啟用的。開一個新 session,打開 System prompt 面板往下找<available_skills>區塊,裡面應該會看到fridge-check跟你寫的 description 出現。有出現就代表 pi-web 已經把它塞進 system prompt 給 AI 看了。
/data/pi-agent/skills/ 下」。差別只在於:GitHub 法多了一層版控、可以分享;本地法快,但只有你自己有。開發過程用本地法快速迭代,成熟後推上 GitHub是常見流程。測試 skill 有沒有真的生效
裝好只是第一步——你要確認 AI 真的有依照 SKILL.md 的步驟回應。測試方式:
-
開一個全新的 session
Skill 是在 session 開始時載入 system prompt 的,所以要開新的——舊 session 不會自動吃到新 skill。點右上「New session」或側邊欄的「+」。
-
選一個 reasoning 模型
模型下拉切到 GLM-4.6、Claude Sonnet 4、DeepSeek-R1 這類會思考的模型。非 reasoning 模型(GLM-4-Flash、Claude Haiku)常常會忽略 skill 指示,因為它們沒有「先讀 system prompt 再組織回答」的推理階段。這是很多人寫 skill 沒生效的第一個原因。
-
貼一張冰箱照片+一句話
手機拍一張你家冰箱、傳到電腦、拖進 pi-web 的對話框。旁邊打一句「幫我看看冰箱」按送出。
-
看回應長怎樣
AI 應該會按你
SKILL.md寫的步驟:先描述看到什麼、標出快過期的、推薦晚餐、列明天要用掉的。如果回應格式跟你範例輸出的格式很像,代表 skill 生效了。 -
如果沒生效——三個檢查點
回應完全沒照 skill 走?照下面順序檢查:
- System prompt 面板:打開看
<available_skills>裡有沒有fridge-check。沒有的話——skill 沒被 pi-web 收到,回第 15 章的常見卡關檢查資料夾位置跟 frontmatter 語法。 - description 具體度:AI 判斷「這一輪要不要用這個 skill」靠的就是 description。你寫「幫使用者做家事」太籠統,AI 不會 match 到「幫我看看冰箱」。改成「使用者傳冰箱照片、提到食材、pantry、冰箱、fridge 時觸發」這種具體 trigger,命中率會高很多。
- 模型能力:換 GLM-4.6 或 Claude Sonnet 4 試試。非 reasoning 模型忽略 skill 是通例,不是 bug。
- System prompt 面板:打開看
寫好一個 skill 的三個原則
試錯過幾個 skill 之後你會發現,AI 有沒有乖乖照 skill 走,很大程度取決於你怎麼寫。三個從實戰累積出來的原則:
| 原則 | 錯的寫法 | 對的寫法 |
|---|---|---|
| description 要具體(含 trigger 條件) | description: 幫使用者做家事 |
description: 使用者傳冰箱照片、提到食材/pantry/剩菜/「今天煮什麼」時觸發 |
| 步驟要明確編號(AI 會照順序做) | 「就幫使用者看看冰箱有什麼,然後給點建議」 | 「1. 先描述看到什麼 2. 標出快過期的 3. 推薦晚餐 4. 列明天要用掉的」 |
| 加「不要」(明確禁止的事) | (沒寫任何禁止事項) | 「不要杜撰你看不到的食材」「不要診斷食物中毒」「不要推薦要 30 分鐘以上的異國料理」 |
為什麼「不要」這麼重要?因為 AI 有一種「熱心過頭」的傾向——你沒明講不能做的事,它就會自己延伸。你只想要它盤點冰箱,它可能會順便講「這樣飲食搭配缺乏蛋白質」「小心大腸桿菌」——變成一份營養健康報告,而不是你要的晚餐建議。加一句「不要診斷、不要延伸」就攔下來了。
常見家用 skill 靈感
寫完冰箱盤點之後,同樣的模板可以複製出一整組家用 skill。這裡列七個平常最有價值的方向:
| Skill 名 | 什麼時候觸發 | AI 該做什麼 | 典型附加檔 |
|---|---|---|---|
冰箱盤點fridge-check |
傳冰箱照片、問「今天煮什麼」 | 盤點、標臨期、建議菜色 | (無) |
家事輪值chore-rotation |
問「這禮拜誰倒垃圾」「輪到誰洗碗」 | 依家人名單+週期輪出當班的人 | family.md(家人清單) |
晚餐建議dinner-suggest |
問「今晚吃什麼」「不知道要煮什麼」 | 依偏好、時間預算、剩菜給 3 種方案 | preferences.md(家人不吃的東西) |
買菜清單grocery-list |
提到「要去買菜」「週菜單」時 | 依 dinner-suggest 產生的菜單反推材料 | staples.md(家裡常備品) |
家電手冊 QAappliance-manual |
問家電錯誤碼、操作方式 | 查資料夾內的 PDF 說明書回答 | washer.pdf、ac.pdf、dryer.pdf |
HA 自動化模板ha-automation |
提到「幫我寫一個自動化」 | 依 HA 自動化的觸發/條件/動作三段式產 YAML(不會寫看HA 入住指南第 8 章) | entity_map.md(家裡實體對照) |
影片管線腳本video-script |
提到「幫我寫個影片腳本」「YouTube shorts」 | 產出 30/60 秒腳本+分鏡+字幕 | voice.md(品牌調性) |
看得出來共通模式了嗎:skill = 你想外包的重複勞動+你希望 AI 遵守的規則+你手上可以給它參考的資料。把這三塊寫進 SKILL.md(第三塊放附加檔),你就多一個專屬助理。
分享出去,讓別人也能用
你寫的 skill 如果別人也用得到,push 到自己 GitHub 的 public repo 就可以分享。
-
確認 repo 是 public
到 GitHub 網站 → 你的 repo → Settings → 拉到最底下 Danger Zone → 確認是 Public。Private 的 repo Pi Agent 抓不到(除非設 token)。
-
朋友只需要 owner/repo shorthand
告訴朋友「去 Skills 面板 Add from URL 輸入
你的帳號/fridge-check就行」。這是 第 15 章教過的縮寫——不用貼完整https://github.com/...。 -
寫個 README.md 更好
在 repo 根目錄放一個
README.md說明 skill 幹嘛用的、怎麼用、示範對話截圖。這對朋友篩選有沒有用到很有幫助。SKILL.md是給 AI 讀的、README.md是給人讀的,兩份不衝突。 -
加到公開索引(進階、可選)
目前 Pi Agent 生態沒有官方的 skill 索引站,各家社群零散有自己的 awesome-list 型清單。想曝光的話發到 HA 中文社群、Reddit r/homeassistant、或推特/BlueSky 掛
#pi-agent、#homeassistanttag 通常比較有效。沒有指定的中央索引可以送 PR,別在網路上聽人講「送到 skills.sh」就照做——那並不是 Pi Agent 官方頻道。
常見卡關
-
AI 完全沒理 skill、回應跟沒裝一樣
兩個檢查點:(1)description 太抽象——改成具體 trigger(「使用者傳冰箱照片時觸發」而不是「幫使用者做家事」);(2)模型太輕——非 reasoning 模型(GLM-4-Flash、GPT-4o-mini、Haiku)常常會忽略 system prompt 裡的 skill 描述,換成 GLM-4.6、Claude Sonnet 4、DeepSeek-R1 這類 reasoning 模型會明顯改善。這在第 12 章講過原理。
-
Skill 不出現在 System prompt 面板
代表 pi-web 根本沒把
SKILL.md讀進來。九成問題出在 frontmatter:(1) 上下兩排---是不是各三個減號、獨佔一行、前後沒空白行;(2)name:跟description:有沒有正確拼寫(冒號後面要有空格);(3) 檔名是不是嚴格SKILL.md(全大寫 SKILL、小寫 .md)。用文字編輯器(VS Code、Notepad++)打開SKILL.md,右下角看編碼是不是 UTF-8 without BOM。 -
Skill 讓 AI 的回答變得很怪、很硬
本文寫得太命令句(「必須做這個」「絕對不能做那個」)會讓 AI 回應變得像機器人念稿。把「必須」改成「建議」、「絕對不能」改成「盡量避免」、「一定要」改成「通常」——留一點彈性讓 AI 用自己的判斷。但關鍵禁令(例如「不要杜撰」「不要給醫療建議」)還是要硬。
-
我不會 git push,怎麼把 skill 傳到 HA host
兩條路避開 git:(1)本地路徑法——用 FileZilla 這種 GUI SFTP 客戶端拖進
/data/pi-agent/skills/,完全不用 git;(2)叫 Pi Agent 幫你 push——貼你的SKILL.md到對話裡,跟 AI 說「幫我把這個 skill push 到 GitHub 的 fridge-check repo」,AI 會用bash工具跑 git 指令。放心你會看到第 9 章講過的工具卡片,push 之前可以確認。 -
Skill 有時候作用、有時候不作用
這通常代表 description 的 trigger 條件不夠廣。例如你只寫「使用者傳冰箱照片時觸發」,那使用者只講「今天煮什麼」(沒傳照片)時就不會 match。把幾種可能的觸發語句都列進 description:
description: 使用者傳冰箱照片、問「今天煮什麼」「冰箱還有什麼」「幫我看看冰箱」,或提到食材、fridge、pantry、剩菜時觸發。列越全越穩。 -
改了 SKILL.md 之後 AI 好像還是照舊版走
Skills 是在 session 開始時載入的。要開一個新 session才會吃到新版的
SKILL.md。舊 session 裡的 system prompt 已經定型不會更新。改完 skill 記得開新 session 測。
常見問題
Skill 一定要用英文寫嗎?
name 欄位跟資料夾名(避免路徑編碼問題);(2)如果 description 想同時對中英使用者觸發,可以中英混寫(「使用者傳冰箱照片、fridge photo、pantry 時觸發」)。除此之外全中文寫作沒問題。YAML 是什麼?我看不懂
alias: 日落開燈、trigger: sun 這種,就是同一個東西。SKILL.md 用到的部分超級簡單,就是 name: 和 description: 這兩行冒號分隔的鍵值對,冒號後要有空格。不用學進階語法。Skill 可以呼叫工具嗎?例如叫 AI 讀 HA 的資料
SKILL.md 裡指示「請用 read_file 讀 /config/automations.yaml」「請呼叫 bash 跑這條指令」,AI 就會叫那個工具(前提是那個工具本來就有裝在 pi-web,例如 bash、read_file、write_file 這些檔案/指令類工具通常是內建)。工具呼叫的細節在第 9 章的「工具卡片」段講過。要操作 HA 實體則要另外設定 MCP server(例如接 ha-mcp 之類的 MCP server 提供 ha_get_state、ha_call_service)——這是 pi-web 外部設定,不是 skill 本身能自帶的東西。Skill 寫錯會不會弄壞 Pi Agent?
SKILL.md(例如 frontmatter 壞了)會跳過它、繼續載入別的 skill,主程式不會 crash、別的 skill 也不受影響。所以你可以放心亂寫、亂測試——寫壞了頂多 Skills 面板少了一列,重寫再試就好。這也是為什麼建議先本地測試玩到穩、再 push GitHub。Skill 的內容會被 AI 記住嗎?換 session 還在嗎?
SKILL.md;一次性的例外就直接對話講。一個 skill 可以做很多件事嗎?還是每件事一個?
Skill 會不會偷偷讀我電腦上的檔案?
SKILL.md 有沒有可疑的「讀 /home 底下所有檔」這種指示,通常就夠安全。可以把 skill 版本化嗎?改壞了想 rollback
SKILL.md 都 commit,想回退用 git log 找舊 commit、git checkout 回去、重新推。本地路徑法沒版控,改壞就得從記憶重寫,所以值得的 skill 值得放 git。另外做 HA snapshot 時(第 20 章),/data/pi-agent/skills/ 整個資料夾會被備份,這也算另一層保險。