Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Tutorial ini mengeksplorasi integrasi pola RAG menggunakan model Open AI dan kemampuan pencarian vektor di aplikasi .NET. Aplikasi sampel melakukan pencarian vektor pada data kustom yang disimpan di Azure Cosmos DB untuk MongoDB dan lebih menyempurnakan respons menggunakan model AI generatif, seperti GPT-35 dan GPT-4. Di bagian berikut, Anda akan menyiapkan aplikasi sampel dan menjelajahi contoh kode kunci yang menunjukkan konsep ini.
Prasyarat
- .NET 8.0
- Akun Azure
- Layanan Azure Cosmos DB untuk MongoDB vCore
- Layanan Azure Open AI
- Menerapkan
text-embedding-ada-002model untuk fitur penyematan - Menerapkan model
gpt-35-turbountuk melengkapi obrolan
- Menerapkan
Gambaran umum aplikasi
Aplikasi Cosmos Recipe Guide memungkinkan Anda melakukan pencarian yang didorong vektor dan AI terhadap sekumpulan data resep. Anda dapat mencari resep yang tersedia secara langsung atau meminta aplikasi dengan nama bahan untuk menemukan resep terkait. Aplikasi dan bagian di depan memandu Anda melalui alur kerja berikut untuk menunjukkan jenis fungsionalitas ini:
Unggah data sampel ke database Azure Cosmos DB for MongoDB.
Buat penyematan dan indeks vektor untuk data sampel yang diunggah menggunakan model Azure OpenAI
text-embedding-ada-002.Lakukan pencarian kesamaan vektor berdasarkan perintah pengguna.
Gunakan model penyelesaian Azure OpenAI
gpt-35-turbountuk menyusun jawaban yang lebih bermakna berdasarkan data hasil pencarian.
Get started
Kloning repositori GitHub berikut:
git clone https://github.com/microsoft/AzureDataRetrievalAugmentedGenerationSamples.gitDi folder C#/CosmosDB-MongoDBvCore , buka file CosmosRecipeGuide.sln .
Dalam file appsettings.json , ganti nilai konfigurasi berikut dengan nilai Azure OpenAI dan Azure CosmosDB untuk MongoDb Anda:
"OpenAIEndpoint": "https://<your-service-name>.openai.azure.com/", "OpenAIKey": "<your-API-key>", "OpenAIEmbeddingDeployment": "<your-ADA-deployment-name>", "OpenAIcompletionsDeployment": "<your-GPT-deployment-name>", "MongoVcoreConnection": "<your-Mongo-connection-string>"Luncurkan aplikasi dengan menekan tombol Mulai di bagian atas Visual Studio.
Menjelajahi aplikasi
Saat Anda menjalankan aplikasi untuk pertama kalinya, aplikasi terhubung ke Azure Cosmos DB dan melaporkan bahwa belum ada resep yang tersedia. Ikuti langkah-langkah yang ditampilkan oleh aplikasi untuk memulai alur kerja inti.
Pilih Unggah resep ke Cosmos DB dan tekan Enter. Perintah ini membaca sampel file JSON dari proyek lokal dan mengunggahnya ke akun Cosmos DB.
Kode dari kelas Utility.cs mengurai file JSON lokal.
public static List<Recipe> ParseDocuments(string Folderpath) { List<Recipe> recipes = new List<Recipe>(); Directory.GetFiles(Folderpath) .ToList() .ForEach(f => { var jsonString= System.IO.File.ReadAllText(f); Recipe recipe = JsonConvert.DeserializeObject<Recipe>(jsonString); recipe.id = recipe.name.ToLower().Replace(" ", ""); recipes.Add(recipe); } ); return recipes; }Metode
UpsertVectorAsyncdalam file VCoreMongoService.cs mengunggah dokumen ke Azure Cosmos DB untuk MongoDB.public async Task UpsertVectorAsync(Recipe recipe) { BsonDocument document = recipe.ToBsonDocument(); if (!document.Contains("_id")) { Console.WriteLine("UpsertVectorAsync: Document does not contain _id."); throw new ArgumentException("UpsertVectorAsync: Document does not contain _id."); } string? _idValue = document["_id"].ToString(); try { var filter = Builders<BsonDocument>.Filter.Eq("_id", _idValue); var options = new ReplaceOptions { IsUpsert = true }; await _recipeCollection.ReplaceOneAsync(filter, document, options); } catch (Exception ex) { Console.WriteLine($"Exception: UpsertVectorAsync(): {ex.Message}"); throw; } }Pilih Vektorisasi resep dan simpan di Cosmos DB.
Item JSON yang diunggah ke Cosmos DB tidak berisi penyematan dan oleh karena itu tidak dioptimalkan untuk RAG melalui pencarian vektor. Penyematan adalah representasi numerik yang padat informasi dari arti semantik dari sepotong teks. Pencarian vektor dapat menemukan item dengan penyematan serupa secara kontekstual.
Metode
GetEmbeddingsAsyncdalam file OpenAIService.cs membuat penyematan untuk setiap item dalam database.public async Task<float[]?> GetEmbeddingsAsync(dynamic data) { try { EmbeddingsOptions options = new EmbeddingsOptions(data) { Input = data }; var response = await _openAIClient.GetEmbeddingsAsync(openAIEmbeddingDeployment, options); Embeddings embeddings = response.Value; float[] embedding = embeddings.Data[0].Embedding.ToArray(); return embedding; } catch (Exception ex) { Console.WriteLine($"GetEmbeddingsAsync Exception: {ex.Message}"); return null; } }dalam
CreateVectorIndexIfNotExistsfile VCoreMongoService.cs membuat indeks vektor, yang memungkinkan Anda melakukan pencarian kesamaan vektor.public void CreateVectorIndexIfNotExists(string vectorIndexName) { try { //Find if vector index exists in vectors collection using (IAsyncCursor<BsonDocument> indexCursor = _recipeCollection.Indexes.List()) { bool vectorIndexExists = indexCursor.ToList().Any(x => x["name"] == vectorIndexName); if (!vectorIndexExists) { BsonDocumentCommand<BsonDocument> command = new BsonDocumentCommand<BsonDocument>( BsonDocument.Parse(@" { createIndexes: 'Recipe', indexes: [{ name: 'vectorSearchIndex', key: { embedding: 'cosmosSearch' }, cosmosSearchOptions: { kind: 'vector-ivf', numLists: 5, similarity: 'COS', dimensions: 1536 } }] }")); BsonDocument result = _database.RunCommand(command); if (result["ok"] != 1) { Console.WriteLine("CreateIndex failed with response: " + result.ToJson()); } } } } catch (MongoException ex) { Console.WriteLine("MongoDbService InitializeVectorIndex: " + ex.Message); throw; } }Pilih opsi Minta Asisten AI (cari resep berdasarkan nama atau deskripsi, atau ajukan pertanyaan) di aplikasi untuk menjalankan kueri pengguna.
Kueri pengguna dikonversi ke penyematan menggunakan layanan Open AI dan model penyematan. Penyematan kemudian dikirim ke Azure Cosmos DB untuk MongoDB dan digunakan untuk melakukan pencarian vektor. Metode
VectorSearchAsyncdalam file VCoreMongoService.cs melakukan pencarian vektor untuk menemukan vektor yang dekat dengan vektor yang disediakan dan mengembalikan daftar dokumen dari Azure Cosmos DB untuk MongoDB vCore.public async Task<List<Recipe>> VectorSearchAsync(float[] queryVector) { List<string> retDocs = new List<string>(); string resultDocuments = string.Empty; try { //Search Azure Cosmos DB for MongoDB vCore collection for similar embeddings //Project the fields that are needed BsonDocument[] pipeline = new BsonDocument[] { BsonDocument.Parse( @$"{{$search: {{ cosmosSearch: {{ vector: [{string.Join(',', queryVector)}], path: 'embedding', k: {_maxVectorSearchResults}}}, returnStoredSource:true }} }}"), BsonDocument.Parse($"{{$project: {{embedding: 0}}}}"), }; var bsonDocuments = await _recipeCollection .Aggregate<BsonDocument>(pipeline).ToListAsync(); var recipes = bsonDocuments .ToList() .ConvertAll(bsonDocument => BsonSerializer.Deserialize<Recipe>(bsonDocument)); return recipes; } catch (MongoException ex) { Console.WriteLine($"Exception: VectorSearchAsync(): {ex.Message}"); throw; } }Metode ini
GetChatCompletionAsyncmenghasilkan respons penyelesaian obrolan yang ditingkatkan berdasarkan permintaan pengguna dan hasil pencarian vektor terkait.public async Task<(string response, int promptTokens, int responseTokens)> GetChatCompletionAsync(string userPrompt, string documents) { try { ChatMessage systemMessage = new ChatMessage( ChatRole.System, _systemPromptRecipeAssistant + documents); ChatMessage userMessage = new ChatMessage( ChatRole.User, userPrompt); ChatCompletionsOptions options = new() { Messages = { systemMessage, userMessage }, MaxTokens = openAIMaxTokens, Temperature = 0.5f, //0.3f, NucleusSamplingFactor = 0.95f, FrequencyPenalty = 0, PresencePenalty = 0 }; Azure.Response<ChatCompletions> completionsResponse = await openAIClient.GetChatCompletionsAsync(openAICompletionDeployment, options); ChatCompletions completions = completionsResponse.Value; return ( response: completions.Choices[0].Message.Content, promptTokens: completions.Usage.PromptTokens, responseTokens: completions.Usage.CompletionTokens ); } catch (Exception ex) { string message = $"OpenAIService.GetChatCompletionAsync(): {ex.Message}"; Console.WriteLine(message); throw; } }Aplikasi ini juga menggunakan rekayasa cepat untuk memastikan batas layanan dari Open AI dan memformat respons sesuai dengan resep yang disediakan.
//System prompts to send with user prompts to instruct the model for chat session private readonly string _systemPromptRecipeAssistant = @" You are an intelligent assistant for Contoso Recipes. You are designed to provide helpful answers to user questions about recipes, cooking instructions provided in JSON format below. Instructions: - Only answer questions related to the recipe provided below. - Don't reference any recipe not provided below. - If you're unsure of an answer, say ""I don't know"" and recommend users search themselves. - Your response should be complete. - List the Name of the Recipe at the start of your response followed by step by step cooking instructions. - Assume the user is not an expert in cooking. - Format the content so that it can be printed to the Command Line console. - In case there is more than one recipe you find, let the user pick the most appropriate recipe.";