Jegyzet
Az oldalhoz való hozzáférés engedélyezést igényel. Próbálhatod be jelentkezni vagy könyvtárat váltani.
Az oldalhoz való hozzáférés engedélyezést igényel. Megpróbálhatod a könyvtár váltását.
Ez az oktatóanyag bemutatja a RAG-minta integrációját open AI-modellek és vektorkeresési képességek használatával egy .NET-alkalmazásban. A mintaalkalmazás vektorkereséseket végez a MongoDB-hez készült Azure Cosmos DB-ben tárolt egyéni adatokon, és tovább finomítja a válaszokat generatív AI-modellek, például a GPT-35 és a GPT-4 használatával. Az alábbi szakaszokban beállít egy mintaalkalmazást, és megismeri az ezeket a fogalmakat szemléltető kulcskód-példákat.
Előfeltételek
- .NET 8.0
- Azure-fiók
- Azure Cosmos DB for MongoDB vCore szolgáltatás
-
Azure Open AI-szolgáltatás
- A modell üzembe helyezése
text-embedding-ada-002beágyazások céljára - A
gpt-35-turbomodellt üzembe helyezése csevegés befejezéséhez
- A modell üzembe helyezése
Alkalmazás áttekintése
A Cosmos Receptútmutató alkalmazás lehetővé teszi vektoros és AI-alapú keresések elvégzését receptadatok halmaza alapján. Közvetlenül megkeresheti a rendelkezésre álló recepteket, vagy kérheti, hogy az alkalmazás összetevőnevekkel keresse meg a kapcsolódó recepteket. Az alkalmazás és az előtte álló szakaszok végigvezetik az alábbi munkafolyamaton az ilyen típusú funkciók bemutatásához:
Mintaadatok feltöltése egy MongoDB-adatbázishoz készült Azure Cosmos DB-adatbázisba.
Beágyazásokat és vektorindexet hozhat létre a feltöltött mintaadatokhoz az Azure OpenAI-modell
text-embedding-ada-002használatával.A felhasználói kérések alapján végezzen vektoros hasonlósági keresést.
Az Azure OpenAI-kiegészítési
gpt-35-turbomodell használatával értelmesebb válaszokat írhat a keresési eredmények adatai alapján.
Első lépések
Klónozza a következő GitHub-adattárat:
git clone https://github.com/microsoft/AzureDataRetrievalAugmentedGenerationSamples.gitA C#/CosmosDB-MongoDBvCore mappában nyissa meg a CosmosRecipeGuide.sln fájlt.
A appsettings.json fájlban cserélje le a következő konfigurációs értékeket az Azure OpenAI és az Azure CosmosDB for MongoDb értékekre:
"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>"Indítsa el az alkalmazást a Visual Studio tetején található Start gombra kattintva.
Az alkalmazás felfedezése
Amikor első alkalommal futtatja az alkalmazást, az csatlakozik az Azure Cosmos DB-hez, és arról számol be, hogy még nem állnak rendelkezésre receptek. Az alapvető munkafolyamat elindításához kövesse az alkalmazás által megjelenített lépéseket.
Válassza a Recept feltöltése a Cosmos DB-be lehetőséget, és nyomja le az Enter billentyűt. Ez a parancs beolvassa a minta JSON-fájlokat a helyi projektből, és feltölti őket a Cosmos DB-fiókba.
A Utility.cs osztály kódja elemzi a helyi JSON-fájlokat.
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; }A
UpsertVectorAsyncVCoreMongoService.cs fájl metódusa feltölti a dokumentumokat a MongoDB-hez készült Azure Cosmos DB-be.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; } }Válassza a Receptek vektorizálása lehetőséget, és tárolja a Cosmos DB-ben.
A Cosmos DB-be feltöltött JSON-elemek nem tartalmaznak beágyazásokat, ezért nem optimalizálhatók RAG-ra vektorkereséssel. A beágyazás egy szöveg szemantikai jelentésének információdús, numerikus ábrázolása. A vektorkeresések környezetfüggően hasonló beágyazású elemeket találnak.
A
GetEmbeddingsAsyncOpenAIService.cs fájlban lévő metódus beágyazást hoz létre az adatbázis minden eleméhez.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; } }A
CreateVectorIndexIfNotExistsVCoreMongoService.cs fájlban létrehoz egy vektorindexet, amely lehetővé teszi a vektorok hasonlósági keresését.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; } }Felhasználói lekérdezés futtatásához válassza az Ask AI Assistant (recept keresése név vagy leírás alapján, vagy kérdés feltevése) lehetőséget az alkalmazásban.
A felhasználói lekérdezés beágyazássá alakul az Open AI szolgáltatás és a beágyazási modell használatával. A beágyazást ezután a rendszer elküldi a MongoDB-hez készült Azure Cosmos DB-nek, és vektorkeresés végrehajtására szolgál. A
VectorSearchAsyncVCoreMongoService.cs fájl metódusa vektorkeresést végez a megadott vektorhoz közeli vektorok kereséséhez, és visszaadja a MongoDB virtuális maghoz készült Azure Cosmos DB-ből származó dokumentumok listáját.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; } }A
GetChatCompletionAsyncmetódus továbbfejlesztett csevegés-befejezési választ hoz létre a felhasználói kérés és a kapcsolódó vektorkeresési eredmények alapján.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; } }Az alkalmazás emellett parancssori fejlesztéssel biztosítja az Open AI szolgáltatás korlátait, és formázni fogja a megadott receptekre adott választ.
//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.";