實作課程 03 — 工具¶
目標: 使用以下項目,以模型可視需要呼叫的真正 C# 函式取代靜態提示內容: CopilotTool.DefineTool 以及 SessionConfig.Tools.
時間: 約 20 分鐘
必要條件: 實作課程 02 已完成。
步驟 1 — 為何需要工具¶
在實作課程 02 中,您將零售資料放入系統訊息,讓助理的回答有所依據。這適用於小型範例,但有三個問題:
- 內容是靜態的 — 它只知道您一開始貼入的資訊
- 模型必須猜測哪些事實重要
- 每項事實都會消耗權杖,即使回答根本不需要該事實
工具會改變問題的處理方式。您不再需要寄望提示中包含正確資料,而是註冊一個 C# 函式。模型會判斷何時需要該函式、要求 SDK 呼叫、接收結果,再撰寫最終答案。
步驟 2 — 檢視工具結構¶
開啟
ToolsSample.cs
並找到 GetCustomerTotal.
Copilot SDK 工具一開始只是一個一般的 C# 方法:
[Description("Gets the total amount a given retail customer has spent.")]
private static string GetCustomerTotal(
[Description("Customer identifier, for example C003")] string customerId)
{
...
}
最重要的部分是 [Description] 中繼資料,來源為
System.ComponentModel.
這些描述就是模型的 API 文件。若方法描述含糊,模型可能找不到工具;若參數描述含糊,模型可能傳入錯誤值。請像為其他開發人員記錄公用 API 一樣撰寫描述。
步驟 3 — 註冊工具¶
CopilotTool.DefineTool(GetCustomerTotal) 會將方法轉換為
AIFunction。接著,將該函式指派給工作階段設定:
var modelId = await ModelPicker.PickAsync(client, requestedModelId);
var totalTool = CopilotTool.DefineTool(GetCustomerTotal);
var config = new SessionConfig
{
Model = modelId,
Streaming = false,
Tools = [totalTool]
};
該 Tools = [totalTool] 行正是「模型只有一些文字內容」與「模型可以要求主機應用程式執行實際工作」之間的差異。
ModelPicker 會保留 claude-haiku-4.5 作為這些實作課程的慣用模型,但若您的帳戶無法使用,則會回復為可用模型。您可以使用以下項目覆寫:
--model <id>.
步驟 4 — 執行¶
預期輸出:
== Lab 03: tools ==
Model: claude-haiku-4.5
Prompt: How much has customer C003 spent in total?
Assistant:
[tool] GetCustomerTotal(C003) -> $1,700.00
Assistant: Customer C003 has spent a total of **$1,700.00** across 2 transactions.
⚠️ 請注意第一個空白 Assistant: 行。這是真實行為:助理訊息事件會在工具呼叫附近觸發,早於最終自然語言答案的組合。
步驟 5 — 追蹤實際發生的情況¶
執行作業包含四個運作部分:
- 提示要求查詢客戶的消費總額:
C003 - 模型判斷已註冊工具是回答問題的正確方式
- SDK 會叫用 C# 方法,產生
[tool]行 - 工具結果會送回模型,再由模型撰寫最終答案
此 [tool] GetCustomerTotal(C003) -> $1,700.00 行並非模擬輸出,而是由真正的 GetCustomerTotal 方法,而 SDK 正在處理模型的工具呼叫。
步驟 6 — 進行實驗¶
試試不存在的客戶,例如 C999。工具會傳回一般字串而不是擲回例外,以處理該情況:
重新執行範例,確認助理回報找不到任何交易。
然後試試不需要零售資料的提示:
模型應該直接回答。由於不需要查詢客戶,
[tool] 行不應出現。
步驟 7 — 使用權限控制工具執行¶
SDK 也公開處理程序內權限掛鉤:
OnPermissionRequest = (request, invocation) =>
{
return Task.FromResult(PermissionDecision.ApproveOnce());
}
簽章如下:
決策來自 GitHub.Copilot.Rpc.PermissionDecision,包括
ApproveOnce() 以及 Reject(string feedback)。另外也有內建捷徑: PermissionHandler.ApproveAll,適用於允許所有要求的範例。
⚠️ 在 GitHub Copilot SDK v1.0.9 中,此權限決策 API 標示為實驗性。使用 GitHub.Copilot.Rpc.PermissionDecision 會引發建置錯誤
GHCP001 ,除非該內容遭到隱藏。範例專案刻意在以下位置進行此處理:
SdkLabs.csproj:
⚠️ 將此掛鉤當作強制執行點時,務必極度謹慎。根據我們的測試,處理常式 從未叫用 — 即使處理常式拒絕每個要求,命令仍會執行,因為主機 CLI 已預先授予工具核准。請將 OnPermissionRequest 視為只有在主機將決策交給它時才會介入的掛鉤。請在 您的
環境中進行驗證,再將它作為控制措施。
請參閱
PermissionsSample.cs
取得參考程式碼。如需 Shell 掛鉤治理替代方案,請參閱
extra-governance-hooks.
CopilotToolOptions.SkipPermission 也可以在適合您的主機時,讓工具不參與權限流程。
✅ 檢查點¶
您現在可以說明:
- [x] 瞭解為何工具優於將動態資料塞入系統訊息
- [x] 如何
[Description]屬性會引導工具選擇與引數設定 - [x] 如何
CopilotTool.DefineTool會將 C# 方法註冊為AIFunction - [x] 如何
SessionConfig.Tools會讓模型可以使用該函式 - [x] 瞭解為何權限掛鉤必須在實際執行的主機中驗證
💡 延伸練習¶
新增第二個工具,用來傳回客戶購買過的產品類別,例如 Electronics 以及 Fashion 用於 C003。請為方法及其參數提供精確的 [Description] 屬性,並將它註冊在以下項目旁:
GetCustomerTotal,接著詢問:
確認模型呼叫一個工具、兩個工具,或直接回答。
相關內容¶
- 上一步: 實作課程 02 — 您的第一次串流對話
- 下一步: 實作課程 04 — 事件
- 示範:Copilot SDK 整合
- 疑難排解