快速入門:使用您自己的數據與 Azure OpenAI 模型聊天

參考 | 原始程式碼 | 套件 (pypi)範例 |

上述鏈接會參考適用於 Python 的 OpenAI API。 沒有 Azure 特定的 OpenAI Python SDK。 瞭解如何在 OpenAI 服務和 Azure OpenAI 服務之間切換。

在本快速入門中,您可以搭配 Azure OpenAI 模型使用自己的數據。 在您的數據上使用 Azure OpenAI 的模型,可提供功能強大的交談式 AI 平臺,讓您更快速且更精確的通訊。

必要條件

使用 Azure OpenAI Studio 新增您的數據

提示

您可以使用 Azure 開發人員 CLI ,以程式設計方式建立 Azure OpenAI On Your Data 所需的資源

流覽至 Azure OpenAI Studio ,並使用可存取 Azure OpenAI 資源的認證登入。 在登入工作流程期間 (或之後),選取適當的目錄、Azure 訂用帳戶和 Azure OpenAI 資源。

  1. 選取 [ 攜帶您自己的數據 ] 圖格

    Azure OpenAI Studio 登陸頁面的螢幕快照。

  2. 在出現的窗格中,選取 [選取數據源] 底下的 [上傳檔案][預覽]。 Azure OpenAI 需要儲存資源和搜尋資源,才能存取及為資料編製索引。

    提示

    1. 若要讓 Azure OpenAI 存取記憶體帳戶,您必須開啟 跨原始來源資源分享 (CORS) 。 如果 Azure Blob 儲存體 資源尚未開啟 CORS,請選取 [開啟 CORS]。

    2. 選取您的 Azure AI 搜尋資源,然後選取連線將會在您的帳戶上產生使用量的通知。 然後選取下一步

    螢幕快照,顯示在 Azure OpenAI Studio 中選取數據源的選項。

  3. 在 [ 上傳檔案 ] 窗格中,選取 [ 瀏覽檔案] ,然後選取您從 必要條件 區段或您自己的數據下載的檔案。 然後選取 [ 上傳檔案]。 然後選取下一步

  4. 在 [ 資料管理 ] 窗格中,您可以選擇啟用 索引的語意搜尋或向量搜尋

    重要

    • 語意搜尋和向量搜尋受限於其他定價。 您必須選擇 [基本] 或更高 SKU ,才能啟用語意搜尋或向量搜尋。 如需詳細資訊,請參閱 定價層差異 和服務 限制
    • 為了協助改善資訊擷取和模型回應的質量,建議您啟用 下列數據源語言的語意搜尋 :英文、法文、西班牙文、葡萄牙文、義大利文、德國、中文(Zh)、日文、韓文、俄文和阿拉伯文。
  5. 檢閱輸入的詳細資料,然後選取 [儲存並關閉]。 您現在可以與模型聊天,並且會使用來自數據的資訊來建構回應。

聊天遊樂場

透過聊天遊樂場,開始使用無程序代碼方法探索 Azure OpenAI 功能。 這隻是一個文字框,您可以在其中提交提示以產生完成。 您可以從此頁面快速反覆運算並實驗功能。

Azure OpenAI Studio 遊樂場頁面的螢幕快照,其中已醒目提示區段。

遊樂場可讓您選擇量身打造聊天體驗。 在右側,您可以選取 [部署 ] 來判斷哪個模型會使用索引中的搜尋結果來產生回應。 您可以選擇過去訊息的數目,以作為未來產生的回應的交談歷程記錄。 交談歷程記錄 提供內容來產生相關的回應,但也會取用 令牌使用方式。 輸入令牌進度指示器會追蹤您提交問題的令牌計數。

左側的進 階設定運行時間參數,可讓您控制從數據擷取和搜尋相關信息。 良好的使用案例是當您想要確定只會根據您的數據產生回應,或您發現模型無法根據數據上存在的信息產生回應時。

  • 嚴格性 會根據系統相似度分數來篩選搜尋檔時,判斷系統的主動性。 將嚴格設定為 5 表示系統會積極篩選出檔,並套用非常高的相似度閾值。 在此案例中,語意搜尋 很有用,因為排名模型會更妥善地推斷查詢的意圖。 較低層級的嚴格度會產生更詳細的答案,但也可能包含不在索引中的資訊。 默認會設定為 3。

  • 擷取的檔 是一個整數,可以設定為 3、5、10 或 20,並控制提供給大型語言模型的檔區塊數目,以制定最終回應。 根據預設,這會設定為5。

  • 啟用 [限制數據回應] 時,模型會嘗試只依賴您的文件進行回應。 根據預設,這會設定為 true。

進階設定的螢幕快照。

傳送您的第一個查詢。 聊天模型在問答練習中表現最佳。 例如,「我的可用健康情況方案為何?」或「什麼是健康情況加號選項?」。

需要數據分析的查詢可能會失敗,例如「哪一個健康情況計劃最受歡迎?」。 需要所有數據相關信息的查詢也可能會失敗,例如「我上傳了多少份檔?」。 請記住,搜尋引擎會尋找具有查詢確切或類似字詞、片語或建構的區塊。 雖然模型可能會了解問題,但如果搜尋結果是數據集中的區塊,則不是回答這類問題的正確資訊。

聊天受限於回應中傳回的檔數(限制為 Azure OpenAI Studio 遊樂場中的 3-20)。 如您所想像,提出有關「所有標題」的問題需要完整掃描整個向量存放區。

部署模型

一旦您對 Azure OpenAI Studio 中的體驗感到滿意,您可以選取 [部署至 ] 按鈕,直接從 Studio 部署 Web 應用程式。

顯示 Azure OpenAI Studio 中模型部署按鈕的螢幕擷取畫面。

這可讓您選擇部署至獨立 Web 應用程式,或在 Copilot Studio 中部署 copilot Studio (預覽版),如果您是 在模型上使用自己的數據

例如,如果您選擇部署 Web 應用程式:

第一次部署 Web 應用程式時,您應該選取 [ 建立新的 Web 應用程式]。 選擇應用程式的名稱,這會成為應用程式URL的一部分。 例如: https://<appname>.azurewebsites.net

選取已發佈應用程式的訂用帳戶、資源群組、位置和定價方案。 若要更新現有的應用程式,請選取 [發佈至現有的 Web 應用程式 ],然後從下拉功能表中選擇上一個應用程式的名稱。

如果您選擇部署 Web 應用程式,請參閱 使用它的重要考慮

擷取必要的變數

若要成功對 Azure OpenAI 進行呼叫,您需要下列變數。 本快速入門假設您已將數據上傳至 Azure Blob 記憶體帳戶,並已建立 Azure AI 搜尋服務索引。 請參閱 使用 Azure AI Studio 新增您的數據

變數名稱
AZURE_OPENAI_ENDPOINT 檢查來自 Azure 入口網站 的 Azure OpenAI 資源時,您可以在 [金鑰與端點] 區段中找到此值。 或者,您可以在 Azure AI Studio>Chat 遊樂場>程式代碼檢視中找到此值。 範例端點為:https://my-resoruce.openai.azure.com
AZURE_OPENAI_API_KEY 當您從 Azure 入口網站 檢查 Azure OpenAI 資源時,可以在資源管理>密鑰和端點一節中找到此值。 您可以使用 KEY1KEY2。 隨時持有兩個金鑰可讓您安全地輪替和重新產生金鑰,而不會造成服務中斷。
AZURE_OPENAI_DEPLOYMENT_ID 此值會對應至您在部署模型時為部署選擇的自定義名稱。 此值可在 Azure 入口網站 的資源管理>部署找到,也可以在 Azure AI Studio 中的管理>部署找到。
AZURE_AI_SEARCH_ENDPOINT 檢查來自 Azure 入口網站 的 Azure AI 搜尋資源時,您可以在 [概觀] 區段中找到此值。
AZURE_AI_SEARCH_API_KEY 從 Azure 入口網站 檢查 Azure AI 搜尋資源時,您可以在 [設定> Keys] 區段中找到此值。 您可以使用主要系統管理員金鑰或次要系統管理員金鑰。 隨時持有兩個金鑰可讓您安全地輪替和重新產生金鑰,而不會造成服務中斷。
AZURE_AI_SEARCH_INDEX 此值會對應至您建立來儲存數據的索引名稱。 當您從 Azure 入口網站 檢查 Azure AI 搜尋資源時,您可以在 [概觀] 區段中找到它

環境變數

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 的新主控台應用程式。 此命令會建立具有單一 C# 原始程式檔的簡單 「Hello World」 專案: 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 AI 服務安全性一文。

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 進行呼叫,您需要下列變數。 本快速入門假設您已將數據上傳至 Azure Blob 記憶體帳戶,並已建立 Azure AI 搜尋服務索引。 如需詳細資訊,請參閱 使用 Azure AI Studio 新增您的數據。

變數名稱
AZURE_OPENAI_ENDPOINT 從 Azure 入口網站 檢查 Azure OpenAI 資源時,您可以在 [金鑰與端點] 區段中找到此值。 或者,您可以在 Azure AI Studio>Chat 遊樂場>程式代碼檢視中找到此值。 範例端點為:https://my-resource.openai.azure.com
AZURE_OPENAI_API_KEY 當您從 Azure 入口網站 檢查 Azure OpenAI 資源時,您可以在資源管理>金鑰和端點一節中找到此值。 您可以使用 KEY1KEY2。 隨時持有兩個金鑰可讓您安全地輪替和重新產生金鑰,而不會造成服務中斷。
AZURE_OPEN_AI_DEPLOYMENT_ID 此值會對應至您在部署模型時為部署選擇的自定義名稱。 您可以在 Azure 入口網站 的資源管理>部署,或在 Azure AI Studio 中的 [管理>部署] 底下找到此值。
AZURE_AI_SEARCH_ENDPOINT 從 Azure 入口網站 檢查 Azure AI 搜尋資源時,您可以在 [概觀] 區段中找到此值
AZURE_AI_SEARCH_API_KEY 當您從 Azure 入口網站 檢查 Azure AI 搜尋資源時,您可以在 [設定> Keys] 區段中找到此值。 您可以使用主要系統管理員金鑰或次要系統管理員金鑰。 隨時持有兩個金鑰可讓您安全地輪替和重新產生金鑰,而不會造成服務中斷。
AZURE_AI_SEARCH_INDEX 此值會對應至您建立來儲存數據的索引名稱。 當您從 Azure 入口網站 檢查 Azure AI 搜尋資源時,您可以在 [概觀] 區段中找到它

環境變數

注意

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 AI 查詢封裝 擷取擴增世代 (RAG) 方法的選項,並隱藏使用者的詳細數據。 或者,您仍然可以直接在應用程式中叫用RAG方法,以查詢 Azure AI 搜尋服務索引中的數據,並使用擷取的文件來增強查詢。

Spring AI 支援 VectorStore 抽象概念,而且您可以將 Azure AI 搜尋包裝在 Spring AI VectorStore 實作中,以查詢自定義數據。 下列專案會實作 Azure AI 搜尋所支援的自定義 VectorStore,並直接執行 RAG 作業。

在Bash視窗中,為您的應用程式建立新的目錄,然後流覽至該目錄。

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

從您的工作目錄執行 spring init 命令。 此命令會為您的 Spring 專案建立標準目錄結構,包括主要 Java 類別來源檔案,以及 用於管理 Maven 型專案的pom.xml 檔案。

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檔案。

    從項目目錄的根目錄中,在慣用的編輯器或 IDE 中開啟 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 資料夾,開啟您慣用編輯器或 IDE 中的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 AI 服務安全性一文。

  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 進行呼叫,您需要下列變數。 本快速入門假設您已將數據上傳至 Azure Blob 記憶體帳戶,並已建立 Azure AI 搜尋服務索引。 請參閱 使用 Azure AI Studio 新增您的數據

變數名稱
AZURE_OPENAI_ENDPOINT 檢查來自 Azure 入口網站 的 Azure OpenAI 資源時,您可以在 [金鑰與端點] 區段中找到此值。 或者,您可以在 Azure AI Studio>Chat 遊樂場>程式代碼檢視中找到此值。 範例端點為:https://my-resoruce.openai.azure.com
AZURE_OPENAI_API_KEY 從 Azure 入口網站 檢查 Azure OpenAI 資源時,可以在資源管理>密鑰和端點一節中找到此值。 您可以使用 KEY1KEY2。 隨時持有兩個金鑰可讓您安全地輪替和重新產生金鑰,而不會造成服務中斷。
AZURE_OPENAI_DEPLOYMENT_ID 此值會對應至您在部署模型時為部署選擇的自定義名稱。 此值可在 Azure 入口網站 中的資源管理>部署找到,或是在 Azure AI Studio 中的管理>部署找到。
AZURE_AI_SEARCH_ENDPOINT 檢查來自 Azure 入口網站 的 Azure AI 搜尋資源時,您可以在 [概觀] 區段中找到此值。
AZURE_AI_SEARCH_API_KEY 檢查來自 Azure 入口網站 的 Azure AI 搜尋資源時,您可以在 [設定> Keys] 區段中找到此值。 您可以使用主要系統管理員金鑰或次要系統管理員金鑰。 隨時持有兩個金鑰可讓您安全地輪替和重新產生金鑰,而不會造成服務中斷。
AZURE_AI_SEARCH_INDEX 此值會對應至您建立來儲存數據的索引名稱。 當您從 Azure 入口網站 檢查 Azure AI 搜尋資源時,您可以在 [概觀] 區段中找到它

環境變數

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

建立節點應用程式

在主控台視窗 (例如 cmd、PowerShell 或 Bash) 中,為您的應用程式建立新的目錄,並瀏覽至該目錄。 然後執行 npm init 命令,以使用 package.json 檔案建立節點應用程式。

npm init

安裝用戶端程式庫

使用 npm 安裝適用於 JavaScript 的 Azure OpenAI 用戶端和 Azure 身分識別連結庫:

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 AI 服務安全性一文。

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 進行呼叫,您需要下列變數。 本快速入門假設您已將數據上傳至 Azure Blob 記憶體帳戶,並已建立 Azure AI 搜尋服務索引。 請參閱 使用 Azure AI Studio 新增您的數據

變數名稱
AZURE_OPENAI_ENDPOINT 檢查來自 Azure 入口網站 的 Azure OpenAI 資源時,您可以在 [金鑰與端點] 區段中找到此值。 或者,您可以在 Azure AI Studio>Chat 遊樂場>程式代碼檢視中找到此值。 範例端點為:https://my-resoruce.openai.azure.com
AZURE_OPENAI_API_KEY 當您從 Azure 入口網站 檢查 Azure OpenAI 資源時,可以在資源管理>密鑰和端點一節中找到此值。 您可以使用 KEY1KEY2。 隨時持有兩個金鑰可讓您安全地輪替和重新產生金鑰,而不會造成服務中斷。
AZURE_OPENAI_DEPLOYMENT_ID 此值會對應至您在部署模型時為部署選擇的自定義名稱。 此值可在 Azure 入口網站 的資源管理>部署找到,也可以在 Azure AI Studio 中的管理>部署找到。
AZURE_AI_SEARCH_ENDPOINT 檢查來自 Azure 入口網站 的 Azure AI 搜尋資源時,可以在 [概觀] 區段中找到此值。
AZURE_AI_SEARCH_API_KEY 當您從 Azure 入口網站 檢查 Azure AI 搜尋資源時,可以在 [設定> Keys] 區段中找到此值。 您可以使用主要系統管理員金鑰或次要系統管理員金鑰。 隨時持有兩個金鑰可讓您安全地輪替和重新產生金鑰,而不會造成服務中斷。
AZURE_AI_SEARCH_INDEX 此值會對應至您建立來儲存數據的索引名稱。 當您從 Azure 入口網站 檢查 Azure AI 搜尋資源時,您可以在 [概觀] 區段中找到它

環境變數

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 的新資料夾,以及名為 main.py 的新 Python 程式代碼檔案。 變更為該目錄:
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 AI 服務安全性一文。

  1. 執行以下 命令:
python main.py

應用程式會以 JSON 格式列印適用於許多案例的回應。 其中包含來自所上傳檔案之查詢和引文的解答。

擷取必要的變數

若要成功對 Azure OpenAI 進行呼叫,您需要下列變數。 本快速入門假設您已將數據上傳至 Azure Blob 記憶體帳戶,並已建立 Azure AI 搜尋服務索引。 請參閱 使用 Azure AI Studio 新增您的數據

變數名稱
AZURE_OPENAI_ENDPOINT 檢查來自 Azure 入口網站 的 Azure OpenAI 資源時,您可以在 [金鑰與端點] 區段中找到此值。 或者,您可以在 Azure AI Studio>Chat 遊樂場>程式代碼檢視中找到此值。 範例端點為:https://my-resoruce.openai.azure.com
AZURE_OPENAI_API_KEY 檢查來自 Azure 入口網站 的 Azure OpenAI 資源時,可以在資源管理>密鑰和端點一節中找到此值。 您可以使用 KEY1KEY2。 隨時持有兩個金鑰可讓您安全地輪替和重新產生金鑰,而不會造成服務中斷。
AZURE_OPENAI_DEPLOYMENT_ID 此值會對應至您在部署模型時為部署選擇的自定義名稱。 此值可在 Azure 入口網站 中的資源管理>部署中找到,或是在 Azure AI Studio 中的管理>部署找到。
AZURE_AI_SEARCH_ENDPOINT 檢查來自 Azure 入口網站 的 Azure AI 搜尋資源時,您可以在 [概觀] 區段中找到此值。
AZURE_AI_SEARCH_API_KEY 檢查來自 Azure 入口網站 的 Azure AI 搜尋資源時,您可以在 [設定> Keys] 區段中找到此值。 您可以使用主要系統管理員金鑰或次要系統管理員金鑰。 隨時持有兩個金鑰可讓您安全地輪替和重新產生金鑰,而不會造成服務中斷。
AZURE_AI_SEARCH_INDEX 此值會對應至您建立來儲存數據的索引名稱。 當您從 Azure 入口網站 檢查 Azure AI 搜尋資源時,您可以在 [概觀] 區段中找到它

環境變數

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 模型使用您的數據來回應。

若要觸發模型的回應,您應該以使用者訊息結尾,指出輪到助理回應。

提示

您可以使用數個參數來變更模型的回應,例如 temperaturetop_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 金鑰保存庫。 如需有關認證安全性的詳細資訊,請參閱 Azure AI 服務安全性一文。

使用 Web 應用程式與您的模型聊天

若要開始與使用數據的 Azure OpenAI 模型聊天,您可以使用 Azure OpenAI Studio 或我們在 GitHub 上提供的範例程式代碼來部署 Web 應用程式 此應用程式會使用 Azure 應用程式服務進行部署,並提供使用者介面來傳送查詢。 此應用程式可以使用 Azure OpenAI 模型來使用您的數據,或不使用數據的模型。 如需需求、設定和部署的指示,請參閱存放庫中的自述檔。 您可以選擇性地自定義 Web 應用程式的前端和後端邏輯 ,方法是對原始程式碼進行變更。

擷取必要的變數

若要成功對 Azure OpenAI 進行呼叫,您需要下列變數。 本快速入門假設您已將數據上傳至 Azure Blob 記憶體帳戶,並已建立 Azure AI 搜尋服務索引。 請參閱 使用 Azure AI Studio 新增您的數據

變數名稱
AZURE_OPENAI_ENDPOINT 檢查來自 Azure 入口網站 的 Azure OpenAI 資源時,您可以在 [金鑰與端點] 區段中找到此值。 或者,您可以在 Azure AI Studio>Chat 遊樂場>程式代碼檢視中找到此值。 範例端點為:https://my-resoruce.openai.azure.com
AZURE_OPENAI_API_KEY 檢查來自 Azure 入口網站 的 Azure OpenAI 資源時,可以在資源管理>密鑰和端點一節中找到此值。 您可以使用 KEY1KEY2。 隨時持有兩個金鑰可讓您安全地輪替和重新產生金鑰,而不會造成服務中斷。
AZURE_OPENAI_DEPLOYMENT_ID 此值會對應至您在部署模型時為部署選擇的自定義名稱。 此值可以在 Azure 入口網站 的資源管理>部署找到,或是在 Azure AI Studio 中的管理>部署找到。
AZURE_AI_SEARCH_ENDPOINT 檢查來自 Azure 入口網站 的 Azure AI 搜尋資源時,您可以在 [概觀] 區段中找到此值。
AZURE_AI_SEARCH_API_KEY 從 Azure 入口網站 檢查 Azure AI 搜尋資源時,您可以在 設定> Keys 區段中找到此值。 您可以使用主要系統管理員金鑰或次要系統管理員金鑰。 隨時持有兩個金鑰可讓您安全地輪替和重新產生金鑰,而不會造成服務中斷。
AZURE_AI_SEARCH_INDEX 此值會對應至您建立來儲存數據的索引名稱。 當您從 Azure 入口網站 檢查 Azure AI 搜尋資源時,可以在 [概觀] 區段中找到它

環境變數

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 的新資料夾,以及名為 sample.go 的新 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 AI 服務安全性一文。

  2. 執行以下 命令:

    go run sample.go
    

    應用程式會列印回應,包括來自所上傳檔案的查詢和引文答案。

擷取必要的變數

若要成功對 Azure OpenAI 進行呼叫,您需要下列變數。 本快速入門假設您已將數據上傳至 Azure Blob 記憶體帳戶,並已建立 Azure AI 搜尋服務索引。 請參閱 使用 Azure AI Studio 新增您的數據

變數名稱
AZURE_OPENAI_ENDPOINT 檢查來自 Azure 入口網站 的 Azure OpenAI 資源時,您可以在 [金鑰與端點] 區段中找到此值。 或者,您可以在 Azure AI Studio>Chat 遊樂場>程式代碼檢視中找到此值。 範例端點為:https://my-resoruce.openai.azure.com
AZURE_OPENAI_API_KEY 檢查來自 Azure 入口網站 的 Azure OpenAI 資源時,可以在資源管理>密鑰和端點一節中找到此值。 您可以使用 KEY1KEY2。 隨時持有兩個金鑰可讓您安全地輪替和重新產生金鑰,而不會造成服務中斷。
AZURE_OPENAI_DEPLOYMENT_ID 此值會對應至您在部署模型時為部署選擇的自定義名稱。 此值可在 Azure 入口網站 的資源管理>部署找到,也可以在 Azure AI Studio 中的管理>部署找到。
AZURE_AI_SEARCH_ENDPOINT 檢查來自 Azure 入口網站 的 Azure AI 搜尋資源時,您可以在 [概觀] 區段中找到此值。
AZURE_AI_SEARCH_API_KEY 檢查來自 Azure 入口網站 的 Azure AI 搜尋資源時,您可以在 設定> Keys 區段中找到此值。 您可以使用主要系統管理員金鑰或次要系統管理員金鑰。 隨時持有兩個金鑰可讓您安全地輪替和重新產生金鑰,而不會造成服務中斷。
AZURE_AI_SEARCH_INDEX 此值會對應至您建立來儲存數據的索引名稱。 當您從 Azure 入口網站 檢查 Azure AI 搜尋資源時,您可以在 [概觀] 區段中找到它

環境變數

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 AI 搜尋索引,並讓 Azure OpenAI 模型使用您的數據來回應。

若要觸發模型的回應,您應該以使用者訊息結尾,指出輪到助理回應。

提示

您可以使用數個參數來變更模型的回應,例如 temperaturetop_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
    }
}

使用 Web 應用程式與您的模型聊天

若要開始與使用數據的 Azure OpenAI 模型聊天,您可以使用 Azure OpenAI Studio 或我們在 GitHub 上提供的範例程式代碼來部署 Web 應用程式 此應用程式會使用 Azure 應用程式服務進行部署,並提供使用者介面來傳送查詢。 此應用程式可以使用 Azure OpenAI 模型來使用您的數據,或不使用數據的模型。 如需需求、設定和部署的指示,請參閱存放庫中的自述檔。 您可以選擇性地自定義 Web 應用程式的前端和後端邏輯 ,方法是對原始程式碼進行變更。

清除資源

如果您想要清除並移除 Azure OpenAI 或 Azure AI 搜尋資源,您可以刪除資源或資源群組。 刪除資源群組也會刪除與其相關聯的任何其他資源。

下一步