跳到主要內容

【2026 最新】Skill Router 是什麼?Agent Skills 太多,怎麼只載入對的一個

最後更新: ·
Skill Router 教學首圖:多個 Agent Skills 經過 Router 後只載入正確的一個

Skill Router 正在從「可有可無」變成 Agent 架構裡的交通警察。截至 2026 年 8 月 8 日,資安垂直套件 reverse-skillGitHub Trending 顯示「本週 10,400 stars」;2026 年 8 月 6 日提交的預印本,又把一個持續成長、建圖時有 690 個 Skill 節點的資料庫拿來測試檢索。這是很強的興趣訊號,但不是「每個 Agent 都需要同一套 Router」的證明。

真正的問題很直白:Skill 裝得愈多,目錄愈長;全部載入很貴,只看關鍵字又容易選錯。這篇專為第一次做 Agent 系統的讀者寫,不假設你會資訊檢索。我會先拆清楚 discovery、routing、loading、sequencing,再帶你做一個 BM25+embedding 的 top-k Router,加上低信心澄清、NO_SKILL fallback 與可重跑的評測。

先說結論:Skill Router 的一句話公式

本篇要做的最小可用版本:Skill Router = BM25(抓字面)+ Embedding(抓意思)+ Abstain(不確定就不選)

  • 啟動時只向模型揭露輕量目錄,不把每份 SKILL.md 正文都放進 context;宿主仍可預先解析或快取檔案。
  • 每次任務先取 top-k 候選,再用信心閘門決定「啟用、澄清、或不選」。
  • 選中一個或多個任務 Skills 後,才展開明確 prerequisites,決定執行順序。
  • 成敗看 held-out 任務,不看你自己照著 Skill 描述改寫的漂亮測試題。

Skill Router 是什麼?先把四個動作分開

把 Agent 想成剛進大型五金行的新員工。它不需要先背完每把工具的說明書;它需要先看目錄、找到候選、拿出正確工具,若工作要兩把工具,再決定先後。這四步分別是:

  1. Discovery「盤點目錄」:掃描允許的 Skill 位置,讀取名稱、描述、路徑與相容條件。
  2. Routing「找候選」:拿目前任務去搜尋目錄,排出最相關的 top-k。
  3. Loading/Activation「拿說明書」:通過閘門後才把完整 SKILL.md 放進模型 context。
  4. Sequencing「排施工順序」:若任務需要多個 Skills,再依 prerequisites、輸入輸出與先後關係排序。

Agent Skills 官方 client guide 把 progressive disclosure 分成三層:啟動時只向模型揭露名稱與描述,啟用時讀完整指令;指令需要時,才讀 references/assets 或執行 scripts。官方粗估每個目錄項約 50–100 tokens。換句話說,Skill Router 管的是「先找誰」;Loader 管的是「何時把正文拿進來」

Agent Skills 規格沒有規定 BM25、embedding、top-k、信心門檻或多 Skill dependency graph;本文都是 Router 控制層的自訂實作。

Skill Router 從 discovery、hybrid routing、低信心閘門、loading 到 sequencing 的五步流程
Skill Router 的完整責任邊界:搜尋候選不等於載入正文,相關性排名也不等於執行順序。

為什麼 Skills 愈多,不一定愈強?

第一個成本是 context。按照官方每個目錄項約 50–100 tokens 的估算,100 個 Skills 的輕量目錄就可能佔 5,000–10,000 tokens;這還不是正文。第二個成本是混淆:pdf-ocrpdf-redactorpdf-form-fill 都有 PDF,字面很像,真正意圖卻不同。第三個成本是錯誤流程:選到「把畫面模糊」的 Skill,不等於真正移除 PDF 文字層裡的個資。

2026 年 8 月 6 日提交的 《Comparative Approaches to Agent Retrieval over Large Skill Libraries》v1 預印本,把這個痛點量化了。在這一份單一組織、117-query 的評測裡,BM25 hit@5 是 50.4%,hybrid 是 73.5%(95% half-width ±8.0 個百分點),相差 23.1 個百分點;但 hybrid 仍有 26.5% 沒把正確 Skill 放進前五。這支持在該目錄測 hybrid,不證明它在每個 corpus、語言或 embedding 都會勝出。

這裡要讀準數字:690 是建圖當下的 Skill 節點數;主要 retrieval 表格使用 117 題與 875 筆 catalogue entries,論文也註明部分較早測量發生在 639-Skill 快照。研究索引的是名稱與一行描述,不是把 690 份完整正文都拿來搜尋。

先把 Skill metadata 寫成「可檢索的名片」

Agent Skills 規格只要求 namedescriptioncompatibilitymetadata 是選填,而且自訂 metadata 是 string-to-string map。以下 alphalab/* 欄位是 Router 的延伸約定,不是所有宿主都會自動理解:

---
name: pdf-redactor
description: Remove sensitive text from PDFs before sharing. Use for PDF redaction, PII masking, or sanitizing scanned documents.
compatibility: Requires Python, a readable PDF, and permission to write a new file.
metadata:
  alphalab/router-version: "1"
  alphalab/aliases: "pdf-redact,pdf-sanitize"
  alphalab/intents: "redact PDF,remove PII,sanitize scanned document"
  alphalab/input-kinds: "pdf,image,redaction-rules"
  alphalab/output-kinds: "redacted-pdf,audit-log"
  alphalab/requires: "pdf-ocr when input is scanned"
  alphalab/not-for: "ordinary image blur,PDF form filling"
---
  1. Name 與 aliases 解決精確名稱、縮寫、產品名。
  2. Intent 與 not-for 說清楚要完成什麼,以及相鄰 Skill 的邊界。
  3. Inputs 只在 runtime 已有可信結構化事實時做 hard filter;格式或必要輸入未知時先澄清,不能靠含糊 query 猜測。
  4. Outputs 讓多 Skill 流程知道上一站會交出什麼。
  5. Prerequisites 與 compatibility 管權限、環境與先後,不要混成搜尋關鍵字。

欄位變多不代表命中率會自動上升;它先讓限制變得可檢查。上面的 alphalab/requires 也只是人類可讀摘要,不能直接排程。Indexer 應把它編譯並驗證成結構化記錄,例如 {"prerequisites":[{"skill_id":"pdf-ocr","when":{"input_kind":"scanned-pdf"}}]};只有 allowlist 內、條件可判定且通過 cycle check 的 ID 才能進 dependency graph。若輸入是否為掃描檔仍不明,先澄清,不要猜。需要陣列、正負例與依賴圖時,可保留標準 SKILL.md,再產生 router-index.jsonl

實作 Skill Router:BM25+Embedding+RRF

第 1 層:BM25 抓「字面很像」

BM25 像圖書館的精準索引,擅長 .pdfPostgreSQL、產品名與罕見錯誤碼。原型可用 rank_bm25;它要求已斷詞的 token lists,或由你提供 tokenizer,沒有內建 CJK 前處理。繁中/英文混合資料通常不宜只靠 text.split(),而且 corpus 與 query 必須用同一套斷詞。

第 2 層:Embedding 抓「意思很像」

使用者說「把個資遮掉」,Skill 可能寫的是 redaction,字面沒有重疊。Embedding 會把 query 與 routing card 轉成向量,再用相似度找近鄰。Sentence Transformers 文件對非對稱搜尋建議分別使用 v5+ 的 encode_queryencode_document;若模型沒有 query/document prompts 或 route,兩者可能和一般 encode() 產生相同結果。

第 3 層:RRF 合併兩份排名

BM25 分數與 cosine similarity 不在同一把尺上,直接相加很危險。入門版可用 Reciprocal Rank Fusion:只看每個候選在兩份清單的名次,計算 1 / (60 + rank) 後相加。60 是常見起點,不是通用最佳值;depth、top-k 與融合方式都要在開發集調整。

先安裝 v5 系列 API。以下是刻意不可直接部署的 Python-like pseudocode;它會保留 ranking evidence,供下一節的 Gate 使用:

python -m pip install "sentence-transformers>=5,<6" rank-bm25 pyyaml
# Python-like pseudocode;tokenizer、model 初始化與 imports 省略
# 所有門檻只能由 dev set 取得,不能照抄範例數字
# offline:每個 Skill 只建立一張短 routing card
cards = [routing_card(skill) for skill in skills]
bm25 = BM25Okapi([tokenize(card) for card in cards])
doc_vecs = encoder.encode_document(cards, normalize_embeddings=True)

# online:兩路各取 20,再用排名融合
def retrieve(query, top_k=5, depth=20):
    bm25_scores = bm25.get_scores(tokenize(query))
    lexical = [
        i for i in top_indices(bm25_scores, depth)
        if isfinite(bm25_scores[i]) and bm25_scores[i] > 0
    ]  # BM25 全為 0 時,這一路不投票

    q = encoder.encode_query(query, normalize_embeddings=True)
    cosine_scores = doc_vecs @ q
    semantic = top_indices(cosine_scores, depth)

    fused = defaultdict(float)
    for result in (lexical, semantic):
        for rank, idx in enumerate(result, start=1):
            fused[idx] += 1 / (60 + rank)

    ranked = sorted(fused, key=lambda i: (-fused[i], skills[i].id))
    evidence = {
        "bm25_scores": bm25_scores,
        "cosine_scores": cosine_scores,
        "lexical_ranked": lexical,
        "semantic_ranked": semantic,
        "rrf_scores": fused,
    }
    return [skills[i].id for i in ranked[:top_k]], evidence

candidates, evidence = retrieve(query)
decision = gate(candidates, evidence, DEV_CALIBRATED_THRESHOLDS)

Dense retrieval 即使完全不相關也一定排得出前 20 名,所以 top-k 本身不是「有合適 Skill」的證明;Gate 必須看 dev set 校準過的 evidence。正式環境還要補 CJK tokenizer、權限/相容性 hard filter、向量快取與 digest 失效、錯誤處理,Loader 也要再檢查一次授權與相容性。

近似 Skill 很多、短 metadata 不夠辨識時,再分別測 body-aware first-stage retrieval 與 reranker。約 80K-Skill 的 SkillRouter v5在自己的 benchmark 發現 all-field routing 優於只看 name+description;相對地,690-node v1 只轉述 sibling effort 在 256-word-piece short-context encoder 下加入正文變差,並把方向列為 open question。兩者 corpus、encoder、評測不同,不能直接互比;請在同一份 held-out tasks 上做 metadata-only、field-aware 與 body-aware ablation(一次只改一個設計)。

完整走一次:掃描 PDF 個資該載入哪個 Skill?

以下是機制示意,不是實測 benchmark;假設任務是:「我要把一份掃描 PDF個資遮掉,再交給客戶。」目錄裡有 pdf-redactorpdf-ocrpdf-form-fillimage-blur

  1. Discovery 只把四張 routing cards 揭露給模型,不把四份正文放進 context。
  2. BM25 抓到 PDF;embedding 把「個資遮掉」連到 redaction。
  3. RRFpdf-redactor 排第一、pdf-ocr 排第二。
  4. Gate 接受 pdf-redactor 作為任務 Skill;若前兩名其實是 redactor 與 image-blur 且很接近,就問:「要不可逆移除文字,還是只做視覺模糊?」
  5. Sequencer 看到 scanned input 與明確 prerequisite,排成 pdf-ocr → pdf-redactor,最後才載入這兩份正文。

這個例子也回答一個常見誤會:retrieval rank 代表「和 query 多相關」,不代表「先執行誰」。先選中一個或多個任務 Skills,再展開已驗證的 prerequisite,兩個問題才不會混在一起。

低信心時怎麼辦?不要把 RRF 分數叫做機率

RRF 的 0.031、cosine 的 0.82 都不是「82% 會選對」。正確做法是拿標註過的開發集,記錄 top-1 分數、top-1/top-2 差距、兩個通道是否都把同一 Skill 排進前幾名,再調三段決策:

  • AUTO:證據高、差距夠大,啟用第一名。
  • CLARIFY:兩個候選都合理,先問一個最能區分 intent、input 或 output 的問題,再重新 routing;仍不清楚就繼續澄清或回 NO_SKILL
  • NO_SKILL:現有 evidence 不足,或目錄確實沒有對應能力;不載入任何 Skill。只有基礎 Agent 在既有權限與政策下原本就獲准處理時才可繼續,否則澄清或回報「目前沒有受支援流程」。這不是繞過安全檢查的許可。

門檻不能從別人的 cosine 數字抄過來。Embedding 模型、目錄文字與負例密度一換,分數分布就會換。把「有沒有任何合適 Skill」與「第一名是否正確」分成兩個判斷,才能區分真正的 no-match 和需要澄清的 near-tie。

先用 dev set 選門檻,再只在鎖住的 test set 報一次結果。若 Gate 輸出 probability,校準器還要用獨立 calibration data;否則只能稱 confidence score/規則分數。用 risk–coverage curve 同時看 AUTO error 與 coverage,避免靠大量 abstain 做出漂亮 accuracy。Tokenizer、embedding revision、routing cards 或 Skill pool 改變後,都要重新驗證門檻。

怎麼評測 Skill Router?先凍結題目,再看 token

別讓寫 Skill 的人照著 description 出題。官方描述優化指南建議同時準備 should-trigger、should-not-trigger 與共享關鍵詞的 near misses,並把 train/validation 分開。做 Router 時再加 indirect symptom、多語言、multi-skill 與真正沒有對應 Skill 的題目;最後鎖住一批從未參與調參的 test queries。

至少保留兩種 test:query-held-out 測同一 Skill 的新說法;skill-held-out 則把整個 Skill ID 及衍生 queries 排除在調參/訓練之外,測新 Skill 上架後的泛化。Query writer 也要分組切割;功能等價的近似 Skills 應標成多個可接受 gold,否則正確替代品會被誤算成錯誤。

Skill Router 全載入、BM25 與 hybrid retrieval 的真實研究命中率與 token 比較
同一篇 v1 預印本裡的兩種量尺:117 個 non-echo queries 比較 BM25 與 hybrid;token 圖則比較 875 筆 catalogue rows 的全載入與按需搜尋。詳見論文 Table 1 與 Figure 2

至少分三層記錄。排名層:Hit@1 看第一名是否屬於任一 gold;Hit@5 看前五是否至少出現一個 gold;多 Skill 任務的 Recall@5=前五找回的 required Skills/全部 required Skills,另用 Full-Coverage@5 檢查是否全到齊,MRR 則看第一個 relevant Skill 的倒數名次。閘門層:AUTO coverage=自動啟用題數/全部題數,accepted accuracy=AUTO 中選對的比例,並在真正 no-match 題記 false-activation rate。成本與成品層:記 discovery cards、正文、澄清回合合計的 input tokens(p50/p95)、延遲、正確 Skill 是否啟用與任務是否完成。只有所有 gold 都存在於凍結目錄時,全載入的 retrieval coverage 才是 100%;它仍須用端到端成功率與 context 成本評估。

那篇 690-node 研究的 load-all catalogue 是 46,915 tokens,按需搜尋約 560 tokens,減少 98.8%;這是該系統的序列化與目錄快照,不是所有 Router 都會得到的固定折扣。更值得抄的是實驗方法:相同 candidate budget、非 echo queries、並把檢索失敗和 sequencing/execution 失敗分開記。

這個入門架構先把 Graph 放在 sequencing

690-node 研究還測了 typed graph。它先用同一個 embedding top-k 找鄰居,再讓 LLM 為鄰居加上 requires、precedes、feeds-into 等關係;結果 98.6% 的 typed pairs 本來就落在 embedding 已連到的鄰居中。在相同六個候選預算下,hybrid@1+graph hit@5 是 63.2%,直接取 hybrid@6 是 74.4%。

這不代表 graph 沒用。它只表示:如果 graph 的候選邊先由同一套 embedding top-k 產生,它無法替 entry retrieval 增加 reach。這篇研究沒有驗證 graph sequencing 會勝過重複搜尋;作者明列缺少 skill-to-skill sequence dataset,而且 1,022 組 distinct typed pairs 中有 87 組(8.5%)出現方向矛盾。工程上可先用人工驗證的 prerequisites/dependencies 輔助已選定的任務 Skills,做 topological sort(讓 prerequisite 排在依賴者之前),再用 co-usage 或其他與 embedding 相對獨立的訊號,另做 sequence 與 sufficiency 實驗。

Skill Router 最常踩的 6 個坑

  1. 把「離線索引正文」和「把所有正文塞進 prompt」混為一談:runtime 仍只載入少數 Skills;offline retriever/reranker 是否讀 body,要用同一測試集做 metadata-only、分欄與 body-aware ablation。
  2. 只測明講 Skill 名稱的 query:加入改寫、症狀描述、錯字與跨語言。
  3. 直接加 BM25 與 cosine 原始分數:先用 RRF,或在開發集學習正規化權重。
  4. 永遠強制 top-1:把 CLARIFYNO_SKILL 當正式輸出。
  5. 把相似度當執行順序:只有明確 dependency 才能決定 prerequisites。
  6. 只看 retrieval、不看成品:記錄最後是否真的啟用正確 Skill、任務是否完成、載入多少 tokens。

Skill Router 常見問題 FAQ

1. Skill Router 是另一個 LLM 嗎?

不一定。最小版本就是本機 BM25、embedding 與規則閘門;只有需要精細 rerank 或生成澄清問題時,才可能多用一次模型。

2. 只有 10 個 Skills 也要做嗎?

通常先不用。官方輕量 catalog 加模型判斷常已夠用;當錯選、目錄截斷或 token 成本開始可量測,再加 Router。

3. Top-k 要設 1 還是 5?

先把 5 當候選起點,不是固定答案。Gate 可以選 0 個、1 個或多個 relevant Skills;例如「研究後再發布」可能需要兩個互補能力,而不只是主 Skill 的 prerequisite。只載入判定相關的 Skills,再展開各自的明確 prerequisites;候選 k 與最大載入數要按 Recall、錯選、token 與端到端成功率調整。

4. 只用 embedding 可以嗎?

可以做 baseline,但別先假設它會贏。產品名、錯誤碼與副檔名常讓 BM25 很有價值;hybrid 的意義就是保留兩種訊號。

5. 可以把 cosine 0.8 當自動啟用門檻嗎?

不能直接照抄。門檻要在自己的模型、目錄與 no-match 開發集校準,並一起看 top-1/top-2 margin。

6. Graph Router 比 hybrid retrieval 更進階嗎?

不是同一題。Hybrid 回答「現在最相關的是誰」;dependency graph 更適合回答「選中後還缺誰、先做誰」。

7. 使用者能不能直接指定 Skill?

可以,而且明確指定通常應優先。但 slash command 或 Skill mention 的語法由宿主決定,不是 Agent Skills 規格的一部分;Loader 仍要做權限、相容性與名稱有效性檢查。

8. 怎麼知道 Router 真的變好?

看鎖住的 test set 與端到端任務。同時比較命中率、錯誤啟用、澄清率、tokens、延遲與最後完成率;只展示幾個成功 demo 不夠。

給新手的 7 個重點

  • 先分清 discovery、routing、loading、sequencing。
  • 先做可讀、可檢查的 routing card,再談複雜模型。
  • BM25 抓字面,embedding 抓語意,RRF 合併排名。
  • Top-k 是候選,不是一次載入 k 份正文。
  • 低信心要能澄清,也要能回傳 NO_SKILL
  • Graph 用明確 prerequisites 排序,不用相似度杜撰依賴。
  • 最後以 held-out queries、token 與任務完成率驗收。

📚 延伸閱讀:把 Router 接回完整 Agent 系統

結論:先做一個敢說「不知道」的 Router

Skill Router 的價值,不是讓 Agent 每次都自信選一個答案,而是把「找候選、判斷不確定、按需載入、安排先後」變成可觀察、可測試的控制層。回到開頭的公式:BM25 抓字面,Embedding 抓意思,Abstain 防止硬選

今天先做 smoke test:挑 20 個真實 Skills,收集 direct、paraphrase、indirect、ambiguous、multi-skill 與 no-match 任務;在看結果前就把 dev 與 locked test 分開。用 dev 調 tokenizer、k 與門檻,只在 test 比 BM25、embedding、hybrid。若總共只有 40 題,請報每格 raw counts 與不確定性,不要把同一批題調完後的百分比當成泛化成績。你需要的不是更多 Skills,而是一個知道何時該拿哪一把工具、也知道何時先別拿的 Agent。

AlphaLab 精選

接著閱讀

ALPHALAB 社群

有問題?來 Telegram 聊

和 Terry、編輯、其他網友一起討論這篇文章。提問、分享觀點,回覆更即時。

加入 Telegram 討論

📩 訂閱 AlphaLab 電子報

每週一封,第一時間收到新文章與投資觀察。

我們不會 spam,隨時可退訂。