iT邦幫忙

2026 iThome 鐵人賽

DAY 7
0
Claude AI

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

Day 07|官方來源不是域名清單:設計可維護的 sources.md

  • 分享至 

  • xImage
  •  

昨日回顧

Day 6 建立了 ticket-guard 的目錄與第一版 SKILL.md。流程已經知道要呼叫 scripts/check_domain.py,但分類品質取決於另一個核心:references/sources.md。今天把「官方來源」從模型印象改成有證據、日期與範圍的資料。

為什麼只有域名不夠

最簡單的清單可能長這樣:

tickets.example.com
official-ticket.example

它能比對,卻回答不了四個重要問題:

  • 誰說這是官方來源?
  • 證據在哪裡?
  • 哪一天驗證的?
  • 整個根域名都有效,還是只有特定 host?

沒有這些欄位,清單一過期就無法維護,也無法在結果中說明依據。

一筆來源紀錄的最小 schema

- id: example-tickets-primary
  host: tickets.example.com
  match: exact
  organization: Example Tickets
  evidence_url: https://www.example.org/tickets
  evidence_type: first_party_link
  verified_at: 2026-09-17
  review_after: 2026-12-17
  scope: Primary ticket-sales host linked from the organizer site
  status: active

欄位各有責任:

  • id:穩定識別,讓測試與輸出引用同一筆紀錄
  • host:正規化後要比對的 host
  • match:精確或允許子網域,不能含糊
  • organization:對應的主辦方或售票服務
  • evidence_url:證明關係的第一方頁面
  • evidence_type:證據類型
  • verified_at:最後人工驗證日期
  • review_after:超過哪一天必須重查
  • scope:這筆證據實際涵蓋什麼
  • status:active、stale 或 revoked

證據等級

不是所有連結都能證明官方關係。我會把證據分成三層:

  1. first_party_link:主辦方、場館或藝人官方網站直接連到售票 host。最強。
  2. official_announcement:第一方公告明確命名售票服務與入口。可接受。
  3. ticket_service_claim:售票服務自己聲稱承辦,但沒有第一方交叉證明。只能當線索,不能單獨升級為官方。

搜尋結果、廣告、社群轉貼與頁面設計不進證據欄。它們可以幫忙找到來源,不能成為最終依據。

精確比對優先

host: tickets.example.com
match: exact

代表只允許 tickets.example.com,不能自動放行:

  • login.tickets.example.com
  • tickets.example.com.attacker.net
  • example.com

如果服務真的控制並使用所有子網域,才能明確寫:

host: tickets.example.com
match: include_subdomains
scope: All subdomains documented by the ticket service

include_subdomains 是高風險例外,不是方便的預設。它必須有證據支持。

同一品牌可以有多筆紀錄

售票系統常有地區或活動專用 host。不要把它們硬塞進一條萬用規則:

- id: example-tickets-tw
  host: tw.tickets.example
  match: exact
  organization: Example Tickets Taiwan
  evidence_url: https://organizer.example/tw-event
  verified_at: 2026-09-17
  review_after: 2026-12-17
  scope: Taiwan event sales only
  status: active

- id: example-tickets-jp
  host: jp.tickets.example
  match: exact
  organization: Example Tickets Japan
  evidence_url: https://organizer.example/jp-event
  verified_at: 2026-09-17
  review_after: 2026-12-17
  scope: Japan event sales only
  status: active

拆開後,每筆紀錄能獨立過期、撤銷與測試。

過期不是自動刪除

到達 review_after 時,把紀錄視為 stale,不要靜默刪除,也不要繼續回報 OFFICIAL

建議流程:

  1. 腳本命中 stale 紀錄。
  2. 結果降為 UNCONFIRMED
  3. evidence 說明「曾驗證,但已超過複查日期」。
  4. next_step 指向第一方入口重新確認。
  5. 維護者重查後更新日期,或把狀態改成 revoked。

這樣能避免舊關係在無人注意時繼續被當成現在事實。

撤銷要保留歷史

若官方停止合作,不要直接刪掉紀錄:

status: revoked
revoked_at: 2026-10-02
revocation_evidence_url: https://organizer.example/notice

保留撤銷紀錄有兩個好處:舊連結出現時能解釋「以前有效,現在不是」,測試也能防止它被重新誤判。

文件與機器資料分開

references/sources.md 適合給人看說明,但腳本最好讀結構化區塊。第一版可以在同一檔案使用 fenced YAML:

# Official sources

Only records with `status: active` and a future `review_after` may return OFFICIAL.

```yaml
sources:
  - id: example-tickets-primary
    host: tickets.example.com
    match: exact
    organization: Example Tickets
    evidence_url: https://www.example.org/tickets
    evidence_type: first_party_link
    verified_at: 2026-09-17
    review_after: 2026-12-17
    scope: Primary ticket-sales host
    status: active
```

規模變大後,再把機器資料移到 sources.yaml,讓 sources.md 專注解釋維護規則。現在先保持最少檔案。

新增來源的檢查表

每次新增紀錄前,確認:

  • host 已用 URL parser 正規化
  • 第一方證據頁真的連到或命名該 host
  • scope 沒有超過證據能支持的範圍
  • match 預設 exact
  • verified_at 是實際檢查日期
  • review_after 已設定
  • 沒有 active 紀錄與 revoked 紀錄衝突
  • 新紀錄有正向與反向測試案例

一筆資料沒有通過這張表,就只能進候選區,不能進 active 清單。

明天預告

Day 8 實作 check_domain.py:正規化 URL、精確比對來源、處理 stale/revoked 狀態,輸出固定 JSON,讓「官方」第一次由程式而不是印象決定。


上一篇
Day 06|動手建立 skill:目錄骨架與第一版 SKILL.md
下一篇
Day 08|實作 check_domain.py:讓「官方」由程式決定
系列文
把 Claude 練成專家:30 天打造可驗證的 Agent Skills10
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言