iT邦幫忙

0

Claude Code 的 Skills 不是咒語:做完 27 個台灣資料技能,我學會讓 AI 說「不知道」

  • 分享至 

  • xImage
  •  

先講結論:想讓 Claude Code 穩定完成一件事,別只告訴它「怎麼做」,還要寫清楚「什麼時候不准說做完了」。

一份能用的 Skill,不是更長的 prompt。它是一張驗收單。

這是我做 baodao-skill 之後最想留下的結論。這個專案把台灣日常查詢整理成 AI 代理能讀的技能:發票對獎、YouBike、垃圾車、停車位,也有郵資、所得稅與勞健保的本地計算。現在有 27 個技能,開發過程寫成了 30 篇鐵人賽施工日記。

不是 27 支政府 API。有些來源是公開網頁或檔案,有些技能完全不連網;也不是「全部免金鑰」,目前三個技能需要免費申請的政府資料金鑰。把這些差別講清楚,本身就是技能的一部分。

如果你搜尋 Claude Code Skills,是想知道怎麼把 AI 從「會寫程式」變成「能放心交一件事」,這篇不用從第一天開始追。我們直接看最重要的差別。

會做,不等於知道何時做錯

Claude Code 官方文件的基本單位很簡單:一個目錄,一份 SKILL.md。前面的 YAML 描述用途,後面的 Markdown 寫流程,也可以附腳本與參考資料。

檔案很容易寫。難的是裡面的判斷。

例如「查附近診所」:取得官方 JSON,篩地址,印名字。看起來三步就結束。

但健保署的資料 API,limit=40000 不會真的回四萬筆。2026-09-20 實測,它只回 1,000 筆;當時總數是 37,133,要分 38 頁才拿齊。

若只看「有回 JSON、裡面有診所」,你就會把第一頁當成全台灣。查不到某家診所,不是它不存在,是你的世界只有第一頁。

程式可以正常結束,答案卻不能交出去。

我現在把這個差別濃縮成四格:

能做:從哪裡拿資料,怎麼處理?
算對:拿什麼證據驗收,不只看程式沒報錯?
不做:哪些請求超出能力,不能裝作答得出來?
怎麼說:答案帶哪些時間、來源與限制?

這四格是本文的整理方法,不是 Claude Code 的設定欄位,也不是官方規格。

下面用真實修正記錄填它。

第一格:能做,先找對路,不急著寫 parser

做技能很容易有一種衝動:先寫個漂亮的解析器。

但 Day 6 的日記就是反例:處理完行事曆 xlsx,才發現官方結構化 CSV 已經在那裡。這時最有價值的改動不是把 parser 寫得更厲害,而是少做一個 parser。

給 Claude Code 的工作也一樣。我會先把任務改寫成:

先列官方來源與資料格式,找出能直接使用的結構化資料,再決定需不需要解析網頁。找不到可驗證來源,就先報告,不要補一個猜的網址。

這是工作提示,不是一次實測的對話紀錄。

你可以把 AI 當成手很快的同事。但手快之前,要先確認拿的是正確那份檔案。否則效率只是把錯路走得更遠。

第二格:算對,測試要抓得到「看起來也合理」的錯

我遇過一個比語法錯誤麻煩得多的 bug:台股「漲幅前十名」,原本按 Change 排序。

Change 是漲了幾元,不是漲了幾%。高價股漲十元,不一定比低價股漲一元厲害。

目前文件的算法是:

昨收 = 收盤價 - 價差
漲幅 = 價差 / 昨收
空字串或昨收為 0:略過,不硬算

這個修正記在 2026-10-02 的 CHANGELOG。程式能跑、結果有十支股票、數字也像真的,都不足以抓出它。

所以驗收案例要故意讓「錯算法」和「對算法」分出不同答案。

統編檢核也踩過同一種坑。原本拿 97176270 當第七碼為 7 的特例測試,後來發現它走一般規則就會通過,根本測不到特例有沒有實作。0.8.3 改用合成向量 10000073:不處理特例就不合法,處理特例才合法。

這不是多加一個 assert 的問題。是先問:

如果程式少寫了我要驗的那條規則,這個測試會不會仍然通過?

會的話,那個綠燈沒有替你證明那條規則。

同理,現在的回歸測試會抽出 SKILL.md 裡的程式執行,而不是另外抄一份差不多的算法。文件錯、測試副本對,照樣能得到一個很漂亮、很沒用的綠燈。

第三格:不做,讓 AI 有地方停下來

「不做」不是推卸,是畫清能力的邊界。

taiwan-stock 是收盤資料,不是盤中報價。taiwan-hospital 是院所名錄,不知道現在排隊多久,也不能幫你掛號。taiwan-id-check 能驗檢查碼,不代表這個身分證字號屬於真人,更不代表查到了誰。

若技能只列功能、不列禁區,使用者一句「那順便幫我……」,任務就可能從查資料滑到你根本沒有的能力。

baodao-skill 的範圍刻意停在查詢與計算:不預約、不購買、不發文。README 也列了評估後沒納入的路線。

有一條線更重要:抓不到資料,不准用猜的資料把流程補完。

發票 parser 曾把頁首、頁尾清冊連結裡的獎項字樣讀進去,結果特獎配到了錯的號碼。0.8.2 的修正是從期別後第一個「獎別」表格開始解析,並加上回歸與煙霧測試。

這時真正值得保存的不是「下次小心」,而是把錯誤的入口封住。資料結構不符合預期,就停;沒有驗證過的號碼,就不報。

我另外寫了一篇 HTTP 200 不等於成功,專門整理資料抓取的假成功。這篇更想補上後半句:AI 說「完成」,也不等於驗收通過。

第四格:怎麼說,答案本身要帶著邊界

假設技能真的拿到 YouBike 車數。只回答「還有三台」,資訊仍然少一半。

哪個站?資料幾點更新?是一般車還是電輔車?空欄位是零,還是沒有資料?

所以專案另外整理了共通的回應規則:

  • 即時資料附資料本身的更新時間,不能只寫「目前」。
  • 停車資料的 -9 等缺值如實說「無資料」,不能換成零。
  • 警報先檢查有效期限,不能把過期警報當現況。
  • 推算的期限要標明推算,重要判斷回到官方來源確認。

這些規則不會讓回答更炫。它們只是讓讀者知道能信到哪裡。

我喜歡把它想成食品標示:菜可以很好吃,但包裝上還是要寫保存期限。你不能用廚藝取代保存期限。

把四格寫進一份真的能改的 Skill

不需要一開始就做 27 個。選一件你常問、資料來源清楚、結果可驗證的小事,先做一個。

下面是作者用的骨架,不是可直接查詢的成品;把來源、欄位與案例補齊,再讓代理使用:

---
name: my-data-lookup
description: 查詢某項公開資料;使用者問相關資料時使用。
---

## 能做
- 使用已驗證的官方來源。
- 寫明必要參數、分頁方式與資料更新頻率。

## 算對
- 回應不是錯誤頁,必要欄位齊全。
- 資料日期符合請求;需要全量時驗證分頁完整性。
- 至少一個會讓錯算法失敗的驗收案例。

## 不做
- 不猜缺值,不把歷史資料說成即時資料。
- 超出查詢範圍或來源無法驗證時,停下來說明。

## 怎麼說
- 回答附來源、資料時間與限制。
- 將已知值、推算值、無法確認的部分分開。

在 Claude Code,專案技能可放 .claude/skills/my-data-lookup/SKILL.md;個人技能可放 ~/.claude/skills/my-data-lookup/SKILL.md。用途描述幫它判斷何時載入,也可以直接用 /my-data-lookup 呼叫。以 官方 Skills 文件 為準。

若想看現成案例,baodao-skill README 提供的單技能安裝方式是:

# 需要 Node.js 18+ 與 npx;安裝前先讀公開倉庫內容
npx --yes skills add tahodev/baodao-skill --skill invoice-winning-numbers -g

安裝不是驗收。裝好之後,拿一個你已知道答案的案例、一個邊界案例、一個應該拒答的請求試它。尤其發票與期限這類重要資訊,仍要對照官方公告。

27 個技能不是結論,知道哪裡沒證明才是

30 天的收尾文章沒有寫「完美完成」。它記下當時的數字:2026-10-07 的統計有 28 次排程 run,13 綠、15 紅。

紅燈也不是 15 次 API 壞掉。Day 29 拆開後,10 次在 counts 步驟,5 次在 URL 檢查。部分問題是把會變動的院所、停車場數量寫死,檢查本身在誤報。

後來改成漂移警告、完整性檢查,還得處理兩次請求之間 total 改變的情況。綠燈若包含網路限制的 WARN 或略過,也不能說那個來源已經驗證成功。

這些是當時的紀錄,不是今天的 CI 狀態。

它們教我的不是「測試越多越好」,而是:每盞燈到底證明了什麼,要說得出來。

Claude Code 能幫你把流程做快。Skills 能把可重複的做法留住。但「答案可以交給人使用」這件事,還需要驗收、拒答與回報方式。

你下次寫 Skill,可以先不加更多步驟。先加一句:

遇到什麼情況,我寧可回答不知道,也不交出一個看起來成功的答案?

那句話,常常比下一百行程式更有用。


原始材料與延伸閱讀:


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言