經過了前幾天的開胃菜,我們已經成功地把頂級廚房建立起來,也讓我們的 Semantic Kernel (SK) 大廚說出了第一句話。但是,如果我們的大廚跟金魚一樣只有七秒的記憶,那這頓「AI 全餐」恐怕會吃得相當辛苦。
想像一下,你走進一家高級餐廳,服務生親切地問候你。
你:「你好,我想要一份菲力牛排。」
服務生:「好的,一份菲力牛排。」(服務生轉身,又轉回來)
服務生: 「您好,請問需要什麼服務?」
你:「...我剛剛不是點了嗎?」
服務生:「不好意思,請問您是誰?」
這也太讓人崩潰了吧!一個好的服務生,絕對會記得客人的喜好和剛剛的對話。同樣地,一個聰明的 AI 應用,也必須要有「記憶」,才能提供有溫度、有連貫性的服務。
今天,我們就要來介紹 AI 的記憶本——ChatHistory
!
ChatHistory
在 Semantic Kernel 的世界裡,ChatHistory
物件就是那位服務生的神奇筆記本,它負責記錄下顧客(使用者)與廚師(AI)之間的每一句對話。少了它,每一輪的互動都是一次全新的開始,AI 無法理解上下文,自然也無法提供真正有幫助的回應。
ChatHistory
本質上是一個列表(List
),專門用來存放 ChatMessageContent
物件,讓新增和管理對話紀錄變得非常簡單 。
在我們的對話紀錄中,不是只有你一言我一語,還需要區分是誰說了什麼話。
ChatHistory
定義了幾種不同的角色(AuthorRole
),讓我們的筆記本更加清晰 :
讓我們來看看怎麼把這些對話加進 ChatHistory
裡:
using Microsoft.SemanticKernel.ChatCompletion;
// 建立一個新的對話紀錄
ChatHistory chatHistory = [];
// 1. 加入系統訊息,為 AI 設定角色
chatHistory.AddSystemMessage("你是一位樂於助人的餐廳點餐助理。");
// 2. 加入使用者的問題
chatHistory.AddUserMessage("菜單上有什麼推薦的嗎?");
// 3. 加入 AI 的回覆
chatHistory.AddAssistantMessage("我們有披薩、義大利麵和沙拉。請問您想點什麼呢?");
// 4. 使用者繼續對話
chatHistory.AddUserMessage("我想要第一個選項,謝謝。");
程式碼範例改寫自
就是這麼簡單!當你把這個 chatHistory
物件傳遞給 AI 服務時,它就能看到完整的對話歷史,並理解「第一個選項」指的就是「披薩」。這就是上下文連貫性的魔力!
有時候,我們不希望浪費時間讓 AI 去問一些我們已經知道的資訊。例如,在點餐系統中,我們可能已經透過登入系統知道了顧客的過敏原。這時候,我們可以在 AI 還沒開口問之前,就主動把這些資訊「塞」進對話紀錄裡,引導 AI 做出更精準的回應。
這就像是服務生在把訂單交給廚師前,先在筆記本上加註:「注意!此顧客對花生和麩質過敏!」
我們可以使用
FunctionCallContent
和 FunctionResultContent
來手動模擬這個過程 。
FunctionCallContent
:模擬 AI 決定要去呼叫某個工具。FunctionResultContent
:模擬工具回傳的結果。讓我們看看如何手動將「查詢使用者過敏原」這個動作加入歷史紀錄中:
// 模擬 AI 助理決定呼叫工具來查詢過敏原
chatHistory.Add(
new() {
Role = AuthorRole.Assistant,
Items = [
new FunctionCallContent(
functionName: "get_user_allergies",
pluginName: "UserPlugin",
callId: "call_001" // 這個 id 很重要,用來配對結果
)
]
}
);
// 模擬工具回傳了查詢結果
chatHistory.Add(
new() {
Role = AuthorRole.Tool,
Items = [
new FunctionResultContent(
functionName: "get_user_allergies",
pluginName: "UserPlugin",
callId: "call_001", // 必須和 FunctionCallContent 的 id 相對應
result: "{ \"allergies\": [\"peanuts\", \"gluten\"] }"
)
]
}
);
程式碼範例改寫自
透過這段「預寫」的對話,當使用者點了含有花生的餐點時,AI 就會立刻知道並提醒:「先生,這道菜含有花生,根據您的過敏紀錄,建議您更換餐點。」是不是非常貼心?這項技巧對於在對話中注入重要的外部資訊特別有用,能讓 AI 的反應更即時、更個人化 。
今天我們學會了如何使用 ChatHistory
這個強大的記憶工具,讓我們的 AI 應用從一個健忘的服務生,蛻變成一位能記住顧客大小事的貼心管家。透過記錄不同角色的訊息,並善用模擬函式呼叫的技巧,我們能打造出更有溫度、更懂人心的對話體驗。
有了記憶,我們的大廚才算是真正準備好了。明天,我們將端上這場 AI 滿漢全席的重頭戲之一:Function Calling
!我們將會看到,這位擁有記憶的大廚,是如何真正「動」起來,開始使用他的刀具(Plugins)來為我們料理真正的美味佳餚!敬請期待!