Azure AI Search RAG 實作

Ian Chen
playtech
Published in
7 min readMar 4, 2024

--

上一篇提到使用 Azure AI Search 做為知識庫的向量儲存庫,本篇延續這個主題,搭配Microsoft.KernelMemory.Core進行一個簡單基於RAG概念的LLM知識庫應用POC實作。

RAG概念

檢索增強生成(Retrieval-Augmented Generation, RAG),是一種結合了『檢索Retrieval』及『生成Generation』能力的框架,透過從背景資料中檢索相關資訊來增強模型的生成輸出。在目前的大型語言模型(LLM)技術中,一個明顯的限制是模型無法即時更新其訓練資料集,這導致了兩個主要問題需要被關注:一是新知識的獲取;二是降低生成幻覺(hallucination)的現象。為了解決這些問題,目前普遍採取兩種方式:微調(fine-tuning)和檢索增強生成(Retrieval-Augmented Generation, RAG)。其中RAG的做法,具有成本較低、前置作業較容易,成效不錯等優勢,因此目前比較主流被採用的方式。在RAG的架構中,首要面臨的挑戰是確保檢索到的參考資料具備足夠的參考價值。而解決此問題的關鍵技術是「向量嵌入(Vector Embedding)」與「向量資料庫(Vector Database)」,簡單來說就是將提問轉化為向量後,透過相似度搜尋技術,在向量資料庫中尋找與問題向量相似的資料向量,藉以找出可能的解答。以下二張圖描述了RAG架構中的作業流程及概念。

Microsoft.KernelMemory.Core實作RAG

Microsoft.KernelMemory.Core,源自於原本SemanticKernel Memory的經驗,現在做為一個獨立發展的項目,並且支援更多的資料來源格式,例如pdf,image….,整合一些常見的向量資料庫並且更重要的是實作RAG所需的一切包含Prompt的組合。Microsoft.KernelMemory.Core以及 Azure AI Search做為向量資料庫及向量搜尋,具備實作RAG所需元素。整個實作不到50行C#程式碼就能完成,非常的驚人。

Step 1 : 安裝Microsoft.KernelMemory.Core套件(NuGet Gallery | Microsoft.KernelMemory.Core 0.30.240227.1

Step 2 : 建立Azure OpenAI Service並部署embedding模型及TextGeneration模型,例如:text-embedding-ada-002(目前最新模型是text-embedding-3-large)+gpt-4模型。

Step 3 : 建立Azure AI Search服務並取得API_KEY及Endpoint,知識庫文件不需先匯入,待會由程式直接匯入。

Step 4 : 建立KernelMemory物件,並配置連接Azure OpenAI模型以及Azure AI Search。其中embedding模型用於轉化向量值,text-embedding-ada-002的空間維度是1536維。TextGeneration模型則用於做生成回答。

//Chat Model Config
var aoaiChatConfig = new AzureOpenAIConfig
{
APIKey = api_Key,
Deployment = deploy_Name,
Endpoint = aoai_Endpoint,
APIType = AzureOpenAIConfig.APITypes.ChatCompletion,
Auth = AzureOpenAIConfig.AuthTypes.APIKey
};

//Embedding Model Config
var aoaiEmbeddingConfig = new AzureOpenAIConfig
{
APIKey = api_Key,
Deployment = deploy_embedding_Name,
Endpoint = aoai_Endpoint,
APIType = AzureOpenAIConfig.APITypes.ChatCompletion,
Auth = AzureOpenAIConfig.AuthTypes.APIKey
};

var kernelMemory = new KernelMemoryBuilder()
.WithAzureOpenAITextGeneration(aoaiChatConfig)
.WithAzureOpenAITextEmbeddingGeneration(aoaiEmbeddingConfig)
.WithAzureAISearchMemoryDb(search_Endpoint, search_ApiKey)
.Build<MemoryServerless>();

Step 5 : 將知識庫文件轉向量儲存於Azure AI Search服務,並且建立index。這個步驟只需要執行一次。一般是分成2個獨立專案進行,1個是LLM應用,而另1個則是Azure AI Search服務維運。

await ImportKm(kernelMemory);

static async Task ImportKm(MemoryServerless memory)
{
await memory.ImportDocumentAsync(Path.Combine(Directory.GetCurrentDirectory(), "公寓大廈管理條例.pdf"), documentId: "公寓大廈管理條例", index: "kmindex");
}

Step 6 : 進行提問對話。kernelMemory.AskAsync傳入問題以及設定關係性係數。

while (true)
{
Console.Write("Input Question: ");
var question = Console.ReadLine();

//AskAsync是經過參考向量檢索資料後,再做文本生成的結果,簡單來說就是答案
var ans = await kernelMemory.AskAsync(question, minRelevance: 0.8f);
Console.WriteLine($"Answer: {ans.Result} \n\n");
}

Step 7 : POC結果。本例以"公寓大廈管理條例"做為示範。

整個範例程式約50行,簡單精簡就能實現RAG架構的LLM應用,在這個範例中使用的是Microsoft.KernelMemory.Core而不是Semantic Kernel,如果你的應用中只是單純想要進行知識庫的問答,那麼Microsoft.KernelMemory.Core就能滿足所需,但如果你的LLM應用還有其它功能性,那麼可以使用Microsoft.KernelMemory.SemanticKernelPlugin會比較合適,將KernelMemory視為Semantic Kernel的Plugin,下一篇文章我將會示範如何使用它。

--

--

Ian Chen
playtech

Microsoft MVP / Microsoft Certified Trainer(MCT)