Skills 的觸發困境與 Custom Prompts 的過渡方案

系列:從鐵人賽到 Agent Orchestration — AI 自動建立 .NET 測試的完整方案(2/10)

前言

上一篇介紹了 29 個 Agent Skills 的全貌與安裝方式,看起來一切都很美好 — 安裝 Skills、啟用設定、用自然語言要求 AI 建立測試。

但實際使用之後,很快就會遇到一個根本問題:

AI 不太會主動觸發 Skill。

這篇文章要誠實面對這個痛點,分析背後的原因,以及我嘗試過的解決方案 — 從改善 Description 到設計 16 個 Custom Prompts — 每一步都有改善,但每一步也都留下新的問題。


期望 vs. 現實

理想情境

安裝完 29 個 Skills 之後,理想的使用體驗應該是這樣的:

  1. 使用者在 VS Code Agent Mode 輸入:「幫我為 OrderService 建立單元測試」
  2. AI 自動分析 OrderService 的建構子依賴(IOrderRepository、IPaymentGateway、IEmailService、TimeProvider)
  3. AI 判斷需要 NSubstitute Mock、AutoFixture 測試資料、TimeProvider 時間測試
  4. AI 載入對應的 Skills:nsubstitute-mockingautofixture-basicsdatetime-testing-timeprovider
  5. AI 依照 Skills 指引產出符合最佳實踐的測試程式碼

實際情況

實際上發生的事情往往是:

  • AI 沒有主動觸發任何 Skill,直接用通用知識寫測試
  • AI 觸發了 Skill,但載入的不是最需要的那幾個
  • AI 載入了入口型 Skill dotnet-testing,讀完導航文件後卻沒有繼續載入子技能
  • AI 載入了某個 Skill,但只用了一部分指引就開始寫程式碼

結果就是:測試可能用了 Moq 而不是 NSubstitute、用了原生 Assert 而不是 AwesomeAssertions (或是直接使用要花錢的 FluentAssertions)、命名沒有遵循中文三段式規範。這些「不符合團隊最佳實踐」的問題,正是 Skills 要解決的,卻因為觸發不穩定而打了折扣。

入口型 Skill 的困境

29 個 Skills 中有一個特殊的「入口型 Skill」— dotnet-testing,它的作用是導航中心,告訴 AI 在不同情境下該載入哪些子技能。

但問題在於:AI 需要先讀完整份導航文件,理解 29 個 Skills 的分類與適用情境,才能做出正確的判斷。這對 AI 來說是一個不小的認知負擔,而且即使讀完了,也不保證會做出正確的選擇。


根本原因分析

觸發問題不是單一原因造成的,背後有幾個結構性的因素:

1. AI 無法自動分析被測類別需要哪些技能組合

一個真實的測試場景,通常不是只用到一個 Skill。以 OrderProcessingService 為例:

public class OrderProcessingService
{
    private readonly IOrderRepository _orderRepository;
    private readonly IPaymentGateway _paymentGateway;
    private readonly IEmailService _emailService;
    private readonly TimeProvider _timeProvider;

    public OrderProcessingService(
        IOrderRepository orderRepository,
        IPaymentGateway paymentGateway,
        IEmailService emailService,
        TimeProvider timeProvider)
    {
        // ...
    }
}

要為這個類別寫出高品質的測試,AI 需要同時具備以下技能:

需求對應 Skill
Mock 4 個介面依賴nsubstitute-mocking
自動產生測試資料autofixture-basics
AutoFixture + NSubstitute 整合autofixture-nsubstitute-integration
TimeProvider 時間測試datetime-testing-timeprovider
AwesomeAssertions 斷言awesome-assertions-guide

這需要 AI 先分析被測類別的建構子參數、方法簽章、回傳型別,才能判斷需要哪些 Skills — 但目前的 Agent Skills 機制並沒有提供這種「分析再載入」的流程。AI 只能根據使用者的對話內容和 Skill 的 Description 做模糊匹配。

2. Context Window 壓力

單一 Agent 一次載入 5 個以上的 Skills,Context Window 就會面臨壓力。

以上面的例子來說,5 個 Skills 加起來約 39K tokens。加上被測類別的程式碼、測試專案的既有程式碼、使用者的對話歷史,Context Window 很容易就被填滿。

當 Context 被大量 Skill 內容佔據時,AI 對每個 Skill 的理解深度會下降,產出品質也會受影響。

3. 缺乏智能路由機制

目前的 Agent Skills 機制是「被動」的 — AI 根據對話情境自行判斷要不要載入某個 Skill,以及載入哪個。

沒有一個「路由器」的角色來主動分析情境、決定載入哪些 Skills、以什麼順序使用它們。


Description 與版本演進的努力

意識到觸發問題後,我在每個版本中都嘗試改善 Skill 的 Description、Triggers 與內容結構,希望提高 AI 的觸發機率。

v1.0.0 → v2.0.0:全面加入 Triggers

v1.0.0 是首次發布,27 個 Skills 的 Description 相對簡短。到了 v2.0.0,做了全面優化:

  • 為所有 Skills 加入 Triggers 欄位,總計 400~520 個觸發關鍵字
  • 改用多行 Description 格式,更清楚地描述功能與適用情境
# v1.0.0 — 簡短描述
---
name: nsubstitute-mocking
description: NSubstitute mocking guide for .NET tests.
---

# v2.0.0 — 多行描述 + Triggers
---
name: nsubstitute-mocking
description: >-
  NSubstitute mocking and dependency isolation for .NET unit tests.
  Use when creating mock objects, setting up method returns, or
  verifying method calls with NSubstitute in xUnit test projects.
triggers:
  - mock
  - NSubstitute
  - dependency isolation
  - Substitute.For
  - Returns
  - Received
---

v2.1.0:符合 agentskills.io 官方規範

v2.1.0 的重點是遵循 Agent Skills 的官方規範。其中一個重要變更是:

  • 移除非標準的 triggers 欄位,將觸發關鍵字整合到 description
  • 官方規範中並沒有 triggers 這個 frontmatter 欄位,AI 實際上是靠 description 的內容來判斷是否相關

這個版本讓所有 29 個 Skills 完全符合官方規格。

v2.2.0:依據 Anthropic 指南重新調整

v2.2.0 是根據 Anthropic 發布的「The Complete Guide to Building Skills for Claude」所做的全面調整,引入了幾個關鍵概念:

漸進式揭露(Progressive Disclosure)

將 SKILL.md 主文件控制在 500 行以內,詳細的範例、模式、腳本移到 references/ 目錄。AI 先讀取精簡的主文件理解核心指引,需要時再載入參考資料。

nsubstitute-mocking/
├── SKILL.md              # 精簡主文件(≤500 行)
└── references/
    └── advanced-patterns.md  # 詳細範例與進階模式

具體的改善項目:

改善項目影響範圍
SKILL.md 精簡至 ≤500 行,詳細內容移至 references/21 個 Skills
Description 加入「when you need to...」觸發句型14 個 Skills
補充 related_skills 欄位,改善 Skill 間的導航26 個 Skills
統一第一個 H2 段落為「適用情境」17 個 Skills
統一最後一個 H2 段落為「參考資源」9 個 Skills

效果:有改善但仍無法根本解決

每一次版本優化都有帶來改善 — Description 更精準、結構更清晰、Context Window 佔用更少。

但核心問題依然存在:AI 仍然需要自己判斷要不要載入、載入哪個 Skill。即使 Description 寫得再好,AI 面對一個有 4 個介面依賴的 Service,還是無法可靠地判斷「我需要同時載入 nsubstitute-mocking + autofixture-basics + datetime-testing-timeprovider」。


Custom Prompts 補強方案

既然 AI 不會自己判斷,那就由使用者來明確告訴它 — 這就是 Custom Prompts 的設計初衷。

16 個 Custom Prompts

我設計了 16 個 Custom Prompts(Slash Commands),每個 Prompt 對應一個或多個 Skill 的組合,涵蓋 29 個 Skills 的所有功能:

16 個 Custom Prompts:https://github.com/kevintsengtw/dotnet-testing-agent-orchestration/tree/main/.github/prompts

基礎與框架(4 個)

Custom Prompt用途載入的 Skills
/dotnet-testing-fundamentals基礎單元測試unit-test-fundamentals、test-naming-conventions、xunit-project-setup
/dotnet-testing-advanced-xunit-upgradexUnit v2→v3 升級xunit-upgrade-guide
/dotnet-testing-advanced-tunitTUnit 框架tunit-fundamentals、tunit-advanced
/dotnet-testing-advanced-aspire-testingAspire 測試aspire-testing

整合測試(2 個)

Custom Prompt用途載入的 Skills
/dotnet-testing-advanced-integrationASP.NET 整合測試aspnet-integration-testing、webapi-integration-testing
/dotnet-testing-advanced-testcontainers容器化測試testcontainers-database、testcontainers-nosql

測試資料(2 個)

Custom Prompt用途載入的 Skills
/dotnet-testing-autofixture-bogus測試資料產生autofixture-basics、autofixture-customization、bogus-fake-data、autofixture-bogus-integration、autodata-xunit-integration
/dotnet-testing-test-data-builderTest Data Buildertest-data-builder-pattern

Mock 與斷言(3 個)

Custom Prompt用途載入的 Skills
/dotnet-testing-nsubstitute-mockingNSubstitute Mocknsubstitute-mocking、autofixture-nsubstitute-integration、autodata-xunit-integration
/dotnet-testing-assertions斷言與物件比較awesome-assertions-guide、complex-object-comparison
/dotnet-testing-fluentvalidation-testingFluentValidation 測試fluentvalidation-testing

測試實踐(3 個)

Custom Prompt用途載入的 Skills
/dotnet-testing-test-output-logging測試輸出與記錄test-output-logging
/dotnet-testing-code-coverage-analysis程式碼覆蓋率code-coverage-analysis
/dotnet-testing-private-internal-testingPrivate/Internal 測試private-internal-testing

特定場景(2 個)

Custom Prompt用途載入的 Skills
/dotnet-testing-datetime-testing-timeprovider時間測試datetime-testing-timeprovider
/dotnet-testing-filesystem-testing-abstractions檔案系統測試filesystem-testing-abstractions

使用方式

在 VS Code Agent Mode 的對話中,使用者可以輸入 Slash Command 來明確觸發:

/dotnet-testing-nsubstitute-mocking 為 OrderService 建立單元測試

AI 收到這個指令後,就會確定載入 nsubstitute-mockingautofixture-nsubstitute-integrationautodata-xunit-integration 三個 Skills,然後依照 Skills 的指引來撰寫測試。

每個 Custom Prompt 的結構是標準的 .prompt.md 檔案,包含 YAML frontmatter 和明確的 SKILL.md 讀取指令:

---
agent: 'agent'
description: 'AwesomeAssertions 斷言與複雜物件比較完整指南'
---

## 重要指示

**在執行以下任務之前,你必須先讀取並完整理解以下技能文件的全部內容:**

**必讀資源**:
1. `.github/skills/dotnet-testing-awesome-assertions-guide/SKILL.md`
2. `.github/skills/dotnet-testing-complex-object-comparison/SKILL.md`

...

透過在 Prompt 中明確列出要讀取的 SKILL.md 路徑,確保 AI 一定會載入對應的 Skills。

優點

Custom Prompts 確實解決了「觸發」的問題:

  • 確定性:使用者明確指定,AI 一定會載入對應的 Skills
  • 組合性:每個 Prompt 預先配好了正確的 Skill 組合,不需要使用者了解每個 Skill 的名稱
  • 品質提升:因為 Skills 確實被載入和遵循,測試品質明顯優於不使用 Skills 的情況

致命缺陷

但 Custom Prompts 有一個致命的問題 — 認知負擔轉移到了使用者身上

使用者需要從 16 個指令中選擇正確的那一個。

回到 OrderProcessingService 的例子,使用者需要:

  1. 先分析 OrderProcessingService 有哪些依賴
  2. 判斷需要 Mock(因為有介面依賴)
  3. 判斷需要 TimeProvider 測試(因為有 TimeProvider 參數)
  4. 判斷需要 AutoFixture(因為方法有複雜的輸入參數)
  5. 從 16 個指令中找到最合適的那一個...
    • /dotnet-testing-autofixture-bogus
    • /dotnet-testing-nsubstitute-mocking
    • 還是 /dotnet-testing-datetime-testing-timeprovider

這就是問題所在 — 使用者要從 16 個指令中挑對的那一個,這跟原本期待 AI 自己觸發正確 Skill 一樣難。

使用者不該需要做這些判斷。使用者應該只需要說一句話:「為 OrderService 建立測試」,剩下的事情都該由 AI 來處理。


問題的本質

走過 4 個版本的 SKILL.md 內的 Description 優化和 16 個 Custom Prompts 之後,我就開始意識到:

問題不在 Skill 的數量或 Description 的寫法。

問題在於一個根本的架構缺陷:

誰來決定載入哪些 Skills?

目前的答案是「AI 自己判斷」或「使用者手動指定」。這兩個答案都不夠好。

真正的解決方案需要一個能夠:

  1. 自動分析被測類別的程式碼特徵
  2. 智能決策需要哪些技能組合
  3. 精準載入對應的 Skills
  4. 獨立運作在隔離的 Context 中深入理解每個 Skill

這不是靠改善 SKILL.md 的 Description 或設計更多 Custom Prompts 能解決的。

直到 2026 年 2 月 4 日,VS Code v1.109 更新中出現了 Agent Orchestration and Subagents 的功能支援。於是我就在我想,這或許能拿來解決前面不管是單純使用 Agent Skills 還是改用 Custom Prompts 時所遇到的問題。

下一篇就來聊 VS Code v1.109 帶來了什麼,以及我怎麼用它來設計新的架構。


參考資源

NET Testing Agent Skills

Agent Skills

純粹是在寫興趣的,用寫程式、寫文章來抒解工作壓力