使用 GitHub Copilot SDK 實作 AI 代理

已完成

本單元涵蓋使用 GitHub Copilot SDK 建構 AI 代理的核心實作模式。 這些模式適用於任何代理人的情境。 程式碼範例使用 C# 與 .NET,後者是模組練習所使用的平台。

設定 GitHub Copilot SDK 客戶端

第一步是建立 CopilotClient 一個實例來管理與 Copilot CLI 伺服器的連線。 通常,您會在應用程式中將客戶端註冊為 Singleton 服務。

安裝必要的套件

將 GitHub Copilot SDK 和用於工具定義的 Microsoft.Extensions.AI 套件加入你的專案:

dotnet add package GitHub.Copilot.SDK
dotnet add package Microsoft.Extensions.AI

設定用戶端

使用可控制啟動行為與記錄的 CopilotClientOptions 建立 CopilotClient

var client = new CopilotClient(new CopilotClientOptions
{
    AutoStart = true,
    LogLevel = "info"
});

AutoStart 選項會告訴 SDK 在建立第一個會話時自動啟動 Copilot CLI 伺服器程序。 這個 LogLevel 選項可以控制 SDK 診斷輸出的冗長程度。

建立客戶端後,啟動它:

await client.StartAsync();

此程式碼建立與 CLI 伺服器的連線,並準備用戶端建立會話。

定義代理程式工具

工具讓代理能夠與你應用程式的後端服務互動。 在 GitHub Copilot SDK for .NET 中,你可以用 AIFunctionFactory.Create 套件中的 Microsoft.Extensions.AI 工具來定義工具。

建立工具服務

一個常見的模式是建立一個專用的服務類別,包含代理能呼叫的所有工具方法。 每種方法代表代理人可採取的一個行動:

public class SupportAgentTools
{
    public async Task<string> GetOrderDetailsAsync(int orderId)
    {
        // Query the database for order information
        var order = await _dbContext.Orders.FindAsync(orderId);
        return order != null
            ? $"Order {orderId}: {order.ProductName}, Status: {order.Status}"
            : "Order not found.";
    }

    public async Task<string> ProcessReturnAsync(int orderId, string reason)
    {
        // Business logic to process the return
        var order = await _dbContext.Orders.FindAsync(orderId);
        order.Status = "Return Initiated";
        await _dbContext.SaveChangesAsync();
        return $"Return initiated for order {orderId}.";
    }
}

將工具註冊到 SDK

將你的服務方法轉換成 SDK 可用的工具定義。 每個工具都需要名稱、描述和參數描述,讓 AI 模型了解何時以及如何使用:

var toolService = new SupportAgentTools(dbContext);

var tools = new List<AIFunction>
{
    AIFunctionFactory.Create(
        async ([Description("The order ID number")] int orderId) =>
            await toolService.GetOrderDetailsAsync(orderId),
        "get_order_details",
        "Look up the status and details of a specific order."),

    AIFunctionFactory.Create(
        async ([Description("The order ID")] int orderId,
               [Description("The reason for the return")] string reason) =>
            await toolService.ProcessReturnAsync(orderId, reason),
        "process_return",
        "Process a return request for an order.")
};

每個 AIFunctionFactory.Create 呼叫包含三個參數:

  1. 一個 lambda 函式 ,包裹你的服務方法,每個參數都有 [Description] 屬性。
  2. 一個 AI 模型用來參考的工具名稱
  3. 一個幫助模型了解何時呼叫工具的描述

[Description]參數上的屬性很重要——它們告訴 AI 模型每個參數代表什麼,幫助模型在呼叫工具時提供準確的數值。

建立與設定會話

會話代表單獨的對話或任務上下文。 你可以配置會話的模型、系統提示詞、工具和其他設置。

設定會話

SessionConfig 來指定會話應如何運作:

var config = new SessionConfig
{
    Model = "gpt-4.1",
    SystemMessage = new SystemMessageConfig
    {
        Mode = SystemMessageMode.Replace,
        Content = @"You are a customer support agent for an e-commerce company.

CAPABILITIES:
- Look up order details
- Process returns

RULES:
- Only assist with order-related inquiries
- Always verify order details before taking action
- Be polite and professional"
    },
    Tools = tools,
    InfiniteSessions = new InfiniteSessionConfig
    {
        Enabled = false
    }
};

主要配置選項:

  • 模型:指定本次會議使用哪個 AI 模型。
  • SystemMessage:定義代理的角色與行為。 Mode 確定你的提示是替換預設系統訊息(Replace)還是附加至其後(Append)。
  • 工具:代理可使用的工具定義清單。
  • InfiniteSessions:控制長時間對話的自動上下文壓縮。 啟用後,你可以調整 BackgroundCompactionThresholdBufferExhaustionThreshold 來控制壓實發生的時間。

建立會話

用你的設定從客戶端建立一個會話:

var session = await client.CreateSessionAsync(config);

使用事件來處理回應

GitHub Copilot SDK 採用事件驅動的溝通模型。 發送訊息後,你會訂閱事件以接收回應並偵測處理是否完成。

訂閱會議活動

使用 session.On 帶有模式匹配的方法來處理不同類型的事件:

var responseBuilder = new StringBuilder();
var tcs = new TaskCompletionSource<string>();

session.On(evt =>
{
    switch (evt)
    {
        case AssistantMessageEvent msg:
            responseBuilder.Append(msg.Data.Content);
            break;

        case SessionIdleEvent:
            tcs.SetResult(responseBuilder.ToString());
            break;

        case SessionErrorEvent err:
            tcs.SetException(
                new Exception($"Agent error: {err.Data.Message}"));
            break;
    }
});

每種活動類型都有其特定目的:

  • AssistantMessageEvent:包含代理回應文字的一部分。 你累積這些訊息碎片,以建立完整的回應。
  • SessionIdleEvent:表示代理完成處理,包括所有工具呼叫。 此事件表示回應已完成。
  • SessionErrorEvent:表示處理過程中發生錯誤。 該 Data.Message 屬性包含錯誤描述。

發送訊息並等待回覆

使用 SendAsync 物件 MessageOptions 來將使用者的提示音傳送給代理:

await session.SendAsync(new MessageOptions
{
    Prompt = "What is the status of order 12345?"
});

// Wait for the response with a timeout
var response = await tcs.Task.WaitAsync(TimeSpan.FromSeconds(30));

這裡示範的 TaskCompletionSource 模式,可讓你把事件驅動的 SDK 模型,銜接到 async/await 程式碼。 當 SessionIdleEvent 觸發時,將以累積的回應文字來完成任務。

錯誤處理最佳實務

穩健的錯誤處理對生產代理至關重要。

工具處理器錯誤

請用 try-catch 將工具處理常式包起來,並回傳有意義的錯誤訊息,而不是直接擲出例外狀況。 當工具回傳錯誤訊息時,AI 模型能解讀並向使用者提供有用的回應:

AIFunctionFactory.Create(
    async ([Description("The order ID")] int orderId) =>
    {
        try
        {
            return await toolService.GetOrderDetailsAsync(orderId);
        }
        catch (Exception ex)
        {
            return $"Error retrieving order: {ex.Message}";
        }
    },
    "get_order_details",
    "Look up the status and details of a specific order.")

會話層級錯誤處理

在代理處理過程中使用SessionErrorEvent來捕捉錯誤。 你也可以設定 OnErrorOccurred 會話掛鉤,回傳 ErrorHandling 一個值來控制代理如何回應錯誤:

  • 重試:再次嘗試失敗的行動。
  • 跳過:繼續處理,忽略失敗的結果。
  • 中止:停止處理並顯示錯誤。

Timeouts

等待回覆時一定要設定暫停。 前述範例用於 WaitAsync(TimeSpan.FromSeconds(30)) 防止代理遇到意外問題時無限期等待。

系統提示詞設計

系統提示是最重要的配置決策之一。 它定義了代理人是誰、能做什麼,以及應該如何行為。 一個結構良好的系統提示通常包含:

  • 角色定義:客服代表什麼(例如,「你是 ContosoShop 的客戶支援客服」)。
  • 功能:有哪些工具可用,以及它們的功能。
  • 工作流程指引:客服應如何處理任務(例如:「在處理退貨前,務必確認訂單細節」)。
  • 規則與限制:代理人必須遵守的界限(例如:「僅討論與訂單相關的主題」或「升級超過100美元的退款申請」)。

保持系統提示聚焦且具體。 模糊的指示會導致行為難以預測,而過於嚴格的規則則可能讓客服人員變得無助。

使用delta事件串流傳輸回應

對於像聊天介面這類互動式應用程式,你可以逐個令牌串流代理的回應令牌,而不必等待完整訊息。 使用 AssistantMessageDeltaEvent 在每個部分權杖到達時逐一擷取:

session.On(evt =>
{
    switch (evt)
    {
        case AssistantMessageDeltaEvent delta:
            // Render each token as it arrives
            Console.Write(delta.Data.DeltaContent);
            break;

        case SessionIdleEvent:
            Console.WriteLine();
            tcs.SetResult("Done");
            break;

        case SessionErrorEvent err:
            tcs.SetException(
                new Exception($"Agent error: {err.Data.Message}"));
            break;
    }
});

DeltaContent 屬性包含增量文本片段。 串流提供更靈敏的體驗,因為使用者能看到回應形成的過程,而不必等待模型生成完整訊息。

總結

GitHub Copilot SDK 提供了一個強大的框架,用於實作能夠推理、使用工具並維持上下文的 AI 代理。 透過工具定義客服人員的能力、以明確系統提示配置會話,以及以事件處理回應,您可以打造出真正帶來商業價值的複雜客服。 穩健的錯誤處理與深思熟慮的提示設計,對於確保您的代理在生產情境中可靠且有效運作至關重要。 在下一個單元中,你將看到如何應用這些實作模式,使用 GitHub Copilot SDK 建立一個客戶支援代理範例。