這篇我們要來做一個基於 Single Agent 變化的 AI Agent 範例——「OfficeOne Agent」,這個助理可以根據使用者的需求,使用最合適的工具來完成任務。OfficeOne Agent 能夠處理關於會議室預約、辦公用品申請及訪客通行證申請等請求。這意味著 Agent 需要設計一個具有多個工具並且能夠根據不同的請求動態選擇合適的工具來處理。
接下來,我們將逐步實現這個多工具的 OfficeOne Agent,並展示如何使用 Semantic Kernel 來達成這個目標。
首先,我們要建立一個 OfficePlugin
,這個插件會提供三個 functions,分別是 BookMeetingRoom
、RequestOfficeSupplies
和 RequestVisitorPass
,讓我們的 Agent 可以根據使用者的需求呼叫這些功能來完成任務。開發要點是各 function 都要有清楚的用途及參數描述(Description),這樣 LLM 才能理解每個工具的用途,並在需要時正確的選擇它們。
OfficePlugin
類別,並加入以下方法程式碼:[KernelFunction, Description("預約公司會議室")]
public string BookMeetingRoom(
[Description("會議室編號(例如 A101)")] string roomId,
[Description("預約日期(YYYY-MM-DD)")] string bookingDate,
[Description("開始時間(HH:MM)")] string startTime,
[Description("結束時間(HH:MM)")] string endTime,
[Description("會議主題")] string meetingSubject,
[Description("預約人員工編號(例如 A1234)")] string employeeId)
{
// 模擬會議室預約成功,實際應用中會連接公司內部系統
return $"✅ 會議室預約成功!\n" +
$"會議室:{roomId}\n" +
$"日期:{bookingDate}\n" +
$"時間:{startTime} - {endTime}\n" +
$"主題:{meetingSubject}\n" +
$"預約編號:MTG{DateTime.Now:yyyyMMddHHmmss}";
}
RequestOfficeSupplies
,用於辦公用品申請:[KernelFunction, Description("申請辦公用品(文具/耗材)")]
public string RequestOfficeSupplies(
[Description("申請人員工編號(例如 A1234)")] string employeeId,
[Description("申請人姓名")] string employeeName,
[Description("申請用品項目名稱")] string itemNames,
[Description("申請數量")] string quantities,
[Description("申請用途說明")] string purpose)
{
// 模擬辦公用品申請成功,實際應用中會連接公司內部系統
return $"✅ 辦公用品申請已提交!\n" +
$"申請人:{employeeName}({employeeId})\n" +
$"申請用品:{itemNames}\n" +
$"數量:{quantities}\n" +
$"用途:{purpose}\n" +
$"申請編號:SUP{DateTime.Now:yyyyMMddHHmmss}\n" +
$"狀態:待審核";
}
RequestVisitorPass
,用於訪客通行證申請:[KernelFunction, Description("申請訪客通行證")]
public string RequestVisitorPass(
[Description("申請人員工編號(例如 A1234)")] string employeeId,
[Description("申請人姓名")] string employeeName,
[Description("訪客姓名")] string visitorName,
[Description("訪客公司/機構")] string visitorCompany,
[Description("拜訪日期(YYYY-MM-DD)")] string visitDate,
[Description("預計到達時間(HH:MM)")] string arrivalTime,
[Description("預計離開時間(HH:MM)")] string departureTime,
[Description("拜訪目的")] string visitPurpose,
[Description("拜訪地點/樓層(例如 A棟3樓)")] string visitLocation)
{
// 模擬訪客通行證申請成功,實際應用中會連接公司內部系統
var passCode = GeneratePassCode();
return $"✅ 訪客通行證申請成功!\n" +
$"訪客:{visitorName}\n" +
$"拜訪日期:{visitDate}\n" +
$"拜訪時間:{arrivalTime} - {departureTime}\n" +
$"通行證編號:{passCode}\n" +
$"申請編號:VIS{DateTime.Now:yyyyMMddHHmmss}";
}
接下來,我們要建立一個 OfficeAgent
,這個 Agent 會使用我們剛剛建立的 OfficePlugin
,並根據員工的需求來決定要呼叫哪一個工具來完成任務。
var kernel = Kernel.CreateBuilder()
.AddOpenAIChatCompletion(
apiKey: Config.OpenAI_ApiKey,
modelId: Config.ModelId)
.Build();
// 註冊辦公室助手工具
kernel.Plugins.AddFromType<OfficePlugin>();
var agent = new ChatCompletionAgent
{
Name = "OfficeOneAgent",
Description = "協助員工以對話方式完成辦公室相關請求的 AI 助理",
Instructions = """
你是公司行政服務 AI 助理。
任務原則:根據使用者的請求,選擇最合適的工具來處理,當【資訊不足】時,持續追問直到可以完成請求為止,可以使用使用者原話重述與確認(小結),避免誤會。
任務範圍:
- 會議室預約
- 辦公用品申請
- 訪客通行證申請
工具指引:
- 預約公司會議室 → BookMeetingRoom
- 辦公用品申請 → RequestOfficeSupplies
- 訪客通行證申請 → RequestVisitorPass
嚴格遵守以下規範:
嚴禁自行編造資訊,僅使用已註冊的工具。
嚴禁處理非上述任務外的請求。
請求完成後,回覆僅呈現與本次工具相關的結果與關鍵資訊;不要主動延伸到其他工具。
""",
Kernel = kernel,
Arguments = new(new PromptExecutionSettings
{
// 自動函式選擇
FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
})
};
var agentThread = new ChatHistoryAgentThread();
Console.WriteLine("💬 請輸入您所需要的服務(輸入 exit 結束):");
Console.Write("User > ");
string? userInput;
while ((userInput = Console.ReadLine()) is not null)
{
if (string.IsNullOrWhiteSpace(userInput) ||
userInput.Equals("exit", StringComparison.OrdinalIgnoreCase))
break;
var message = new ChatMessageContent(AuthorRole.User, userInput);
bool first = true;
await foreach (StreamingChatMessageContent resp in agent.InvokeStreamingAsync(message, agentThread))
{
if (first)
{
Console.Write($"{resp.Role} - {resp.AuthorName ?? "*"} > ");
first = false;
}
Console.Write(resp.Content);
}
Console.WriteLine();
Console.WriteLine($"\n# trace chat thread with agent: {agent.Name} - {agent.Description}, threadId: {agentThread.Id}\n");
Console.Write("User > ");
}
現在,已經完成了 OfficePlugin 和 OfficeAgent 的建立,接下來可以執行這個 Agent,並與它進行互動。當使用者輸入他們的需求時,Agent 會根據需求選擇合適的工具來處理,並回覆結果。
User > 我是Ian,幫我訂下週二 10:00–11:00,會議室
Assistant - OfficeOneAgent > 請提供您要預約的會議室編號,才能協助完成預約。
# trace chat thread with agent: OfficeOneAgent - 協助員工以對話方式完成辦公室相關請求的 AI 助理, threadId: 814960cc3e1548f6b544618b262865af
User > A168,專案進度討論
Assistant - OfficeOneAgent > A168會議室已成功預約,時間為2024-06-18(下週二)10:00–11:00,會議主題為「專案進度討論」。預約編號:MTG20250926222002。
# trace chat thread with agent: OfficeOneAgent - 協助員工以對話方式完成辦公室相關請求的 AI 助理, threadId: 814960cc3e1548f6b544618b262865af
User > 申請二張訪客證,今天下午2點到5點,SuperAI公司林先生來訪
Assistant - OfficeOneAgent > 一張訪客通行證已成功申請給 SuperAI 公司林先生,今日下午2點至5點來訪,通行證編號:6387。
如需第二張訪客證,請提供第二位訪客的姓名及相關資訊。
# trace chat thread with agent: OfficeOneAgent - 協助員工以對話方式完成辦公室相關請求的 AI 助理, threadId: c8780a08d3ee4d4287786550af034c99
這篇範例展示了如何使用 Semantic Kernel 建立一個配備多工具的 OfficeOne Agent,這個 Agent 能夠根據使用者的需求動態選擇合適的工具來完成任務。透過清晰的工具描述和自動函式選擇功能,Agent 能夠有效處理各種辦公室相關請求。希望這個範例能夠啟發在實務應用中建立更多有用的 AI 助理!