iT邦幫忙

2025 iThome 鐵人賽

DAY 26
0
生成式 AI

AI 全餐,好吃嗎?用 Semantic Kernel 打造你的客製化滿漢全席!系列 第 26

Day 26: 安全第一的饗宴:用 Filters 確保 AI 的責任與安全

  • 分享至 

  • xImage
  •  

連續二十五天,我們用 Semantic Kernel (SK) 這位頂級廚師烹飪出了一道道令人驚豔的 AI 佳餚。然而,在正式將這些菜餚端給客人之前,我們還差最關鍵的一步:食品安全檢查!

在 AI 的世界裡,這不只是避免 AI 說錯話,更是要確保 AI 執行動作時是安全、負責任,並且符合我們企業規範的。如果我們讓 AI 擁有呼叫 API (Plugins) 的能力,它就擁有改變真實世界的能力(例如:建立訂單、發送郵件、轉帳)。一旦失控,後果不堪設想。

這時候,**Semantic Kernel 的 Filters(篩選器)**就像是我們廚房的「安全檢查閘門」,讓你在 AI 的執行流程中,任何關鍵步驟都能介入、檢查、甚至修改或阻止。

🛡️ Filters:AI 廚房的三大安全檢查點

Filters 提供了三個主要的檢查點,讓我們能實現 Human-in-the-loop (人在迴路中) 的安全機制。

Filter 類型 檢查點比喻 發生時機 主要用途
PromptRenderFilter 食材備料檢查 提示詞送給 LLM 之前 檢查或修改要送給模型的提示詞,可用於防範提示詞注入 (Prompt Injection)。
FunctionInvocationFilter 廚師動手檢查 執行 Plugin 函式 之前/之後 這是最關鍵的安全點,用於檢查函式參數、執行前確認、記錄呼叫日誌。
AutoFunctionInvocationFilter AI 自主呼叫檢查 LLM 決定要呼叫函式、並由 SK 自動執行之前 專門用於 Function Calling 情境,在 SK 自動執行 LLM 建議的函式前進行最後確認。

匯出到試算表

其中,FunctionInvocationFilter 是我們執行敏感操作時最常使用的利器。今天,我們就來實戰這個 Filter,實現一個企業級的常見需求:在執行改變數據的動作前,要求開發者或使用者確認 (Human-in-the-loop)

實戰:敏感操作前的「確認鈕」

想像我們有一個名為 OrderPlugin 的工具,其中包含一個函式 CreateOrder,用來在企業系統中建立一筆正式訂單。這是個高敏感度的操作。我們需要 SK 在呼叫這個函式前,暫停並要求人工確認

我們將實作一個 ApprovalFilter 類別,並將它註冊到 Kernel 中。

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using System.Text.Json;
using static Microsoft.Extensions.AI.FunctionInvokingChatClient;

var config = new ConfigurationBuilder()
    .AddUserSecrets<Program>()
    .Build();

var kernelBuilder = Kernel.CreateBuilder()
    .AddOpenAIChatCompletion(
        modelId: "gpt-5",
        apiKey: config["OpenAI:ApiKey"]!);

// 註冊我們的 OrderPlugin
kernelBuilder.Plugins.AddFromObject(new OrderPlugin());

// 註冊我們的 ApprovalFilter 到 Kernel
kernelBuilder.Services.AddSingleton<ApprovalFilter>();
Kernel kernel = kernelBuilder.Build();
Console.WriteLine("✅ 已註冊 OrderPlugin 及 ApprovalFilter。");

// 讓 AI 決定呼叫函式
var prompt = "請為客戶 ID 888 訂購 10 份『豪華套餐』。";

var settings = new OpenAIPromptExecutionSettings
{
    ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions
};

Console.WriteLine($"\n🧑 客戶請求:{prompt}");

// 執行請求
var result = await kernel.InvokePromptAsync(prompt, new(settings));

// 輸出結果
Console.WriteLine("\n🤖 AI 最終回覆:");
Console.WriteLine(result.GetValue<string>());

// 建立一個模擬的敏感 Plugin:訂單系統
public class OrderPlugin
{
    [KernelFunction("CreateOrder")]
    [System.ComponentModel.Description("在系統中建立一筆新的客戶訂單。")]
    public string CreateOrder(string customerId, string product, int quantity)
    {
        Console.ForegroundColor = ConsoleColor.Red;
        Console.WriteLine($"\n[系統通知] 正在為客戶 {customerId} 建立訂單:{quantity} 個 {product}...");
        Console.ResetColor();
        // 實際業務邏輯 (例如呼叫 CRM 或 ERP API)kmljn
        return $"訂單已成功建立。訂單編號:ORD-{DateTime.Now.Ticks % 10000}";
    }
}

// 實作我們的安全檢查閘門:FunctionInvocationFilter
public class ApprovalFilter : IFunctionInvocationFilter
{
    public async Task OnFunctionInvocationAsync(FunctionInvocationContext context, Func<FunctionInvocationContext, Task> next)
    {
        // 檢查:只有當函式名稱是 'CreateOrder' 時才需要介入
        if (context.Function.Name.Equals("CreateOrder", StringComparison.OrdinalIgnoreCase))
        {
            Console.WriteLine("\n🚨🚨 [FunctionInvocationFilter 啟動] 🚨🚨");
            Console.WriteLine($"AI 建議呼叫的函式: {context.Function.Name}");
            Console.WriteLine($"參數: {JsonSerializer.Serialize(context.Arguments)}");

            // 實現 Human-in-the-loop
            Console.Write("這是敏感操作!您是否確定要執行?(y/n): ");
            var response = Console.ReadLine();

            if (response?.ToLower() != "y")
            {
                Console.WriteLine("🛑 操作已取消。");
                return; // 直接返回,不會執行實際的 CreateOrder 函式
            }
        }

        // 如果不是敏感函式,或使用者已確認,則繼續執行下一個步驟 (執行函式)
        await next(context);
    }
}

運作原理與洞察

當我們執行上述程式碼時,即使 AI 判斷它需要呼叫 CreateOrder 函式,程式也不會直接執行。

  1. AI 判斷: LLM 決定呼叫 OrderPlugin.CreateOrder(customerId: 888, product: "豪華套餐", quantity: 10)
  2. Filter 介入: AutoFunctionInvocationFilter 會先讓 SK 準備執行,但緊接著 FunctionInvocationFilter (也就是我們的 ApprovalFilter) 會被觸發。
  3. 人工確認: ApprovalFilter 檢查到是敏感操作,暫停流程並在 Console 要求使用者輸入 yn
  4. 結果:
    • 如果輸入 y,Filter 呼叫 next(context),實際的 CreateOrder 函式會被執行。
    • 如果輸入 n,Filter 不呼叫 next(context),而是直接在 context.Result 中設置一個「操作取消」的結果,這個結果將被回傳給 LLM,讓 LLM 知道操作失敗。

透過這個機制,我們成功地在 AI 的智慧和現實世界的執行之間,建立了一個不可或缺的安全與責任邊界,確保每一筆敏感操作都在人工的監督之下。


上一篇
Day 25: 企業級特選食材:用 OpenAPI 規格匯入既有 API 作為 Plugin
系列文
AI 全餐,好吃嗎?用 Semantic Kernel 打造你的客製化滿漢全席!26
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言