Пример семантического ядра Azure с внедрениями и сосновой шишкой

Microsoft недавно выпустила семантическое ядро ​​в Azure. Это механизм на базе Azure OpenAI API, аналогичный LangChain, но как на C#, так и на Python. Там есть куча примеров, и я пытаюсь запустить Пример38 в своем проекте. В частности, этот код:

      public static async Task RunAsync()
{
    using (Log.VerboseCall())
    {
        string apiKey = "...xxxxxxxxxxxxxxxxxxx...";  // I got this from Pinecone
        string pineconeEnvironment = "us-west1-gcp-free"; // I got this from Pinecone

        string openAiKey = "...xxxxxxxxxxxxxxxxxxxxx..."; // I got this from OpenAI

        PineconeMemoryStore memoryStore = new(pineconeEnvironment, apiKey);
        IKernel kernel = Kernel.Builder
            .WithOpenAITextCompletionService("text-davinci-003", openAiKey)
            .WithOpenAITextEmbeddingGenerationService("text-embedding-ada-002", openAiKey)
            .WithMemoryStorage(memoryStore)
            .Build();


        Console.WriteLine("== Printing Collections in DB ==");

        IAsyncEnumerable<string> collections = memoryStore.GetCollectionsAsync();

        await foreach (string collection in collections)
        {
            Console.WriteLine(collection);
        }

        Console.WriteLine("== Adding Memories ==");

        Dictionary<string, object> metadata = new()
        {
            { "type", "text" },
            { "tags", new List<string>() { "memory", "cats" } }
        };

        string additionalMetadata = System.Text.Json.JsonSerializer.Serialize(metadata);

        try
        {
            // !!! This line throws exception - see below. !!!
            string key1 = await kernel.Memory.SaveInformationAsync(MemoryCollectionName, "british short hair", "cat1", null, additionalMetadata);
            string key2 = await kernel.Memory.SaveInformationAsync(MemoryCollectionName, "orange tabby", "cat2", null, additionalMetadata);
            string key3 = await kernel.Memory.SaveInformationAsync(MemoryCollectionName, "norwegian forest cat", "cat3", null, additionalMetadata);

            Console.WriteLine("== Retrieving Memories Through the Kernel ==");
            MemoryQueryResult? lookup = await kernel.Memory.GetAsync(MemoryCollectionName, "cat1");
            Console.WriteLine(lookup != null ? lookup.Metadata.Text : "ERROR: memory not found");

            Console.WriteLine("== Retrieving Memories Directly From the Store ==");
            var memory1 = await memoryStore.GetAsync(MemoryCollectionName, key1);
            var memory2 = await memoryStore.GetAsync(MemoryCollectionName, key2);
            var memory3 = await memoryStore.GetAsync(MemoryCollectionName, key3);

            Console.WriteLine(memory1 != null ? memory1.Metadata.Text : "ERROR: memory not found");
            Console.WriteLine(memory2 != null ? memory2.Metadata.Text : "ERROR: memory not found");
            Console.WriteLine(memory3 != null ? memory3.Metadata.Text : "ERROR: memory not found");

            Console.WriteLine("== Similarity Searching Memories: My favorite color is orange ==");
            IAsyncEnumerable<MemoryQueryResult> searchResults = kernel.Memory.SearchAsync(MemoryCollectionName, "My favorite color is orange", 1, 0.8);

            await foreach (MemoryQueryResult item in searchResults)
            {
                Console.WriteLine(item.Metadata.Text + " : " + item.Relevance);
            }
        }
        catch (Exception ex)
        {
            Log.Verbose(ex);
        }
    }
}

Я получаю следующее исключение в указанной строке:

Создание индекса не поддерживается в хранилище памяти. Его следует создать вручную или с помощью CreateIndexAsync. Убедитесь, что индекс находится в состоянии «Готов».

2 ответа

В текущей конструкции памяти SK предполагается, что создание векторного индекса является быстрой операцией, занимающей от миллисекунд до нескольких секунд (аналогично Azure Search и Qdrant). Однако после интеграции Pinecone выяснилось, что создание индекса занимает значительно больше времени, иногда на это уходит несколько минут. Это требует опроса API, чтобы проверить, готов ли индекс, что приводит к неожиданным тайм-аутам в приложениях, предназначенных для создания индексов «на лету» (например, пример 38).

В качестве обходного пути интеграция Pinecone в SK в настоящее время требует от разработчиков приложений создавать индексы вручную либо через портал, либо с помощьюMicrosoft.SemanticKernel.Connectors.Memory.Pinecone.PineconeClient.CreateIndexAsync(). Это позволяет избежать необходимости ставить операцию в очередь и ждать в течение длительного периода времени при опросе службы.

Потенциальным улучшением может быть добавление комментария в примере 38, поясняющего это поведение, или предоставление возможности переопределить поведение по умолчанию и разрешить ожидание. Это было бы ценным усовершенствованием для тех, кто заинтересован в его реализации.

Я также провожу тесты по интеграции Pinecone с SK. На линии:

      string key1 = await kernel.Memory.SaveInformationAsync(MemoryCollectionName, "british short hair", "cat1", null, additionalMetadata);

Я попытался поместить имя индекса в первый параметр, и у меня это сработало.

Когда вы ссылаетесь на пример 38, где эти примеры?

Другие вопросы по тегам