經過前面幾天的美食洗禮,大家是不是都覺得 AI 廚師很厲害了呢?但你有沒有想過,就算是最頂尖的廚師,如果給他的食材只有空氣,他能變出什麼樣的菜色呢?
這就是我們今天要探討的大問題。儘管大型語言模型(LLM)擁有龐大的通用知識,但它們的知識庫並非無限,更無法隨時更新。當你問它「我們公司上個月的財報如何?」或「我那份 500 頁的合約有什麼重點?」時,它肯定會一臉茫然,因為這些知識並不在它的「通用食譜」裡。
這時候,我們就需要一個能夠為 AI 補充外部知識的超級湯底,這就是 檢索增強生成 (Retrieval-Augmented Generation, RAG) 的核心概念。簡單來說,RAG 就是讓 AI 在回答問題前,先去外部的知識庫撈取相關資訊,然後再結合這些資訊與自身的生成能力,給出一個精準且有根據的答案。而我們的「湯底」呢,就是今天的主角:向量儲存庫 (Vector Stores)。
你可以把向量儲存庫想像成一個特殊的圖書館。一般的圖書館是按照書名、作者或主題來分類,但這個圖書館是根據「語意」來分類。每當你放入一本書(或一段文字),這個圖書館會請一個神奇的「語意師」(也就是嵌入模型, Embedding Model)將這段文字的「意義」轉換成一串數字,這串數字我們稱為向量 (Vector)。
這些向量有個超能力:意義相近的文字,它們的向量距離就會很近。當你提出一個問題時,語意師會先把你的問題也變成一個向量,然後在圖書館裡迅速找到那些向量距離最近的「書」,也就是與你問題最相關的資訊。接著,這些資訊就會被送給 AI 廚師,讓他能根據這些「新鮮食材」來回答你的問題。
在 Semantic Kernel 中,我們可以使用特定的屬性來定義我們的資料模型,告訴向量儲存庫如何儲存我們的資料。這就像在料理前,先為食材分門別類,準備好合適的容器。
我們需要用到以下幾個重要的屬性:
[VectorStoreKey]
:標記作為唯一識別碼的屬性,就像每本書的 ISBN。[VectorStoreData]
:標記要被轉換成向量的屬性,也就是我們的「湯底」原料。[VectorStoreVector]
:這個屬性會自動儲存轉換後的向量,你不需要自己處理。讓我們以一個簡單的食譜資料庫為例:
using Microsoft.SemanticKernel.Memory;
public class Recipe
{
[VectorStoreKey]
public string Name { get; set; } = string.Empty;
public string Type { get; set; } = string.Empty;
public string Cuisine { get; set; } = string.Empty;
[VectorStoreData]
public string Description { get; set; } = string.Empty;
[VectorStoreVector(1536)]
public ReadOnlyMemory<float> DescriptionVector { get; set; }
}
在這個範例中,Name
作為唯一識別碼,Description
則是要被向量化的內容。DescriptionVector
則會自動儲存其向量。
定義好資料模型後,我們需要選擇一個容器來存放這些資料。Semantic Kernel 提供了多種選擇,最簡單的就是 InMemoryVectorStore
,適合快速測試和輕量級應用。
var embeddingGenerator = new OpenAIClient(config["OpenAI:ApiKey"]!)
.GetEmbeddingClient("text-embedding-ada-002")
.AsIEmbeddingGenerator();
var vectorStore = new InMemoryVectorStore(new() { EmbeddingGenerator = embeddingGenerator });
今天,我們打下了 RAG 的堅實基礎,準備好了最棒的湯底。明天,我們將會學會如何將這些食材(資料)注入到湯底中,並學會如何「撈料」,讓 AI 廚師能精準地找到它想要的資訊。準備好你的湯勺,明天見!