iT邦幫忙

2026 iThome 鐵人賽

DAY 13
0
Claude AI

把 Claude 練成專家:30 天打造可驗證的 Agent Skills系列 第 15 篇

Day 16|讓 Skill 漸進式揭露:SKILL.md 保持短,把細節放到 references 與 scripts

  • 分享至 

  • xImage
  •  

昨日回顧

Day 15 把 Skill 的觸發範圍寫進 description,並用 positive、negative、near miss 案例檢查 Claude 何時會載入它。今天往裡面走一步:Skill 已經被載入後,是否需要一口氣把所有規則、範例與程式碼都塞進同一份 SKILL.md?

漸進式揭露不是把內容藏起來

Skill 有兩次讀取決策。第一次是 description 決定要不要載入;第二次是載入後,依任務需要讀哪些細節。若 SKILL.md 長到像整本手冊,模型會在每次觸發時都背上不相關的內容。若只留下「詳見其他檔案」,又會找不到入口。

目標是讓入口完整、細節按需展開:核心決策留在 SKILL.md;具體規格放 references/;可重複執行的確定性步驟放 scripts/。安全邊界與失敗政策不能因拆檔而失蹤。

先替內容分類

以 ticket-source-guard 為例,畫一張分工表:

SKILL.md
- 使用時機、輸入與輸出
- 核心流程、停止條件、失敗政策
- 哪個情境讀哪一份 reference
- 哪些判斷必須交給 script

references/source-registry.md
- 來源證據格式、欄位、freshness 規則
- revoked 與 stale 的語義

references/eval-cases.md
- 案例設計、邊界案例、驗收門檻

scripts/normalize_host.py
- host 正規化,不讓模型猜字串規則

scripts/classify_source.py
- 使用 registry 與執行日期回傳固定狀態

這不是依檔案長度隨機切割。每個檔案要有單一用途,SKILL.md 的指針要說清楚何時讀取。把常用但短的硬規則留在入口,把長表格、例子、API 欄位或語言特定細節移出去。

SKILL.md 必須能獨立指揮

入口檔不需要複製每個欄位,但至少要交代下一步和失敗時怎麼做:

# Ticket Source Guard

Use only for verifying a ticketing or resale source before login,
sharing personal information, or payment.

1. Require a concrete URL or host. If absent, return INSUFFICIENT_INPUT.
2. Run `python scripts/normalize_host.py <url>`; do not infer the host.
3. Read `references/source-registry.md` for evidence and freshness rules.
4. Run `python scripts/classify_source.py ...` with the registry and an
   explicit evaluation date. Do not fetch live pages in the classifier.
5. Return status, evidence URL, verified_at, review_after, and next_step.
   Stale or conflicting evidence cannot be reported as OFFICIAL.

For schema changes, read `references/source-registry.md` before editing.
For eval changes, read `references/eval-cases.md` before editing.

這段不依賴模型記得 Day 8 到 Day 15 的文章。它知道該停在哪裡、該跑哪個檔案、什麼時候需要另一份文件。

reference 指針要有條件

不好的指針是「請讀取 references/ 以了解更多」:它沒有告訴模型讀哪份、何時讀、為什麼讀。較好的寫法是:「修改 registry schema 前讀 source-registry.md;新增觸發案例前讀 eval-cases.md。」

同一條規則不要在四個檔案各寫一份。多份副本遲早會互相矛盾。SKILL.md 保留不變的決策界線;reference 保留規格細節;script 實作可測的機械步驟。若 reference 改了,入口的指針與測試也要一起檢查。

script 不是神諭

把 host 正規化、日期比較、schema 驗證寫成 script,可以減少模型每次重新發明規則;但 script 仍需有明確輸入、輸出和錯誤碼。不要讓它偷偷連網、改 registry,或自行延長 review_after。

input: url, registry_path, evaluation_date
output: JSON {status, normalized_host, evidence_url,
              verified_at, review_after, next_step}
errors: INVALID_URL, INVALID_REGISTRY, MISSING_DATE
side effects: none

這個介面也讓測試可以不依賴 Claude 的措辭,直接比較輸出。若 script 不存在或執行失敗,回傳 CONFIGURATION_ERROR,而不是假裝已完成來源驗證。

用 CI 檢查連結沒有斷

拆檔後最常見的退化是搬了檔案卻忘了改指針。先做一個輕量檢查:

from pathlib import Path
import re

root = Path(__file__).resolve().parents[1]
skill = (root / "SKILL.md").read_text(encoding="utf-8")
refs = set(re.findall(r"(?:references|scripts)/[A-Za-z0-9_./-]+", skill))

for rel in refs:
    target = (root / rel).resolve()
    if root not in target.parents or not target.is_file():
        raise SystemExit(f"broken pointer: {rel}")

for folder in ("references", "scripts"):
    for path in (root / folder).glob("*"):
        if path.is_file() and str(path.relative_to(root)) not in refs:
            print(f"review unlinked file: {path.relative_to(root)}")

這是示意檢查,不代表每個輔助檔都必須直接從入口連結。若 reference 彼此引用,CI 也要掃描那層關係,並明確列出允許不連結的測試資料。重點是把孤兒檔案變成可見的維護訊號。

再做一組讀取路徑測試

檔案存在不等於模型會在對的時候讀它。準備三種任務:驗證單一網址、修改 registry 欄位、增加觸發 eval。記錄每種任務讀到哪些檔案:

網址驗證:SKILL.md + source-registry.md + classifier script
schema 修改:SKILL.md + source-registry.md + schema tests
觸發 eval:SKILL.md + eval-cases.md + trigger tests

如果簡單驗證也每次讀完整份 eval 案例,拆檔沒有帶來按需載入;如果 schema 修改沒讀規格,指針又太弱。測試要看行為,不只看檔名是否存在。

今天完成的驗收標準

[ ] SKILL.md 含核心流程、停止條件、失敗政策
[ ] references/ 各檔用途清楚,指針寫出讀取時機
[ ] scripts/ 有可測的輸入、輸出、錯誤與副作用界線
[ ] CI 檢查入口指針存在且不越出專案根目錄
[ ] 孤兒檔案列入維護報告
[ ] 任務型測試確認細節只在需要時載入
[ ] stale、conflict、script failure 不會被包裝成 OFFICIAL

上一篇
Day 14|讓 evidence 會過期:設計來源重驗與 freshness 維護流程
系列文
把 Claude 練成專家:30 天打造可驗證的 Agent Skills 共 15 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言