Краткое руководство. Чат с моделями Azure OpenAI с помощью собственных данных

Примеры пакета исходного кода | ( | pypi) |

Приведенные выше ссылки ссылаются на API OpenAI для Python. Пакет SDK Для OpenAI для OpenAI отсутствует. Узнайте, как переключаться между службами OpenAI и службами Azure OpenAI.

В этом кратком руководстве вы можете использовать собственные данные с моделями Azure OpenAI. С помощью моделей Azure OpenAI в данных можно использовать мощную платформу ИИ для общения, которая обеспечивает более высокую и точную связь.

Необходимые компоненты

  • Подписка Azure — создайте бесплатную учетную запись.

  • Службе Azure OpenAI предоставлен доступ в требуемой подписке Azure

    Для Azure OpenAI требуется регистрация и в настоящее время доступна только утвержденным корпоративным клиентам и партнерам. Дополнительные сведения см. в статье Об ограниченном доступе к службе Azure OpenAI. Вы можете подать заявку на доступ к Azure OpenAI, выполнив форму по адресу https://aka.ms/oai/access. Если у вас возникли проблемы, создайте соответствующий запрос в этом репозитории, чтобы связаться с нами.

  • Ресурс Azure OpenAI, развернутый в поддерживаемом регионе с поддерживаемой моделью.

  • Убедитесь, что вы назначаете по крайней мере роль участника Cognitive Services для ресурса Azure OpenAI.

  • Скачайте примеры данных из GitHub , если у вас нет собственных данных.

Добавление данных с помощью Azure OpenAI Studio

Совет

Вы можете использовать интерфейс командной строки разработчика Azure для программного создания ресурсов, необходимых для Azure OpenAI в данных

Перейдите в Azure OpenAI Studio и войдите с учетными данными, имеющими доступ к ресурсу Azure OpenAI. Во время или после рабочего процесса входа выберите соответствующий каталог, подписку Azure и ресурс Azure OpenAI.

  1. Выберите плитку "Принести собственные данные "

    Снимок экрана: целевая страница Azure OpenAI Studio.

  2. В появившейся области выберите " Отправить файлы (предварительная версия) в разделе "Выбор источника данных". Azure OpenAI требует как ресурса хранилища, так и ресурса поиска для доступа к вашим данным и их индексации.

    Совет

    1. Для доступа к учетной записи хранения Azure OpenAI необходимо включить общий доступ к ресурсам между источниками (CORS). Если CORS еще не включен для ресурса Хранилище BLOB-объектов Azure, нажмите кнопку "Включить CORS".

    2. Выберите ресурс поиска ИИ Azure и выберите подтверждение, что подключение к нему приведет к использованию вашей учетной записи. Затем выберите Далее.

    Снимок экрана: параметры выбора источника данных в Azure OpenAI Studio.

  3. На панели "Отправить файлы" выберите "Обзор файла" и выберите файлы, скачанные из раздела предварительных требований, или собственные данные. Затем выберите " Отправить файлы". Затем выберите Далее.

  4. В области управления данными можно выбрать, следует ли включить семантический поиск или векторный поиск индекса.

    Внимание

    • Семантический поиск и векторный поиск подвергаются дополнительным ценам. Чтобы включить семантический поиск или векторный поиск, необходимо выбрать базовый или более высокий номер SKU . Дополнительные сведения см . в разделе "Разница в ценовой категории" и ограничения служб.
    • Чтобы повысить качество получения информации и ответа модели, рекомендуется включить семантический поиск на следующих языках источника данных: английский, французский, испанский, португальский, итальянский, итальянский, китайский(zh), японский, корейский, русский и арабский.
  5. Просмотрите введенные сведения и нажмите кнопку "Сохранить и закрыть". Теперь вы можете общаться с моделью и использовать информацию из данных для создания ответа.

Детская площадка чата

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

Снимок экрана: страница тестовой площадки Azure OpenAI Studio с выделенными разделами.

На детской площадке вы можете настроить взаимодействие с чатом. Справа можно выбрать развертывание , чтобы определить, какая модель создает ответ с помощью результатов поиска из индекса. Вы выбираете количество прошлых сообщений, включаемых в журнал бесед для будущих созданных ответов. Журнал бесед дает контекст для создания связанных ответов, но также использует использование маркеров. Индикатор хода выполнения входного маркера отслеживает количество маркеров, которые вы отправляете.

Дополнительные параметры слева — это параметры среды выполнения, которые позволяют управлять получением и поиском соответствующих сведений из данных. Хороший вариант использования заключается в том, что вы хотите убедиться, что ответы создаются только на основе данных, или модель не может создать ответ на основе существующих сведений о данных.

  • Строгость определяет агрессивность системы в фильтрации документов поиска на основе их показателей сходства. Установка строгости 5 указывает на то, что система будет агрессивно фильтровать документы, применяя очень высокий порог сходства. Семантический поиск может быть полезным в этом сценарии, так как модели ранжирования делают лучшее задание вывода намерения запроса. Более подробные ответы создают более подробные ответы на более низкие уровни строгости, но также могут содержать сведения, которые не входят в индекс. По умолчанию это значение равно 3.

  • Извлеченные документы — это целое число, которое можно задать для 3, 5, 10 или 20, а также определяет количество блоков документов, предоставленных большой языковой модели для формирования окончательного ответа. По умолчанию это значение равно 5.

  • Если включено ограничение ответов на данные , модель пытается использовать только документы для ответов. По умолчанию это значение имеет значение true.

Снимок экрана: дополнительные параметры.

Отправьте первый запрос. Модели чата лучше всего работают в упражнениях с вопросом и ответами. Например, "Что такое мои доступные планы здравоохранения?", или "Что такое вариант "Здоровье плюс?".

Запросы, требующие анализа данных, вероятно, завершаются ошибкой, например "Какой план работоспособности наиболее популярен?". Запросы, требующие сведений обо всех ваших данных, также могут завершиться ошибкой, например "Сколько документов я отправил?". Помните, что поисковый механизм ищет фрагменты с точными или похожими терминами, фразами или конструкцией запроса. И хотя модель может понять вопрос, если результаты поиска являются блоками из набора данных, это не правильные сведения для ответа на этот вопрос.

Чаты ограничены количеством документов (фрагментов), возвращенных в ответе (ограничено 3–20 на игровой площадке Azure OpenAI Studio). Как вы можете себе представить, создание вопроса о "всех названиях" требует полного сканирования всего векторного хранилища.

Развертывание модели

Когда вы удовлетворены интерфейсом в Студии Azure OpenAI, вы можете развернуть веб-приложение непосредственно из Студии, нажав кнопку "Развернуть в ".

Снимок экрана: кнопка развертывания модели в Azure OpenAI Studio.

Это дает возможность либо развернуть в автономном веб-приложении, либо copilot в Copilot Studio (предварительная версия), если вы используете собственные данные в модели.

Например, если вы решили развернуть веб-приложение:

При первом развертывании веб-приложения следует выбрать команду "Создать новое веб-приложение". Выберите имя приложения, которое станет частью URL-адреса приложения. Например, https://<appname>.azurewebsites.net.

Выберите подписку, группу ресурсов, расположение и тарифный план для опубликованного приложения. Чтобы обновить существующее приложение, выберите "Опубликовать" в существующем веб-приложении и выберите имя предыдущего приложения в раскрывающемся меню.

Если вы решили развернуть веб-приложение, ознакомьтесь с важными рекомендациями по его использованию.

Получение необходимых переменных

Чтобы успешно выполнить вызов к Azure OpenAI, вам потребуются следующие переменные. В этом кратком руководстве предполагается, что вы отправили данные в учетную запись хранения BLOB-объектов Azure и создали индекс поиска ИИ Azure. См. статью "Добавление данных с помощью Студии искусственного интеллекта Azure"

Имя переменной Значение
AZURE_OPENAI_ENDPOINT Это значение можно найти в разделе "Ключи и конечная точка" при проверке ресурса Azure OpenAI из портал Azure. Кроме того, можно найти значение в представлении кода чата чата>Azure.> Пример конечной точки: https://my-resoruce.openai.azure.com.
AZURE_OPENAI_API_KEY Это значение можно найти в разделе "Ключи управления>ресурсами" и "Конечная точка" при изучении ресурса Azure OpenAI из портал Azure. Вы можете использовать KEY1 или KEY2. Наличие двух ключей позволяет безопасно менять и повторно создавать ключи без прерывания работы службы.
AZURE_OPENAI_DEPLOYMENT_ID Это значение соответствует пользовательскому имени, выбранному для развертывания при развертывании модели. Это значение можно найти в разделе "Развертывания управления>ресурсами" в портал Azure или в разделе "Развертывания управления>" в Студии ИИ Azure.
AZURE_AI_SEARCH_ENDPOINT Это значение можно найти в разделе "Обзор" при изучении ресурса поиска ИИ Azure из портал Azure.
AZURE_AI_SEARCH_API_KEY Это значение можно найти в разделе Параметры> Keys при изучении ресурса поиска ИИ Azure из портал Azure. Вы можете использовать ключ первичного администратора или дополнительный ключ администратора. Наличие двух ключей позволяет безопасно менять и повторно создавать ключи без прерывания работы службы.
AZURE_AI_SEARCH_INDEX Это значение соответствует имени индекса, созданного для хранения данных. Его можно найти в разделе "Обзор" при изучении ресурса поиска ИИ Azure из портал Azure.

Переменные среды

setx AZURE_OPENAI_ENDPOINT REPLACE_WITH_YOUR_AOAI_ENDPOINT_VALUE_HERE
setx AZURE_OPENAI_API_KEY REPLACE_WITH_YOUR_AOAI_KEY_VALUE_HERE
setx AZURE_OPENAI_DEPLOYMENT_ID REPLACE_WITH_YOUR_AOAI_DEPLOYMENT_VALUE_HERE
setx AZURE_AI_SEARCH_ENDPOINT REPLACE_WITH_YOUR_AZURE_SEARCH_RESOURCE_VALUE_HERE
setx AZURE_AI_SEARCH_API_KEY REPLACE_WITH_YOUR_AZURE_SEARCH_RESOURCE_KEY_VALUE_HERE
setx AZURE_AI_SEARCH_INDEX REPLACE_WITH_YOUR_INDEX_NAME_HERE

Создание приложения .NET Core

В окне консоли (cmd, PowerShell или Bash) выполните команду dotnet new, чтобы создать консольное приложение с именем azure-openai-quickstart. Эта команда создает простой проект Hello World с одним исходным файлом C#: Program.cs.

dotnet new console -n azure-openai-quickstart

Измените каталог на созданную папку приложения. Чтобы создать приложение, выполните следующую команду:

dotnet build

Выходные данные сборки не должны содержать предупреждений или ошибок.

...
Build succeeded.
 0 Warning(s)
 0 Error(s)
...

Установите клиентская библиотека OpenAI .NET с помощью следующих компонентов:

dotnet add package Azure.AI.OpenAI --prerelease

В каталоге проекта откройте файл Program.cs и замените его содержимое следующим кодом:

Без потоковой передачи ответов

using Azure;
using Azure.AI.OpenAI;
using System.Text.Json;
using static System.Environment;

string azureOpenAIEndpoint = GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT");
string azureOpenAIKey = GetEnvironmentVariable("AZURE_OPENAI_API_KEY");
string deploymentName = GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_ID");
string searchEndpoint = GetEnvironmentVariable("AZURE_AI_SEARCH_ENDPOINT");
string searchKey = GetEnvironmentVariable("AZURE_AI_SEARCH_API_KEY");
string searchIndex = GetEnvironmentVariable("AZURE_AI_SEARCH_INDEX");


var client = new OpenAIClient(new Uri(azureOpenAIEndpoint), new AzureKeyCredential(azureOpenAIKey));

var chatCompletionsOptions = new ChatCompletionsOptions()
{
    Messages =
    {
        new ChatRequestUserMessage("What are my available health plans?"),
    },
    AzureExtensionsOptions = new AzureChatExtensionsOptions()
    {
        Extensions =
        {
            new AzureCognitiveSearchChatExtensionConfiguration()
            {
                SearchEndpoint = new Uri(searchEndpoint),
                Key = searchKey,
                IndexName = searchIndex,
            },
        }
    },
    DeploymentName = deploymentName
};

Response<ChatCompletions> response = client.GetChatCompletions(chatCompletionsOptions);

ChatResponseMessage responseMessage = response.Value.Choices[0].Message;

Console.WriteLine($"Message from {responseMessage.Role}:");
Console.WriteLine("===");
Console.WriteLine(responseMessage.Content);
Console.WriteLine("===");

Console.WriteLine($"Context information (e.g. citations) from chat extensions:");
Console.WriteLine("===");
foreach (ChatResponseMessage contextMessage in responseMessage.AzureExtensionsContext.Messages)
{
    string contextContent = contextMessage.Content;
    try
    {
        var contextMessageJson = JsonDocument.Parse(contextMessage.Content);
        contextContent = JsonSerializer.Serialize(contextMessageJson, new JsonSerializerOptions()
        {
            WriteIndented = true,
        });
    }
    catch (JsonException)
    {}
    Console.WriteLine($"{contextMessage.Role}: {contextContent}");
}
Console.WriteLine("===");

Внимание

Для рабочей среды используйте безопасный способ хранения и доступа к учетным данным, например Azure Key Vault. Дополнительные сведения о безопасности учетных данных см. в статье о безопасности служб искусственного интеллекта Azure.

dotnet run program.cs

Выходные данные

Answer from assistant:
===
The available health plans in the Contoso Electronics plan and benefit packages are the Northwind Health Plus and Northwind Standard plans [^1^].
===
Context information (e.g. citations) from chat extensions:
===
tool: {
  "citations": [
    {
      "content": "...",
      "id": null,
      "title": "...",
      "filepath": "...",
      "url": "...",
      "metadata": {
        "chunking": "orignal document size=1011. Scores=3.6390076 and None.Org Highlight count=38."
      },
      "chunk_id": "2"
    },
    ...
  ],
  "intent": "[\u0022What are my available health plans?\u0022]"
}
===

Ожидается, пока модель не создаст весь ответ перед печатью результатов. Кроме того, если вы хотите асинхронно передавать ответ и распечатать результаты, можно заменить содержимое Program.cs кодом в следующем примере.

Асинхронная передача с потоковой передачей

using Azure;
using Azure.AI.OpenAI;
using System.Text.Json;
using static System.Environment;

string azureOpenAIEndpoint = GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT");
string azureOpenAIKey = GetEnvironmentVariable("AZURE_OPENAI_API_KEY");
string deploymentName = GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_ID");
string searchEndpoint = GetEnvironmentVariable("AZURE_AI_SEARCH_ENDPOINT");
string searchKey = GetEnvironmentVariable("AZURE_AI_SEARCH_API_KEY");
string searchIndex = GetEnvironmentVariable("AZURE_AI_SEARCH_INDEX");


var client = new OpenAIClient(new Uri(azureOpenAIEndpoint), new AzureKeyCredential(azureOpenAIKey));

var chatCompletionsOptions = new ChatCompletionsOptions()
{
    DeploymentName = deploymentName,
    Messages =
    {
        new ChatRequestUserMessage("What are my available health plans?"),
    },
    AzureExtensionsOptions = new AzureChatExtensionsOptions()
    {
        Extensions =
        {
            new AzureCognitiveSearchChatExtensionConfiguration()
            {
                SearchEndpoint = new Uri(searchEndpoint),
                Key = searchKey,
                IndexName = searchIndex,
            },
        }
    }
};
await foreach (StreamingChatCompletionsUpdate chatUpdate in client.GetChatCompletionsStreaming(chatCompletionsOptions))
{
    if (chatUpdate.Role.HasValue)
    {
        Console.Write($"{chatUpdate.Role.Value.ToString().ToUpperInvariant()}: ");
    }
    if (!string.IsNullOrEmpty(chatUpdate.ContentUpdate))
    {
        Console.Write(chatUpdate.ContentUpdate);
    }
}

Получение необходимых переменных

Чтобы успешно выполнить вызов к Azure OpenAI, вам потребуются следующие переменные. В этом кратком руководстве предполагается, что вы отправили данные в учетную запись хранения BLOB-объектов Azure и создали индекс поиска ИИ Azure. Дополнительные сведения см. в статье "Добавление данных с помощью Студии искусственного интеллекта Azure".

Имя переменной Значение
AZURE_OPENAI_ENDPOINT Это значение можно найти в разделе "Ключи и конечная точка" при проверке ресурса Azure OpenAI из портал Azure. Кроме того, можно найти значение в представлении кода чата чата>Azure.> Пример конечной точки: https://my-resource.openai.azure.com.
AZURE_OPENAI_API_KEY Это значение можно найти в разделе "Ключи управления>ресурсами" и "Конечная точка" при изучении ресурса Azure OpenAI из портал Azure. Вы можете использовать KEY1 или KEY2. Наличие двух ключей позволяет безопасно менять и повторно создавать ключи без прерывания работы службы.
AZURE_OPEN_AI_DEPLOYMENT_ID Это значение соответствует пользовательскому имени, выбранному для развертывания при развертывании модели. Это значение можно найти в разделе "Развертывания управления ресурсами" в портал Azure или в разделе "Развертывания управления>>" в Студии ИИ Azure.
AZURE_AI_SEARCH_ENDPOINT Это значение можно найти в разделе "Обзор" при изучении ресурса поиска ИИ Azure из портал Azure.
AZURE_AI_SEARCH_API_KEY Это значение можно найти в разделе Параметры> Keys при изучении ресурса поиска ИИ Azure из портал Azure. Вы можете использовать ключ первичного администратора или дополнительный ключ администратора. Наличие двух ключей позволяет безопасно менять и повторно создавать ключи без прерывания работы службы.
AZURE_AI_SEARCH_INDEX Это значение соответствует имени индекса, созданного для хранения данных. Его можно найти в разделе "Обзор" при изучении ресурса поиска ИИ Azure из портал Azure.

Переменные среды

Примечание.

Spring AI по умолчанию использует имя gpt-35-turboмодели. Необходимо указать SPRING_AI_AZURE_OPENAI_MODEL значение только в том случае, если вы развернули модель с другим именем.

export SPRING_AI_AZURE_OPENAI_ENDPOINT=REPLACE_WITH_YOUR_AOAI_ENDPOINT_VALUE_HERE
export SPRING_AI_AZURE_OPENAI_API_KEY=REPLACE_WITH_YOUR_AOAI_KEY_VALUE_HERE
export SPRING_AI_AZURE_COGNITIVE_SEARCH_ENDPOINT=REPLACE_WITH_YOUR_AZURE_SEARCH_RESOURCE_VALUE_HERE
export SPRING_AI_AZURE_COGNITIVE_SEARCH_API_KEY=REPLACE_WITH_YOUR_AZURE_SEARCH_RESOURCE_KEY_VALUE_HERE
export SPRING_AI_AZURE_COGNITIVE_SEARCH_INDEX=REPLACE_WITH_YOUR_INDEX_NAME_HERE
export SPRING_AI_AZURE_OPENAI_MODEL=REPLACE_WITH_YOUR_MODEL_NAME_HERE

Создание нового приложения Spring

Spring AI в настоящее время не поддерживает AzureCognitiveSearchChatExtensionConfiguration варианты, позволяющие запросу ИИ Azure инкапсулировать метод получения дополненного поколения (RAG) и скрыть сведения от пользователя. В качестве альтернативы вы по-прежнему можете вызвать метод RAG непосредственно в приложении для запроса данных в индексе поиска ИИ Azure и использовать извлеченные документы для расширения запроса.

Spring AI поддерживает абстракцию VectorStore, и вы можете упаковать поиск ИИ Azure в реализацию Spring AI VectorStore для запроса пользовательских данных. Следующий проект реализует пользовательский VectorStore, поддерживаемый поиском ИИ Azure, и выполняет операции RAG напрямую.

В окне Bash создайте новый каталог для приложения и перейдите к нему.

mkdir ai-custom-data-demo && cd ai-custom-data-demo

Выполните команду spring init из рабочей папки. Эта команда создает стандартную структуру каталогов для проекта Spring, включая исходный файл класса Java и файл pom.xml , используемый для управления проектами на основе Maven.

spring init -a ai-custom-data-demo -n AICustomData --force --build maven -x

Созданные файлы и папки похожи на следующую структуру:

ai-custom-data-demo/
|-- pom.xml
|-- mvn
|-- mvn.cmd
|-- HELP.md
|-- src/
    |-- main/
    |   |-- resources/
    |   |   |-- application.properties
    |   |-- java/
    |       |-- com/
    |           |-- example/
    |               |-- aicustomdatademo/
    |                   |-- AiCustomDataApplication.java
    |-- test/
        |-- java/
            |-- com/
                |-- example/
                    |-- aicustomdatademo/
                        |-- AiCustomDataApplicationTests.java

Изменение приложения Spring

  1. Отредактируйте файл pom.xml.

    В корневом каталоге проекта откройте файл pom.xml в предпочтительном редакторе или интегрированной среде разработки и перезаписать файл следующим содержимым:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>3.2.0</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.example</groupId>
        <artifactId>ai-custom-data-demo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>AICustomData</name>
        <description>Demo project for Spring Boot</description>
        <properties>
            <java.version>17</java.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.experimental.ai</groupId>
                <artifactId>spring-ai-azure-openai-spring-boot-starter</artifactId>
                <version>0.7.0-SNAPSHOT</version>
            </dependency>
            <dependency>
                <groupId>com.azure</groupId>
                <artifactId>azure-search-documents</artifactId>
                <version>11.6.0-beta.10</version>
                <exclusions>
                    <!-- exclude this to avoid changing the default serializer and the null-value behavior -->
                    <exclusion>
                        <groupId>com.azure</groupId>
                        <artifactId>azure-core-serializer-json-jackson</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
        <repositories>
            <repository>
                <id>spring-snapshots</id>
                <name>Spring Snapshots</name>
                <url>https://repo.spring.io/snapshot</url>
                <releases>
                    <enabled>false</enabled>
                </releases>
            </repository>
        </repositories>
    </project>
    
  2. В папке src/main/java/com/example/aicustomdatademo откройте AiCustomDataApplication.java в предпочтительном редакторе или интегрированной среде разработки и вставьте следующий код:

    package com.example.aicustomdatademo;
    
    import java.util.Collections;
    import java.util.List;
    import java.util.Map;
    import java.util.Optional;
    import java.util.stream.Collectors;
    
    import org.springframework.ai.client.AiClient;
    import org.springframework.ai.document.Document;
    import org.springframework.ai.embedding.EmbeddingClient;
    import org.springframework.ai.prompt.Prompt;
    import org.springframework.ai.prompt.SystemPromptTemplate;
    import org.springframework.ai.prompt.messages.MessageType;
    import org.springframework.ai.prompt.messages.UserMessage;
    import org.springframework.ai.vectorstore.VectorStore;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.Bean;
    
    import com.azure.core.credential.AzureKeyCredential;
    import com.azure.core.util.Context;
    import com.azure.search.documents.SearchClient;
    import com.azure.search.documents.SearchClientBuilder;
    import com.azure.search.documents.models.IndexingResult;
    import com.azure.search.documents.models.SearchOptions;
    import com.azure.search.documents.models.RawVectorQuery;
    
    import lombok.AllArgsConstructor;
    import lombok.NoArgsConstructor;
    import lombok.Builder;
    import lombok.Data;
    import lombok.extern.jackson.Jacksonized;
    
    @SpringBootApplication
    public class AiCustomDataApplication implements CommandLineRunner
    {
        private static final String ROLE_INFO_KEY = "role";
    
        private static final String template = """
                You are a helpful assistant. Use the information from the DOCUMENTS section to augment answers.
    
                DOCUMENTS:
                {documents}
                """;
    
        @Value("${spring.ai.azure.cognitive-search.endpoint}")
        private String acsEndpoint;
    
        @Value("${spring.ai.azure.cognitive-search.api-key}")
        private String acsApiKey;
    
        @Value("${spring.ai.azure.cognitive-search.index}")
        private String acsIndexName;
    
        @Autowired
        private AiClient aiClient;
    
        @Autowired
        private EmbeddingClient embeddingClient;
    
        public static void main(String[] args) {
            SpringApplication.run(AiCustomDataApplication.class, args);
        }
    
        @Override
        public void run(String... args) throws Exception
        {
            System.out.println(String.format("Sending custom data prompt to AI service. One moment please...\r\n"));
    
            final var store = vectorStore(embeddingClient);
    
            final String question = "What are my available health plans?";
    
            final var candidateDocs = store.similaritySearch(question);
    
            final var userMessage = new UserMessage(question);
    
            final String docPrompts =
                    candidateDocs.stream().map(entry -> entry.getContent()).collect(Collectors.joining("\n"));
    
            final SystemPromptTemplate promptTemplate = new SystemPromptTemplate(template);
            final var systemMessage = promptTemplate.createMessage(Map.of("documents", docPrompts));
    
            final var prompt = new Prompt(List.of(systemMessage, userMessage));
    
            final var resps = aiClient.generate(prompt);
    
            System.out.println(String.format("Prompt created %d generated response(s).", resps.getGenerations().size()));
    
            resps.getGenerations().stream()
              .forEach(gen -> {
                  final var role = gen.getInfo().getOrDefault(ROLE_INFO_KEY, MessageType.ASSISTANT.getValue());
    
                  System.out.println(String.format("Generated respose from \"%s\": %s", role, gen.getText()));
              });
    
        }
    
        @Bean
        public VectorStore vectorStore(EmbeddingClient embeddingClient)
        {
            final SearchClient searchClient = new SearchClientBuilder()
                    .endpoint(acsEndpoint)
                    .credential(new AzureKeyCredential(acsApiKey))
                    .indexName(acsIndexName)
                    .buildClient();
            return new AzureCognitiveSearchVectorStore(searchClient, embeddingClient);
        }
    
        public static class AzureCognitiveSearchVectorStore implements VectorStore
        {
            private static final int DEFAULT_TOP_K = 4;
    
            private static final Double DEFAULT_SIMILARITY_THRESHOLD = 0.0;
    
            private SearchClient searchClient;
    
            private final EmbeddingClient embeddingClient;
    
            public AzureCognitiveSearchVectorStore(SearchClient searchClient, EmbeddingClient embeddingClient)
            {
                this.searchClient = searchClient;
                this.embeddingClient = embeddingClient;
            }
    
            @Override
            public void add(List<Document> documents)
            {
                final var docs = documents.stream().map(document -> {
    
                    final var embeddings = embeddingClient.embed(document);
    
                    return new DocEntry(document.getId(), "", document.getContent(), embeddings);
    
                }).toList();
    
                searchClient.uploadDocuments(docs);
            }
    
            @Override
            public Optional<Boolean> delete(List<String> idList)
            {
                final List<DocEntry> docIds = idList.stream().map(id -> DocEntry.builder().id(id).build())
                    .toList();
    
                var results = searchClient.deleteDocuments(docIds);
    
                boolean resSuccess = true;
    
                for (IndexingResult result : results.getResults())
                    if (!result.isSucceeded()) {
                        resSuccess = false;
                        break;
                    }
    
                return Optional.of(resSuccess);
            }
    
            @Override
            public List<Document> similaritySearch(String query)
            {
                return similaritySearch(query, DEFAULT_TOP_K);
            }
    
            @Override
            public List<Document> similaritySearch(String query, int k)
            {
                return similaritySearch(query, k, DEFAULT_SIMILARITY_THRESHOLD);
            }
    
            @Override
            public List<Document> similaritySearch(String query, int k, double threshold)
            {
                final var searchQueryVector = new RawVectorQuery()
                        .setVector(toFloatList(embeddingClient.embed(query)))
                        .setKNearestNeighborsCount(k)
                        .setFields("contentVector");
    
                final var searchResults = searchClient.search(null,
                        new SearchOptions().setVectorQueries(searchQueryVector), Context.NONE);
    
                return searchResults.stream()
                        .filter(r -> r.getScore() >= threshold)
                        .map(r -> {
    
                            final DocEntry entry = r.getDocument(DocEntry.class);
    
                            final Document doc = new Document(entry.getId(), entry.getContent(), Collections.emptyMap());
                            doc.setEmbedding(entry.getContentVector());
    
                            return doc;
                        })
                        .collect(Collectors.toList());
            }
    
            private List<Float> toFloatList(List<Double> doubleList)
            {
                return doubleList.stream().map(Double::floatValue).toList();
            }
    
        }
    
        @Data
        @Builder
        @Jacksonized
        @AllArgsConstructor
        @NoArgsConstructor
        static class DocEntry
        {
            private String id;
    
            private String hash;
    
            private String content;
    
            private List<Double> contentVector;
        }
    
    }
    

    Внимание

    Для рабочей среды используйте безопасный способ хранения и доступа к учетным данным, например Azure Key Vault. Дополнительные сведения о безопасности учетных данных см. в статье о безопасности служб искусственного интеллекта Azure.

  3. Вернитесь к корневой папке проекта и запустите приложение с помощью следующей команды:

    ./mvnw spring-boot:run
    

Выходные данные

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.1.5)

2023-11-07T14:40:45.250-06:00  INFO 18557 --- [           main] c.e.a.AiCustomDataApplication            : No active profile set, falling back to 1 default profile: "default"
2023-11-07T14:40:46.035-06:00  INFO 18557 --- [           main] c.e.a.AiCustomDataApplication            : Started AiCustomDataApplication in 1.095 seconds (process running for 1.397)
Sending custom data prompt to AI service. One moment please...

Prompt created 1 generated response(s).
Generated response from "assistant": The available health plans in the Contoso Electronics plan and benefit packages are the Northwind Health Plus and Northwind Standard plans.

Получение необходимых переменных

Чтобы успешно выполнить вызов к Azure OpenAI, вам потребуются следующие переменные. В этом кратком руководстве предполагается, что вы отправили данные в учетную запись хранения BLOB-объектов Azure и создали индекс поиска ИИ Azure. См. статью "Добавление данных с помощью Студии искусственного интеллекта Azure"

Имя переменной Значение
AZURE_OPENAI_ENDPOINT Это значение можно найти в разделе "Ключи и конечная точка" при проверке ресурса Azure OpenAI из портал Azure. Кроме того, можно найти значение в представлении кода чата чата>Azure.> Пример конечной точки: https://my-resoruce.openai.azure.com.
AZURE_OPENAI_API_KEY Это значение можно найти в разделе "Ключи управления>ресурсами" и "Конечная точка" при изучении ресурса Azure OpenAI из портал Azure. Вы можете использовать KEY1 или KEY2. Наличие двух ключей позволяет безопасно менять и повторно создавать ключи без прерывания работы службы.
AZURE_OPENAI_DEPLOYMENT_ID Это значение соответствует пользовательскому имени, выбранному для развертывания при развертывании модели. Это значение можно найти в разделе "Развертывания управления>ресурсами" в портал Azure или в разделе "Развертывания управления>" в Студии ИИ Azure.
AZURE_AI_SEARCH_ENDPOINT Это значение можно найти в разделе "Обзор" при изучении ресурса поиска ИИ Azure из портал Azure.
AZURE_AI_SEARCH_API_KEY Это значение можно найти в разделе Параметры> Keys при изучении ресурса поиска ИИ Azure из портал Azure. Вы можете использовать ключ первичного администратора или дополнительный ключ администратора. Наличие двух ключей позволяет безопасно менять и повторно создавать ключи без прерывания работы службы.
AZURE_AI_SEARCH_INDEX Это значение соответствует имени индекса, созданного для хранения данных. Его можно найти в разделе "Обзор" при изучении ресурса поиска ИИ Azure из портал Azure.

Переменные среды

setx AZURE_OPENAI_ENDPOINT REPLACE_WITH_YOUR_AOAI_ENDPOINT_VALUE_HERE
setx AZURE_OPENAI_API_KEY REPLACE_WITH_YOUR_AOAI_KEY_VALUE_HERE
setx AZURE_OPENAI_DEPLOYMENT_ID REPLACE_WITH_YOUR_AOAI_DEPLOYMENT_VALUE_HERE
setx AZURE_AI_SEARCH_ENDPOINT REPLACE_WITH_YOUR_AZURE_SEARCH_RESOURCE_VALUE_HERE
setx AZURE_AI_SEARCH_API_KEY REPLACE_WITH_YOUR_AZURE_SEARCH_RESOURCE_KEY_VALUE_HERE
setx AZURE_AI_SEARCH_INDEX REPLACE_WITH_YOUR_INDEX_NAME_HERE

Создание приложения Node

В окне консоли (например, cmd, PowerShell или Bash) создайте новый каталог для приложения и перейдите в него. Затем выполните npm init команду, чтобы создать приложение узла с package.json файлом.

npm init

Установка клиентской библиотеки

Установите клиент Azure OpenAI и библиотеки удостоверений Azure для JavaScript с помощью npm:

npm install @azure/openai @azure/identity

Файл package.json приложения будет обновлен с помощью зависимостей.

Создание примера приложения

Откройте командную строку, в которой хотите создать проект, и создайте файл с именем ChatWithOwnData.js. Скопируйте следующий код в файл ChatWithOwnData.js.

const { OpenAIClient, AzureKeyCredential } = require("@azure/openai");

// Set the Azure and AI Search values from environment variables
const endpoint = process.env["AZURE_OPENAI_ENDPOINT"];
const azureApiKey = process.env["AZURE_OPENAI_API_KEY"];
const deploymentId = process.env["AZURE_OPENAI_DEPLOYMENT_ID"];
const searchEndpoint = process.env["AZURE_AI_SEARCH_ENDPOINT"];
const searchKey = process.env["AZURE_AI_SEARCH_API_KEY"];
const searchIndex = process.env["AZURE_AI_SEARCH_INDEX"];


async function main(){
  const client = new OpenAIClient(endpoint, new AzureKeyCredential(azureApiKey));

  const messages = [
    { role: "user", content: "What are my available health plans?" },
  ];

  console.log(`Message: ${messages.map((m) => m.content).join("\n")}`);

  const events = await client.streamChatCompletions(deploymentId, messages, { 
    maxTokens: 128,
    azureExtensionOptions: {
      extensions: [
        {
          type: "AzureCognitiveSearch",
          endpoint: searchEndpoint,
          key: searchKey,
          indexName: searchIndex,
        },
      ],
    },
  });
  let response = "";
  for await (const event of events) {
    for (const choice of event.choices) {
      const newText = choice.delta?.content;
      if (!!newText) {
        response += newText;
        // To see streaming results as they arrive, uncomment line below
        // console.log(newText);
      }
    }
  }
  console.log(response);
}

main().catch((err) => {
  console.error("The sample encountered an error:", err);
});



module.exports = { main };

Внимание

Для рабочей среды используйте безопасный способ хранения и доступа к учетным данным, например Azure Key Vault. Дополнительные сведения о безопасности учетных данных см. в статье о безопасности служб искусственного интеллекта Azure.

node.exe ChatWithOwnData.js

Выходные данные

Message: What are my available health plans?
The available health plans in the Contoso Electronics plan and benefit packages are the Northwind Health Plus and Northwind Standard plans.

Получение необходимых переменных

Чтобы успешно выполнить вызов к Azure OpenAI, вам потребуются следующие переменные. В этом кратком руководстве предполагается, что вы отправили данные в учетную запись хранения BLOB-объектов Azure и создали индекс поиска ИИ Azure. См. статью "Добавление данных с помощью Студии искусственного интеллекта Azure"

Имя переменной Значение
AZURE_OPENAI_ENDPOINT Это значение можно найти в разделе "Ключи и конечная точка" при проверке ресурса Azure OpenAI из портал Azure. Кроме того, можно найти значение в представлении кода чата чата>Azure.> Пример конечной точки: https://my-resoruce.openai.azure.com.
AZURE_OPENAI_API_KEY Это значение можно найти в разделе "Ключи управления>ресурсами" и "Конечная точка" при изучении ресурса Azure OpenAI из портал Azure. Вы можете использовать KEY1 или KEY2. Наличие двух ключей позволяет безопасно менять и повторно создавать ключи без прерывания работы службы.
AZURE_OPENAI_DEPLOYMENT_ID Это значение соответствует пользовательскому имени, выбранному для развертывания при развертывании модели. Это значение можно найти в разделе "Развертывания управления>ресурсами" в портал Azure или в разделе "Развертывания управления>" в Студии ИИ Azure.
AZURE_AI_SEARCH_ENDPOINT Это значение можно найти в разделе "Обзор" при изучении ресурса поиска ИИ Azure из портал Azure.
AZURE_AI_SEARCH_API_KEY Это значение можно найти в разделе Параметры> Keys при изучении ресурса поиска ИИ Azure из портал Azure. Вы можете использовать ключ первичного администратора или дополнительный ключ администратора. Наличие двух ключей позволяет безопасно менять и повторно создавать ключи без прерывания работы службы.
AZURE_AI_SEARCH_INDEX Это значение соответствует имени индекса, созданного для хранения данных. Его можно найти в разделе "Обзор" при изучении ресурса поиска ИИ Azure из портал Azure.

Переменные среды

setx AZURE_OPENAI_ENDPOINT REPLACE_WITH_YOUR_AOAI_ENDPOINT_VALUE_HERE
setx AZURE_OPENAI_API_KEY REPLACE_WITH_YOUR_AOAI_KEY_VALUE_HERE
setx AZURE_OPENAI_DEPLOYMENT_ID REPLACE_WITH_YOUR_AOAI_DEPLOYMENT_VALUE_HERE
setx AZURE_AI_SEARCH_ENDPOINT REPLACE_WITH_YOUR_AZURE_SEARCH_RESOURCE_VALUE_HERE
setx AZURE_AI_SEARCH_API_KEY REPLACE_WITH_YOUR_AZURE_SEARCH_RESOURCE_KEY_VALUE_HERE
setx AZURE_AI_SEARCH_INDEX REPLACE_WITH_YOUR_INDEX_NAME_HERE

Создание среды Python

  1. Создайте новую папку с именем openai-python для проекта и новый файл кода Python с именем main.py. Перейдите в этот каталог:
mkdir openai-python
cd openai-python
  1. Установите следующие библиотеки Python:
pip install openai
pip install python-dotenv

Создание приложения Python

  1. В каталоге проекта откройте файл main.py и добавьте следующий код:
import os
import openai
import dotenv

dotenv.load_dotenv()

endpoint = os.environ.get("AZURE_OPENAI_ENDPOINT")
api_key = os.environ.get("AZURE_OPENAI_API_KEY")
deployment = os.environ.get("AZURE_OPENAI_DEPLOYMENT_ID")

client = openai.AzureOpenAI(
    azure_endpoint=endpoint,
    api_key=api_key,
    api_version="2024-02-01",
)

completion = client.chat.completions.create(
    model=deployment,
    messages=[
        {
            "role": "user",
            "content": "What are my available health plans?",
        },
    ],
    extra_body={
        "data_sources":[
            {
                "type": "azure_search",
                "parameters": {
                    "endpoint": os.environ["AZURE_AI_SEARCH_ENDPOINT"],
                    "index_name": os.environ["AZURE_AI_SEARCH_INDEX"],
                    "authentication": {
                        "type": "api_key",
                        "key": os.environ["AZURE_AI_SEARCH_API_KEY"],
                    }
                }
            }
        ],
    }
)

print(completion.model_dump_json(indent=2))

Внимание

Для рабочей среды используйте безопасный способ хранения и доступа к учетным данным, например Azure Key Vault. Дополнительные сведения о безопасности учетных данных см. в статье о безопасности служб искусственного интеллекта Azure.

  1. Выполните следующую команду:
python main.py

Приложение печатает ответ в формате JSON, подходящем для использования во многих сценариях. Он включает как ответы на запрос, так и ссылки из отправленных файлов.

Получение необходимых переменных

Чтобы успешно выполнить вызов к Azure OpenAI, вам потребуются следующие переменные. В этом кратком руководстве предполагается, что вы отправили данные в учетную запись хранения BLOB-объектов Azure и создали индекс поиска ИИ Azure. См. статью "Добавление данных с помощью Студии искусственного интеллекта Azure"

Имя переменной Значение
AZURE_OPENAI_ENDPOINT Это значение можно найти в разделе "Ключи и конечная точка" при проверке ресурса Azure OpenAI из портал Azure. Кроме того, можно найти значение в представлении кода чата чата>Azure.> Пример конечной точки: https://my-resoruce.openai.azure.com.
AZURE_OPENAI_API_KEY Это значение можно найти в разделе "Ключи управления>ресурсами" и "Конечная точка" при изучении ресурса Azure OpenAI из портал Azure. Вы можете использовать KEY1 или KEY2. Наличие двух ключей позволяет безопасно менять и повторно создавать ключи без прерывания работы службы.
AZURE_OPENAI_DEPLOYMENT_ID Это значение соответствует пользовательскому имени, выбранному для развертывания при развертывании модели. Это значение можно найти в разделе "Развертывания управления>ресурсами" в портал Azure или в разделе "Развертывания управления>" в Студии ИИ Azure.
AZURE_AI_SEARCH_ENDPOINT Это значение можно найти в разделе "Обзор" при изучении ресурса поиска ИИ Azure из портал Azure.
AZURE_AI_SEARCH_API_KEY Это значение можно найти в разделе Параметры> Keys при изучении ресурса поиска ИИ Azure из портал Azure. Вы можете использовать ключ первичного администратора или дополнительный ключ администратора. Наличие двух ключей позволяет безопасно менять и повторно создавать ключи без прерывания работы службы.
AZURE_AI_SEARCH_INDEX Это значение соответствует имени индекса, созданного для хранения данных. Его можно найти в разделе "Обзор" при изучении ресурса поиска ИИ Azure из портал Azure.

Переменные среды

setx AZURE_OPENAI_ENDPOINT REPLACE_WITH_YOUR_AOAI_ENDPOINT_VALUE_HERE
setx AZURE_OPENAI_API_KEY REPLACE_WITH_YOUR_AOAI_KEY_VALUE_HERE
setx AZURE_OPENAI_DEPLOYMENT_ID REPLACE_WITH_YOUR_AOAI_DEPLOYMENT_VALUE_HERE
setx AZURE_AI_SEARCH_ENDPOINT REPLACE_WITH_YOUR_AZURE_SEARCH_RESOURCE_VALUE_HERE
setx AZURE_AI_SEARCH_API_KEY REPLACE_WITH_YOUR_AZURE_SEARCH_RESOURCE_KEY_VALUE_HERE
setx AZURE_AI_SEARCH_INDEX REPLACE_WITH_YOUR_INDEX_NAME_HERE

Примеры команд PowerShell

Модели чата Azure OpenAI оптимизированы для работы с входными данными, отформатированными в виде беседы. Переменная messages передает массив словарей с разными ролями в беседе, очерченной системой, пользователем, инструментом и помощник. Переменная dataSources подключается к индексу Когнитивный поиск Azure и позволяет моделям Azure OpenAI реагировать с помощью данных.

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

Совет

Существует несколько параметров, которые можно использовать для изменения ответа модели, например temperature или top_p. Дополнительные сведения см. в справочной документации.

# Azure OpenAI metadata variables
   $openai = @{
       api_key     = $Env:AZURE_OPENAI_API_KEY
       api_base    = $Env:AZURE_OPENAI_ENDPOINT # your endpoint should look like the following https://YOUR_RESOURCE_NAME.openai.azure.com/
       api_version = '2023-07-01-preview' # this may change in the future
       name        = 'YOUR-DEPLOYMENT-NAME-HERE' #This will correspond to the custom name you chose for your deployment when you deployed a model.
   }

   $acs = @{
       search_endpoint     = 'YOUR ACS ENDPOINT' # your endpoint should look like the following https://YOUR_RESOURCE_NAME.search.windows.net/
       search_key    = 'YOUR-ACS-KEY-HERE' # or use the Get-Secret cmdlet to retrieve the value
       search_index = 'YOUR-INDEX-NAME-HERE' # the name of your ACS index
   }

   # Completion text
   $body = @{
    dataSources = @(
        @{
            type = 'AzureCognitiveSearch'
            parameters = @{
                    endpoint = $acs.search_endpoint
                    key = $acs.search_key
                    indexName = $acs.search_index
                }
        }
    )
    messages = @(
            @{
                role = 'user'
                content = 'What are my available health plans?'
            }
    )
   } | convertto-json -depth 5

   # Header for authentication
   $headers = [ordered]@{
       'api-key' = $openai.api_key
   }

   # Send a completion call to generate an answer
   $url = "$($openai.api_base)/openai/deployments/$($openai.name)/extensions/chat/completions?api-version=$($openai.api_version)"

   $response = Invoke-RestMethod -Uri $url -Headers $headers -Body $body -Method Post -ContentType 'application/json'
   return $response.choices.messages[1].content

Пример результата

The available health plans in the Contoso Electronics plan and benefit packages are the Northwind Health Plus and Northwind Standard plans.

Внимание

Для рабочей среды используйте безопасный способ хранения и доступа к учетным данным, таким как Управление секретами PowerShell с помощью Azure Key Vault. Дополнительные сведения о безопасности учетных данных см. в статье о безопасности служб искусственного интеллекта Azure.

Чат с моделью с помощью веб-приложения

Чтобы начать чат с моделью Azure OpenAI, использующую данные, можно развернуть веб-приложение с помощью Azure OpenAI Studio или примера кода, который мы предоставляем на GitHub. Это приложение развертывает с помощью службы приложений Azure и предоставляет пользовательский интерфейс для отправки запросов. Это приложение можно использовать модели Azure OpenAI, использующие данные или модели, которые не используют данные. Ознакомьтесь с файлом readme в репозитории с инструкциями по требованиям, настройке и развертыванию. При необходимости можно настроить интерфейсную и серверную логику веб-приложения, внося изменения в исходный код.

Получение необходимых переменных

Чтобы успешно выполнить вызов к Azure OpenAI, вам потребуются следующие переменные. В этом кратком руководстве предполагается, что вы отправили данные в учетную запись хранения BLOB-объектов Azure и создали индекс поиска ИИ Azure. См. статью "Добавление данных с помощью Студии искусственного интеллекта Azure"

Имя переменной Значение
AZURE_OPENAI_ENDPOINT Это значение можно найти в разделе "Ключи и конечная точка" при проверке ресурса Azure OpenAI из портал Azure. Кроме того, можно найти значение в представлении кода чата чата>Azure.> Пример конечной точки: https://my-resoruce.openai.azure.com.
AZURE_OPENAI_API_KEY Это значение можно найти в разделе "Ключи управления>ресурсами" и "Конечная точка" при изучении ресурса Azure OpenAI из портал Azure. Вы можете использовать KEY1 или KEY2. Наличие двух ключей позволяет безопасно менять и повторно создавать ключи без прерывания работы службы.
AZURE_OPENAI_DEPLOYMENT_ID Это значение соответствует пользовательскому имени, выбранному для развертывания при развертывании модели. Это значение можно найти в разделе "Развертывания управления>ресурсами" в портал Azure или в разделе "Развертывания управления>" в Студии ИИ Azure.
AZURE_AI_SEARCH_ENDPOINT Это значение можно найти в разделе "Обзор" при изучении ресурса поиска ИИ Azure из портал Azure.
AZURE_AI_SEARCH_API_KEY Это значение можно найти в разделе Параметры> Keys при изучении ресурса поиска ИИ Azure из портал Azure. Вы можете использовать ключ первичного администратора или дополнительный ключ администратора. Наличие двух ключей позволяет безопасно менять и повторно создавать ключи без прерывания работы службы.
AZURE_AI_SEARCH_INDEX Это значение соответствует имени индекса, созданного для хранения данных. Его можно найти в разделе "Обзор" при изучении ресурса поиска ИИ Azure из портал Azure.

Переменные среды

setx AZURE_OPENAI_ENDPOINT REPLACE_WITH_YOUR_AOAI_ENDPOINT_VALUE_HERE
setx AZURE_OPENAI_API_KEY REPLACE_WITH_YOUR_AOAI_KEY_VALUE_HERE
setx AZURE_OPENAI_DEPLOYMENT_ID REPLACE_WITH_YOUR_AOAI_DEPLOYMENT_VALUE_HERE
setx AZURE_AI_SEARCH_ENDPOINT REPLACE_WITH_YOUR_AZURE_SEARCH_RESOURCE_VALUE_HERE
setx AZURE_AI_SEARCH_API_KEY REPLACE_WITH_YOUR_AZURE_SEARCH_RESOURCE_KEY_VALUE_HERE
setx AZURE_AI_SEARCH_INDEX REPLACE_WITH_YOUR_INDEX_NAME_HERE

Создание среды Go

  1. Создайте новую папку с именем openai-go для проекта и новый файл кода Go с именем sample.go. Перейдите в этот каталог:

    mkdir openai-go
    cd openai-go
    
  2. Установите следующие пакеты Go:

    go get github.com/Azure/azure-sdk-for-go/sdk/ai/azopenai
    
  3. Включите отслеживание зависимостей для кода.

    go mod init example/azure-openai
    

Создание приложения Go

  1. В каталоге проекта откройте файл sample.go и добавьте следующий код:

    package main
    
    import (
     "context"
     "fmt"
     "log"
     "os"
    
     "github.com/Azure/azure-sdk-for-go/sdk/ai/azopenai"
     "github.com/Azure/azure-sdk-for-go/sdk/azcore"
     "github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
    )
    
    func main() {
     azureOpenAIKey := os.Getenv("AZURE_OPENAI_API_KEY")
     modelDeploymentID := os.Getenv("AZURE_OPENAI_DEPLOYMENT_ID")
    
     // Ex: "https://<your-azure-openai-host>.openai.azure.com"
     azureOpenAIEndpoint := os.Getenv("AZURE_OPENAI_ENDPOINT")
    
     // Azure AI Search configuration
     searchIndex := os.Getenv("AZURE_AI_SEARCH_INDEX")
     searchEndpoint := os.Getenv("AZURE_AI_SEARCH_ENDPOINT")
     searchAPIKey := os.Getenv("AZURE_AI_SEARCH_API_KEY")
    
     if azureOpenAIKey == "" || modelDeploymentID == "" || azureOpenAIEndpoint == "" || searchIndex == "" || searchEndpoint == "" || searchAPIKey == "" {
     	fmt.Fprintf(os.Stderr, "Skipping example, environment variables missing\n")
     	return
     }
    
     keyCredential := azcore.NewKeyCredential(azureOpenAIKey)
    
     // In Azure OpenAI you must deploy a model before you can use it in your client. For more information
     // see here: https://learn.microsoft.com/azure/cognitive-services/openai/how-to/create-resource
     client, err := azopenai.NewClientWithKeyCredential(azureOpenAIEndpoint, keyCredential, nil)
    
     if err != nil {
     	//  TODO: Update the following line with your application specific error handling logic
     	log.Fatalf("ERROR: %s", err)
     }
    
     resp, err := client.GetChatCompletions(context.TODO(), azopenai.ChatCompletionsOptions{
     	Messages: []azopenai.ChatRequestMessageClassification{
     		&azopenai.ChatRequestUserMessage{Content: azopenai.NewChatRequestUserMessageContent("What are my available health plans?")},
     	},
     	MaxTokens: to.Ptr[int32](512),
     	AzureExtensionsOptions: []azopenai.AzureChatExtensionConfigurationClassification{
     		&azopenai.AzureCognitiveSearchChatExtensionConfiguration{
     			// This allows Azure OpenAI to use an Azure AI Search index.
     			//
     			// > Because the model has access to, and can reference specific sources to support its responses, answers are not only based on its pretrained knowledge
     			// > but also on the latest information available in the designated data source. This grounding data also helps the model avoid generating responses
     			// > based on outdated or incorrect information.
     			//
     			// Quote from here: https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/use-your-data
     			Parameters: &azopenai.AzureCognitiveSearchChatExtensionParameters{
     				Endpoint:  &searchEndpoint,
     				IndexName: &searchIndex,
     				Authentication: &azopenai.OnYourDataAPIKeyAuthenticationOptions{
     					Key: &searchAPIKey,
     				},
     			},
     		},
     	},
     	DeploymentName: &modelDeploymentID,
     }, nil)
    
     if err != nil {
     	//  TODO: Update the following line with your application specific error handling logic
     	log.Fatalf("ERROR: %s", err)
     }
    
     // Contains contextual information from your Azure chat completion extensions, configured above in `AzureExtensionsOptions`
     msgContext := resp.Choices[0].Message.Context
    
     fmt.Fprintf(os.Stderr, "Extensions Context Role: %s\nExtensions Context (length): %d\n",
     	*msgContext.Messages[0].Role,
     	len(*msgContext.Messages[0].Content))
    
     fmt.Fprintf(os.Stderr, "ChatRole: %s\nChat content: %s\n",
     	*resp.Choices[0].Message.Role,
     	*resp.Choices[0].Message.Content,
     )
    }
    

    Внимание

    Для рабочей среды используйте безопасный способ хранения и доступа к учетным данным, например Azure Key Vault. Дополнительные сведения о безопасности учетных данных см. в статье о безопасности служб искусственного интеллекта Azure.

  2. Выполните следующую команду:

    go run sample.go
    

    Приложение печатает ответ, включая ответы на запрос и ссылки из отправленных файлов.

Получение необходимых переменных

Чтобы успешно выполнить вызов к Azure OpenAI, вам потребуются следующие переменные. В этом кратком руководстве предполагается, что вы отправили данные в учетную запись хранения BLOB-объектов Azure и создали индекс поиска ИИ Azure. См. статью "Добавление данных с помощью Студии искусственного интеллекта Azure"

Имя переменной Значение
AZURE_OPENAI_ENDPOINT Это значение можно найти в разделе "Ключи и конечная точка" при проверке ресурса Azure OpenAI из портал Azure. Кроме того, можно найти значение в представлении кода чата чата>Azure.> Пример конечной точки: https://my-resoruce.openai.azure.com.
AZURE_OPENAI_API_KEY Это значение можно найти в разделе "Ключи управления>ресурсами" и "Конечная точка" при изучении ресурса Azure OpenAI из портал Azure. Вы можете использовать KEY1 или KEY2. Наличие двух ключей позволяет безопасно менять и повторно создавать ключи без прерывания работы службы.
AZURE_OPENAI_DEPLOYMENT_ID Это значение соответствует пользовательскому имени, выбранному для развертывания при развертывании модели. Это значение можно найти в разделе "Развертывания управления>ресурсами" в портал Azure или в разделе "Развертывания управления>" в Студии ИИ Azure.
AZURE_AI_SEARCH_ENDPOINT Это значение можно найти в разделе "Обзор" при изучении ресурса поиска ИИ Azure из портал Azure.
AZURE_AI_SEARCH_API_KEY Это значение можно найти в разделе Параметры> Keys при изучении ресурса поиска ИИ Azure из портал Azure. Вы можете использовать ключ первичного администратора или дополнительный ключ администратора. Наличие двух ключей позволяет безопасно менять и повторно создавать ключи без прерывания работы службы.
AZURE_AI_SEARCH_INDEX Это значение соответствует имени индекса, созданного для хранения данных. Его можно найти в разделе "Обзор" при изучении ресурса поиска ИИ Azure из портал Azure.

Переменные среды

setx AZURE_OPENAI_ENDPOINT REPLACE_WITH_YOUR_AOAI_ENDPOINT_VALUE_HERE
setx AZURE_OPENAI_API_KEY REPLACE_WITH_YOUR_AOAI_KEY_VALUE_HERE
setx AZURE_OPENAI_DEPLOYMENT_ID REPLACE_WITH_YOUR_AOAI_DEPLOYMENT_VALUE_HERE
setx AZURE_AI_SEARCH_ENDPOINT REPLACE_WITH_YOUR_AZURE_SEARCH_RESOURCE_VALUE_HERE
setx AZURE_AI_SEARCH_API_KEY REPLACE_WITH_YOUR_AZURE_SEARCH_RESOURCE_KEY_VALUE_HERE
setx AZURE_AI_SEARCH_INDEX REPLACE_WITH_YOUR_INDEX_NAME_HERE

Примеры команд cURL

Модели чата Azure OpenAI оптимизированы для работы с входными данными, отформатированными в виде беседы. Переменная messages передает массив словарей с разными ролями в беседе, очерченной системой, пользователем, инструментом и помощник. Переменная dataSources подключается к индексу поиска ИИ Azure и позволяет моделям Azure OpenAI реагировать с помощью данных.

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

Совет

Существует несколько параметров, которые можно использовать для изменения ответа модели, например temperature или top_p. Дополнительные сведения см. в справочной документации.

curl -i -X POST $AZURE_OPENAI_ENDPOINT/openai/deployments/$AZURE_OPENAI_DEPLOYMENT_ID/chat/completions?api-version=2024-02-15-preview \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-d \
'
{
    "data_sources": [
        {
            "type": "AzureCognitiveSearch",
            "parameters": {
                "endpoint": "'$AZURE_AI_SEARCH_ENDPOINT'",
                "key": "'$AZURE_AI_SEARCH_API_KEY'",
                "index_name": "'$AZURE_AI_SEARCH_INDEX'"
            }
        }
    ],
    "messages": [
        {
            "role": "user",
            "content": "What are my available health plans?"
        }
    ]
}
'

Пример результата

{
    "id": "12345678-1a2b-3c4e5f-a123-12345678abcd",
    "model": "gpt-4",
    "created": 1709835345,
    "object": "extensions.chat.completion",
    "choices": [
        {
            "index": 0,
            "finish_reason": "stop",
            "message": {
                "role": "assistant",
                "content": "The available health plans in the Contoso Electronics plan and benefit packages are the Northwind Health Plus and Northwind Standard plans. [doc1].",
                "end_turn": true,
                "context": {
                    "citations": [
                        {
                            "content": "...",
                            "title": "...",
                            "url": "https://mysearch.blob.core.windows.net/xyz/001.txt",
                            "filepath": "001.txt",
                            "chunk_id": "0"
                        }
                    ],
                    "intent": "[\"Available health plans\"]"
                }
            }
        }
    ],
    "usage": {
        "prompt_tokens": 3779,
        "completion_tokens": 105,
        "total_tokens": 3884
    }
}

Чат с моделью с помощью веб-приложения

Чтобы начать чат с моделью Azure OpenAI, использующую данные, можно развернуть веб-приложение с помощью Azure OpenAI Studio или примера кода, который мы предоставляем на GitHub. Это приложение развертывает с помощью службы приложений Azure и предоставляет пользовательский интерфейс для отправки запросов. Это приложение можно использовать модели Azure OpenAI, использующие данные или модели, которые не используют данные. Ознакомьтесь с файлом readme в репозитории с инструкциями по требованиям, настройке и развертыванию. При необходимости можно настроить интерфейсную и серверную логику веб-приложения, внося изменения в исходный код.

Очистка ресурсов

Если вы хотите очистить и удалить ресурс Azure OpenAI или azure AI Search, можно удалить ресурс или группу ресурсов. При удалении группы ресурсов также удаляются все связанные с ней ресурсы.

Следующие шаги