---
# System prepended metadata

title: MS-Skills 使用 Azure OpenAI 服務開發生成式 AI 解決方案
tags: [AI, MicrosoftLearn]

---

# MS-Skills 使用 Azure OpenAI 服務開發生成式 AI 解決方案

https://learn.microsoft.com/zh-tw/training/paths/develop-ai-solutions-azure-openai/

Azure OpenAI 服務可讓您存取 OpenAI 的強大大型語言模型，例如 ChatGPT、GPT、Codex 和 Embeddings 模型。 這些模型可讓各種自然語言處理 (NLP) 解決方案瞭解、談論及產生內容。 使用者可以透過 REST API、SDK 和 Azure OpenAI Studio 存取該服務。

前置作業
---
- Microsoft Account 建立
- MCID 建立
- PowerShell 安裝
- Visual Studio Code 工具安裝
- Python 環境安裝
- MOC 教材兌換
- Lab操作說明

PowerShell 安裝
---
下載 [PowerShell 安裝檔](https://github.com/PowerShell/PowerShell/releases/download/v7.4.2/PowerShell-7.4.2-win-x64.msi)，安裝最新版。

Visual Studio Code 工具安裝
---
前往 [VS Code 官方網站](https://code.visualstudio.com/Download)，下載最新版安裝。

安裝完成後，啟動 VS Code。

安裝 VS Code開發工具的 Python 擴充功能
![image](https://hackmd.io/_uploads/H1TygJ3SR.png)


Python 環境安裝
---
前往 [Python 官方網站](https://www.python.org/)，下載 Python 3.12.4 安裝包。

以下二個選項請注意要勾選起來，接著按照安裝指引完成安裝。

![image](https://hackmd.io/_uploads/HJvwRAjBR.png)

MOC 教材兌換
---
請分校資教協助同學兌換或協助兌換步驟教學

Lab操作說明
---
* [Lab Github 原始碼專案下載](https://github.com/microsoftlearning/mslearn-openai)
* 每一個Lab都有C#及Python版本
* Lab中所使用到AZURE_OAI_ENDPOINT、API Key、AZURE_OAI_DEPLOYMENT 均以環境變數型式存在，以Python為例，在Lab目錄下有個.env，以VS Code開啟後，把相關值填入即可

開始使用 Azure OpenAI 服務
---
- [課程模組教材](https://learn.microsoft.com/zh-tw/training/modules/get-started-openai/)

#### 學習目標
* 建立 Azure OpenAI 服務資源，並了解 Azure OpenAI 基底模型的類型。
* 使用 Azure OpenAI Studio、主控台或 REST API 來部署基底模型，並在 Studio 的遊樂場中進行測試。
* 產生提示完成並開始管理模型參數。

#### 知識檢定

![image](https://hackmd.io/_uploads/HyqdGhUBC.png)


使用 Azure OpenAI 服務建置自然語言解決方案
---
- [Link](https://learn.microsoft.com/zh-tw/training/modules/build-language-solution-azure-openai/)

#### 學習目標
* 將 Azure OpenAI 整合到您的應用程式中
* 區分應用程式可用的不同端點
* 使用 REST API 和語言特定 SDK 產生提示的完成

#### 使用 Azure OpenAI SDK
![image](https://hackmd.io/_uploads/Bk2MdqUSC.png)

* 安裝程式庫
```
pip install python-dotenv
pip install openai
```
* 設定應用程式以存取 Azure OpenAI 資源
```
# Add OpenAI library
from openai import AzureOpenAI

deployment_name = '<YOUR_DEPLOYMENT_NAME>' 

# Initialize the Azure OpenAI client
client = AzureOpenAI(
        azure_endpoint = '<YOUR_ENDPOINT_NAME>', 
        api_key='<YOUR_API_KEY>',  
        api_version="20xx-xx-xx" #  Target version of the API, such as 2024-02-15-preview
        )
```

* 呼叫 Azure OpenAI 資源
```
response = client.chat.completions.create(
    model=deployment_name,
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "What is Azure OpenAI?"}
    ]
)
generated_text = response.choices[0].message.content

# Print the response
print("Response: " + generated_text + "\n")
```

在 C# 和 Python 中，您的呼叫都可以包含選擇性參數，包括 temperature 和 max_tokens。

#### Lab 實作
* [Step手冊](https://microsoftlearning.github.io/mslearn-openai/Instructions/Exercises/02-natural-language-azure-openai.html)
* [Lab Github 原始碼專案下載](https://github.com/microsoftlearning/mslearn-openai)
```
https://github.com/microsoftlearning/mslearn-openai
```
* SDK使用要點
1. 取得Azure OpenAI的 endpoint(服務端點)
2. 取得Azure OpenAI的 key(服務金鑰)
3. 取得Azure OpenAI的 deployment(模型部署名稱)
4. 指定使用的API 版本
5. 設定system prompt(規劃ChatGPT的角色扮演、負責的任務目標及內容要求)
6. 建立對話歷史記錄

* 02-azure-openai-api/Python 實作1
以下為Lab要加入程式碼的地方
1. **Add Azure OpenAI package**
2. **Initialize the Azure OpenAI client...**
3. **Add code to send request...**(Create a system message+ Send request to Azure OpenAI model+ Print the response)


```
import os
from dotenv import load_dotenv

# Add Azure OpenAI package
from openai import AzureOpenAI


def main(): 
        
    try: 
    
        # Get configuration settings 
        load_dotenv()
        azure_oai_endpoint = os.getenv("AZURE_OAI_ENDPOINT")
        azure_oai_key = os.getenv("AZURE_OAI_KEY")
        azure_oai_deployment = os.getenv("AZURE_OAI_DEPLOYMENT")
        
        # Initialize the Azure OpenAI client...
        client = AzureOpenAI(
            azure_endpoint = azure_oai_endpoint, 
            api_key=azure_oai_key,  
            api_version="2024-02-15-preview"
        )


        while True:
            # Get input text
            input_text = input("Enter the prompt (or type 'quit' to exit): ")
            if input_text.lower() == "quit":
                break
            if len(input_text) == 0:
                print("Please enter a prompt.")
                continue

            print("\nSending request for summary to Azure OpenAI endpoint...\n\n")
            
            # Add code to send request...
            # Create a system message
            system_message = """I am a hiking enthusiast named Forest who helps people discover hikes in their area. 
                If no area is specified, I will default to near Rainier National Park. 
                I will then provide three suggestions for nearby hikes that vary in length. 
                I will also share an interesting fact about the local nature on the hikes when making a recommendation.
                """
            
            # Send request to Azure OpenAI model
            response = client.chat.completions.create(
                model=azure_oai_deployment,
                temperature=0.7,
                max_tokens=400,
                messages=[
                    {"role": "system", "content": system_message},
                    {"role": "user", "content": input_text}
                ]
            )
            generated_text = response.choices[0].message.content
            
            # Print the response
            print("Response: " + generated_text + "\n")

    except Exception as ex:
        print(ex)

if __name__ == '__main__': 
    main()
```

* 02-azure-openai-api/Python 實作2
以下為Lab要加入程式碼的地方
1. **Add Azure OpenAI package**
2. **Initialize the Azure OpenAI client...**
3. **Add code to send request...**(Create a system message + Initialize messages array + Send request to Azure OpenAI model+ Print the response)


```
import os
from dotenv import load_dotenv

# Add Azure OpenAI package
from openai import AzureOpenAI


def main(): 
        
    try: 
    
        # Get configuration settings 
        load_dotenv()
        azure_oai_endpoint = os.getenv("AZURE_OAI_ENDPOINT")
        azure_oai_key = os.getenv("AZURE_OAI_KEY")
        azure_oai_deployment = os.getenv("AZURE_OAI_DEPLOYMENT")
        
        # Initialize the Azure OpenAI client...
        client = AzureOpenAI(
            azure_endpoint = azure_oai_endpoint, 
            api_key=azure_oai_key,  
            api_version="2024-02-15-preview"
        )


        while True:
            # Get input text
            input_text = input("Enter the prompt (or type 'quit' to exit): ")
            if input_text.lower() == "quit":
                break
            if len(input_text) == 0:
                print("Please enter a prompt.")
                continue

            print("\nSending request for summary to Azure OpenAI endpoint...\n\n")
            
            # Add code to send request...
            # Create a system message
            system_message = """I am a hiking enthusiast named Forest who helps people discover hikes in their area. 
                If no area is specified, I will default to near Rainier National Park. 
                I will then provide three suggestions for nearby hikes that vary in length. 
                I will also share an interesting fact about the local nature on the hikes when making a recommendation.
                """
            
            # Initialize messages array
            messages_array = [{"role": "system", "content": system_message}]
            
            
            # Send request to Azure OpenAI model
            messages_array.append({"role": "user", "content": input_text})
            response = client.chat.completions.create(
                model=azure_oai_deployment,
                temperature=0.7,
                max_tokens=1200,
                messages=messages_array
            )
            generated_text = response.choices[0].message.content
            
            # Print the response
            print("Response: " + generated_text + "\n")

    except Exception as ex:
        print(ex)

if __name__ == '__main__': 
    main()
```

#### 知識檢查

![image](https://hackmd.io/_uploads/BySJG38SA.png)


使用 Azure OpenAI 服務套用提示工程
---
- [Link](https://learn.microsoft.com/zh-tw/training/modules/apply-prompt-engineering-azure-openai/)

#### 學習目標
* 了解提示工程的概念，以及其在將 Azure OpenAI 模型效能最佳化方面所扮演的角色。
* 了解如何設計和最佳化提示，以更妥善地利用 AI 模型。
* 包括清楚的指示、要求輸出組合，以及使用內容相關的內容來提升模型回應的品質。
* 提示工程是最佳化 Azure OpenAI 模型效能的重要流程。 提供清楚的指示、要求輸出組合、調整模型參數，以及使用內容相關的內容，可協助改善模型回應的精確度和相關性。 使用 AI 時請務必負責，並請一律記住，AI 模型的回應絕對不應該被視為事實或不受偏差影響。

#### 什麼是提示工程
* 在生成式AI中，"prompt" 是指用來引導或觸發AI生成內容的輸入文本或指令。具體來說，prompt 是用戶提供給AI模型的一段文字或問題，這段文字或問題會告訴AI應該生成什麼樣的內容。根據這個prompt，AI模型會產生相應的文本、圖像、音頻或其他形式的輸出。
* 我們傳送給 AI 模型的輸入提示品質，會直接影響我們取回的內容品質。
* 提示工程是一項設計及最佳化提示，以更妥善地利用 AI 模型的程序。 
* 生成式AI模型會有幻覺，不論您能設計出多麼優秀的提示，AI 模型的回應都不應該被視為事實，或完全不受偏差影響。 請一律負責任地使用 AI

#### API 端點的考量
* Completion 端點可以搭配 gpt-3 和更早版本使用
* ChatCompletion 端點可以搭配 gpt-35-turbo 和更新版本模型使用，ChatCompletion 也可用於非聊天案例。

#### 調整模型參數
* 調整模型的參數可能會對回應產生重大影響。
* temperature 和 top_p (top_probability) 同時控制模型中的隨機性 (不過是以不同的方式)，所以最有可能影響模型的回應。一次變更 temperature 或 top_p 其中一項，但切勿同時變更兩者。
* 較高的值會產生更具創意性和隨機性回應，但可能較不一致或較不專注。 
* 想要更一致且具體的內容，則應該使用較低的值。

#### 撰寫更有效率的提示
* 提供明確的指示
* 指示的格式，位於提示結尾的資訊對輸出產生的影響，可能會比位於開頭的資訊更大。 將重要資訊放在更接近提示結尾，回應的效果可能會更好。
* 使用區段標記
* 格式化指示的特定技術是分割提示開頭或結尾的指示，並讓使用者內容包含在 --- 或 ### 區塊內。 這些標記可讓模型更明確地區分指示和內容。 

#### 主要、支援和基礎內容
* 主要內容是指查詢主體的內容，例如要翻譯的句子或要摘要的文章，假設我們有一篇想進行摘要的長文章。 我們可以將其放在提示中的 --- 區塊中，然後以指示作為結尾。
* 支援內容是可能會改變回應的內容，但不是提示的重點或主旨。支援內容的範例包括名稱、偏好、回應中要包含的未來日期等等。 提供支援內容可讓模型做出更完整且更精確的回應，並且更有可能包含所需的資訊。
* 基礎內容為模型提供內容，使其從中獲取回答，以便讓模型能夠提供可靠的回答。 基礎內容可能是您隨後據以提出問題的短文或文章、公司常見問題集文件，或比模型定型資料更近期的資訊。 如果您需要更可靠的最新回應，或需要參考未發佈或特定資訊，強烈建議使用基礎內容。
* 基礎內容與主要內容不同，因為它是回答提示查詢的資訊來源，而不是用於摘要或翻譯等操作的內容。

#### 提示
* 提示是前置詞，提示模型接下來生成什麼內容，例如，如果您想要協助建立 SQL 查詢，請提供您需要的指示以及查詢的開頭
```
Write a join query to get customer names with purchases in the past 30 days between tables named orders and customer on customer ID. 

SELECT
```

#### 提供內容以提高正確性
* 藉由提供 AI 模型內容，它可讓模型更瞭解您所要求的內容，或應該知道的內容以提供最佳答案。 您可以透過數種方式提供內容。
* 將回應撰寫為電子郵件、將回應格式化為 SQL 查詢、將情緒分類為特定結構等內容
* 系統訊息會在提示的開頭，其設計目的是要提供模型指令、從中回答的觀點，或其他有助於引導模型回應的資訊。 此系統訊息可能包含語氣或個性、不應包含的主題，或回答方式等特定資訊 (如格式)。
```
「我希望你成為從英文到西班牙文的翻譯工具。 不要回應我說的或詢問的任何內容，只要在這兩種語言之間翻譯，並以翻譯的文字回覆。」
```
* 交談歷程記錄可讓模型以類似方式繼續回應。 
* 提示中包含的交談歷程記錄越多，表示會使用較多的輸入權杖（Token）。

#### Few shot learning
* 提供模型範本參考
* 藉由提供模型幾個提示和預期的回應，它會以相同的模式繼續執行

#### 分解複雜工作
* 將複雜的提示分割成多個查詢。 這可讓模型進一步瞭解每個個別的部分，並改善模型整體回應正確性。

#### 思維鏈結
* 要求模型解釋其思維過程

#### Lab
* [Step 手冊](https://microsoftlearning.github.io/mslearn-openai/Instructions/Exercises/03-prompt-engineering.html)
* Lab1
開啟 VS Code 整合式終端機，安裝以下套件
```
pip install openai==1.13.3
```

開啟.env檔案填入Azure OpenAI 參數值
```
AZURE_OAI_ENDPOINT="xxx"
AZURE_OAI_KEY="xxx"
AZURE_OAI_DEPLOYMENT="xxx"
```

開啟python檔案，填入以下程式碼
```
# Add Azure OpenAI package
from openai import AsyncAzureOpenAI
```

```
# Configure the Azure OpenAI client
client = AsyncAzureOpenAI(
    azure_endpoint = azure_oai_endpoint, 
    api_key=azure_oai_key,  
    api_version="2024-02-15-preview"
    )
```

在call_openai_model方法加入以下程式碼
```
# Format and send the request to the model
messages =[
    {"role": "system", "content": system_message},
    {"role": "user", "content": user_message},
]

print("\nSending request to Azure OpenAI model...\n")

# Call the Azure OpenAI model
response = await client.chat.completions.create(
    model=model,
    messages=messages,
    temperature=0.7,
    max_tokens=800
)
```

開啟 VS Code 整合式終端機
```
python prompt-engineering.py
```

* Lab2
開啟 system.txt 檔案，對於每次的迭代，您需要在該檔案中輸入 system prompt 並儲存它

sample1 
```
You are an AI assistant
```
sample2 
```
You are an AI assistant helping to write emails
```
sample3
```
You are an AI assistant helping to write emails
```
sample4
```
You are an AI assistant that helps write promotional emails to generate interest in a new business. Your tone is light, chit-chat oriented and you always include at least two jokes.
```

* Lab3
新增以下代碼片段，以從 grounding.txt 中讀取文本，並使用這些基礎內容來增強用戶提示。
```
// Format and send the request to the model
Console.WriteLine("\nAdding grounding context from grounding.txt");
string groundingText = System.IO.File.ReadAllText("grounding.txt");
userMessage = groundingText + userMessage;
```
開啟 system.txt 檔案，輸入以下內容
```
You're an AI assistant who helps people find information. You'll provide answers from the text provided in the prompt, and respond concisely.
```

#### 知識檢定
![image](https://hackmd.io/_uploads/rkBCsK9BR.png)


使用 Azure OpenAI 服務產生程式碼
---
- [Link](https://learn.microsoft.com/zh-tw/training/modules/generate-code-azure-openai/)

#### 學習目標
* 使用自然語言提示撰寫程式碼
* 使用 AI 模型建置單元測試並了解複雜的程式碼
* 產生現有程式碼的註解與文件

#### 透過自然語言建構程式碼
gpt 模型中，有些模型已經過專門定型以搭配程式碼 (通常稱為 codex 模型) 一起使用。 隨著新世代的模型演進，基底模型會大幅改善其效能以及對語言和程式碼的理解，從而不需要特定的程式碼模型。 這項改進為更新的世代 (例如 gpt-35-turbo 和 gpt-4) 產生單一模型，可用於自然語言和程式碼。

Azure OpenAI 模型的其中一個功能是透過自然語言提示產生程式碼。 工作的範圍可以從簡單的單行命令到完整的應用程式。

* 如果您有一種語言的程式碼，但需要轉換成另一種語言，Azure OpenAI 可以為您進行翻譯。例如提供C#要求轉成Python
* 理解未知的程式碼，要求模型解釋說明程式碼及邏輯

#### 完成程式碼並協助開發流程
* 模型能够根據註解、函式名稱和部分撰寫的程式碼產生後續的程式碼。例如給予模型註解說明，模型自動完成Function的撰寫
* 模型可以為您撰寫的函式產生單元測試，以協助您的程式碼更加強固。
* 針對已存在的程式碼，新增註解並產生文件

#### 修正錯誤並改善程式碼
* 模型可藉由分析程式碼，並建議可能修正問題的變更，以協助修正程式碼中的錯誤
* 改善效能
* 重構效率不佳的程式碼

#### Lab
* [Step手冊](https://microsoftlearning.github.io/mslearn-openai/Instructions/Exercises/04-code-generation.html)
* Lab 1
開啟 VS Code 整合式終端機，安裝以下套件
```
pip install openai==1.13.3
```

開啟.env檔案填入Azure OpenAI 參數值
```
AZURE_OAI_ENDPOINT="xxx"
AZURE_OAI_KEY="xxx"
AZURE_OAI_DEPLOYMENT="xxx"
```

開啟python檔案，找到call_openai_model方法，填入以下程式碼

```
# Format and send the request to the model
messages =[
    {"role": "system", "content": system_message},
    {"role": "user", "content": user_message},
]

# Call the Azure OpenAI model
response = client.chat.completions.create(
    model=model,
    messages=messages,
    temperature=0.7,
    max_tokens=1000
)
```

開啟 VS Code 整合式終端機
```
python code-generation.py
```

1. 選擇選項1來為您的代碼新增註解，並輸入以下提示。請注意，這些任務的每個步驟可能需要幾秒鐘的時間。

輸入以下user prompt
```
Add comments to the following function. Return only the commented code.\n---\n
```

生成結果寫入在 result/app.txt

2. 選擇選項2來為相同的函數編寫單元測試，並輸入以下提示。

輸入以下user prompt
```
Write four unit tests for the following function.\n---\n
```

生成結果寫入在 result/app.txt

3. 選擇選項3來修復一個用於玩 Go Fish 遊戲的應用程式中的錯誤，並輸入以下提示。

輸入以下user prompt
```
Fix the code below for an app to play Go Fish with the user. Return only the corrected code.\n---\n
```

生成結果寫入在 result/app.txt


#### 知識檢定
![image](https://hackmd.io/_uploads/rkVxSh5HA.png)


使用 Azure OpenAI 服務產生影像
---
- [Link](https://learn.microsoft.com/zh-tw/training/modules/generate-images-azure-openai/)

#### 學習目標
* 描述 Azure openAI 服務中 DALL-E 的功能
* 在 Azure OpenAI Studio 中使用 DALL-E 遊樂場
* 使用 Azure OpenAI REST 介面，將 DALL-E 影像產生整合到您的應用程式

#### 什麼是 DALL-E
* 可以向 DALL-E 提供描述(Prompt)，DALL-E 就能產生適當的影像。
* DALL-E 所產生的影像是原創影像；而不是擷取自從策展的影像目錄。 換句話說，DALL-E 不是尋找適當影像的搜尋系統，它是一種人工智慧 (AI) 模型，可根據其訓練資料來產生新影像。

#### 在 Azure OpenAI Studio 中探索 DALL-E
* 產生影像的解析度 (大小)。 可用的大小為 256x256、512x512、1024x1024 (這是預設值)，或 1024x1792。
* 要產生的影像樣式 (例如 vivid 或 natural)。
* 影像品質 (從 standard 或 hd選擇)。

#### 使用 Azure OpenAI REST API 取用 DALL-E 模型
* 必須具備已在 Azure 中佈建的 Azure OpenAI 服務資源的端點和授權金鑰
* 使用標頭中的授權金鑰將 POST 要求提交至服務端點
* 請求必須在 JSON 本文中包含下列參數：prompt：要產生之影像的描述、n：要產生的影像數目、size：要產生之影像的解析度 (256x256、512x512 或 1024x1024)
```
{
    "prompt": "A badger wearing a tuxedo",
    "n": 1,
    "size": "512x512"
}
```
* 不會立即傳回影像產生程序的結果，實際上回應會包含 operation-location 標頭，內附回呼服務的 URL 供應用程式程式碼輪詢，直到影像產生的結果就緒。
* 作業成功時，會傳回類似於下列 JSON 的回應，result 元素包含 url 元素的集合，每個元素分別會參考一個從提示產生的 PNG 影像檔
```
{
    "created": 1686780744,
    "expires": 1686867152,
    "id": "6d765598-eeee-4f49-885d-03ee1c8f9b02",
    "result": {
        "created": 1686780744,
        "data": [
            {
                "url": "https://dalleproduse.....png"
            }
        ]
    },
    "status": "succeeded"
}
```

#### Lab
* [Step手冊](https://microsoftlearning.github.io/mslearn-openai/Instructions/Exercises/05-generate-images.html)
* Lab 1
開啟.env檔案填入Azure OpenAI 參數值
```
AZURE_OAI_ENDPOINT="https://xxxxx.openai.azure.com/"
AZURE_OAI_KEY="xxxxx"
```

程式碼說明
1. HTTPS 請求
代碼向服務端點發出 HTTPS 請求。
請求中包含服務的金鑰，這些值都從配置文件中獲得。
2. 請求參數
圖像提示（用於生成圖像的基礎）。
要生成的圖像數量。
生成圖像的大小。
3. 回應內容
回應包括 DALL-E 模型從用戶提供的提示中推斷出的更具描述性的提示。
回應還包含生成圖像的 URL。

開啟 VS Code 整合式終端機
```
pip install requests
python generate-image.py
```

#### 知識檢定
![image](https://hackmd.io/_uploads/ryTXwn9r0.png)


實作如何搭配 Azure OpenAI 服務使用檢索增強生成 (RAG)
---
- [Link](https://learn.microsoft.com/zh-tw/training/modules/use-own-data-azure-openai/)

#### 學習目標
* 描述 Azure OpenAI 對於資料的功能
* 設定 Azure OpenAI 以使用自己的資料
* 使用 Azure OpenAI API 以根據自己的資料產生回應

> RAG（Retrieval-Augmented Generation）是一種結合檢索和生成技術的AI方法，旨在提高文本生成的準確性和相關性。RAG模型由兩個主要組成部分構成：檢索器（Retriever）和生成器（Generator）。

* 檢索器（Retriever）：
檢索器負責從一個大型數據庫或知識庫中檢索與用戶輸入（即query）相關的文檔或資訊。這個過程可以理解為一個高效的搜索操作，目的是找到最相關的資料來輔助生成部分的工作。
* 生成器（Generator）：
生成器是一個文本生成模型（如GPT-3），它會根據檢索器提供的相關資料和用戶的輸入，生成最終的回答或內容。生成器不僅依賴於用戶輸入的prompt，還會利用檢索到的文檔內容來生成更具上下文相關性和準確性的回答。

#### 了解擷取增強產生 (RAG) 與 Azure OpenAI 服務
* RAG 可讓開發人員使用支援的 AI 聊天模型，用參考特定資訊來源來建立回應基礎。
* 新增這項資訊可讓模型參考提供的特定資料與其預先訓練的知識，以提供更有效的回應。
* Azure OpenAI 可將預先定型的模型連線到您自己的資料來源，以啟用 RAG。
* Azure OpenAI 可利用 Azure AI 搜尋服務的搜尋能力，將相關的資料區塊新增至提示。
1. 接收使用者提示。
2. 判斷提示的相關內容和意圖。
3. 使用該內容和意圖查詢搜尋索引。
4. 將搜尋結果區塊與系統訊息和使用者提示一起插入到 Azure OpenAI 提示中。
5. 將整個提示傳送至 Azure OpenAI。
6. 將回應和資料參考 (如果有) 傳回給使用者。

> 根據預設，基於資料的 Azure OpenAI 建議 (但不要求) 模型僅使用您的資料進行回應。 連線到資料時，可以取消選取此設定，這可能會導致模型選擇使用其預先訓練的知識，而不是您的資料。

* 微調與RAG
1. 微調是一種用來建立自訂模型的技術，其方式是使用其他訓練資料的資料集訓練現有的基礎模型 (例如 gpt-35-turbo)。 
2. 微調的流程既昂貴又耗時，應僅用於必要的使用案例。

#### 新增您自己的資料來源
* 透過 Azure OpenAI Studio 完成新增資料
1. 選擇上傳資料檔案
2. 使用 Blob 儲存體帳戶中的資料
3. 連線至現有的 AI 搜尋索引
*  Azure OpenAI 支援 .md、.txt、.html、.pdf，以及 Microsoft Word 或 PowerPoint 檔案
*  支援圖形或影像OCR
*  啟用 AI 搜尋服務的語意搜尋可以改善搜尋資料索引的結果，而且您可能會收到更高品質的回應和引文。 不過，啟用語意搜尋可能會增加搜尋服務的成本。

#### 使用自己的資料來與模型聊天
* 語彙基元Token
* 模型的呼叫都包含系統訊息、使用者提示、交談歷程記錄、擷取的搜尋文件、內部提示以及模型回應的語彙基元
* 系統訊息是模型指令的實用參考，包含在每次呼叫之內。
* 系統訊息沒有語彙基元限制，但使用自己的資料時，超過 200 個語彙基元的系統訊息會遭到截斷。 
* 使用自己的資料時，模型回應也有 1,500 個語彙基元的上限。
* 使用 API 搭配自己的資料時，您必須指定儲存資料的資料來源。 每個呼叫都需要包含 AI 搜尋服務資源的 endpoint、key 和 indexName。

#### Lab
* Lab1 使用Azure AI Studio Playground建立RAG應用 [Step手冊](https://microsoftlearning.github.io/mslearn-openai/Instructions/Exercises/06-use-own-data.html#connect-your-data-in-the-chat-playground)
1. 在Azure Portal 建立Azure OpenAI Service
區域請選擇以下之一 : 
Australia East
Canada East
East US
East US 2
France Central
Japan East
North Central US
Sweden Central
Switzerland North
UK South

付費層級 : Standard S0

2. 進入 Azure OpenAI Studio 部署模型
![image](https://hackmd.io/_uploads/HJ2dQDMI0.png)

選擇部署 gpt-35-turbo-16k 模型 (配置以下參數值)
![image](https://hackmd.io/_uploads/HkaqVwGLA.png)

3. 在聊天遊樂場playground，在setup部分，選擇「add your data」，選擇「新增資料來源」。
![image](https://hackmd.io/_uploads/Bk5OrPMLR.png)

4. 選擇「Upload files.」，建立新的Azure Blob Storage + 新的Azure AI Search
![image](https://hackmd.io/_uploads/Hy9WLwGUA.png)

建立新的Azure Blob Storage，資源群組及區域請與原本Azure OpenAI 服務一樣，價格層選擇Basic，備援選擇 Locally-redundant storage (LRS)
![image](https://hackmd.io/_uploads/HkssPwfU0.png)

啟用CORS
![image](https://hackmd.io/_uploads/r1tL_DfIR.png)


建立新的 Azure AI Search，資源群組及區域請與原本 Azure OpenAI 服務一樣，價格層選擇Basic
![image](https://hackmd.io/_uploads/S1JndPzLA.png)

輸入索引名稱 : margiestravel
![image](https://hackmd.io/_uploads/BkMf9DMLC.png)

5. 上傳所有Lab中的[PDFs](https://aka.ms/own-data-brochures)
![image](https://hackmd.io/_uploads/ryhI9DGL0.png)

6. 搜尋類型選擇「關鍵字」
![image](https://hackmd.io/_uploads/SynY5DMLR.png)


7. 開啟另一個瀏覽器分頁，設置三個服務間的連線權限配置，首先 Azure AI Search　啟用 RBAC 驗證(選both可保留API使用)
![image](https://hackmd.io/_uploads/BJVdf1zLC.png)

8. Azure AI Search 啟用 system assigned managed identity
![image](https://hackmd.io/_uploads/By-3iwzI0.png)

9. Azure OpenAI 服務啟用 system assigned managed identity
![image](https://hackmd.io/_uploads/rkHs3vzUR.png)


10. 角色指派(要設定好才能正確跨服務互通)
![image](https://hackmd.io/_uploads/H1f5tR-I0.png)

授予角色權限的操作方式
* 授予角色權限
![image](https://hackmd.io/_uploads/BJxSpDzLC.png)
* 查詢角色
![image](https://hackmd.io/_uploads/S1y6pDfUC.png)
* 授予給誰用
![image](https://hackmd.io/_uploads/S1CxAvGL0.png)
* 查詢目前授予角色權限的清單
![image](https://hackmd.io/_uploads/HJvaAvGUC.png)

需要10分鐘才會生效變更

11. 確認 Azure AI Search 的 Access control (IAM)，授予 Azure OpenAI 以下 ROLE：**Search Index Data Reader**、**Search Service Contributor**
12. 確認 Azure Blob Storage 的 Access control (IAM)，授予 Azure AI Search 以下 ROLE：**Storage Blob Data Contributor** 
13. 確認 Azure Blob Storage 的 Access control (IAM)，授予 Azure OpenAI 以下 ROLE：**Storage Blob Data Contributor** 
14. 確認 Azure OpenAI 的 Access control (IAM)，授予 Azure AI Search 以下 ROLE：**Cognitive Services OpenAI Contributor** 
15. 輸入索引鍵名稱 : margiestravel
16. 上傳檔案
17. 搜尋類型 : 關鍵字
18. 資料連線選擇「系統指派的受控識別」如果發生錯誤，改用「API KEY識別」

16. 輸入以下Prompt
```
I'd like to take a trip to New York. Where should I stay?
```

```
What are some facts about New York?
```

* Lab2 application

開啟 VS Code 整合式終端機，安裝以下套件
```
pip install openai==1.13.3
```

開啟.env檔案填入Azure OpenAI 參數值
```
AZURE_OAI_ENDPOINT="xxxx"
AZURE_OAI_KEY="xxxx"
AZURE_OAI_DEPLOYMENT="xxxxx"
AZURE_SEARCH_ENDPOINT="xxxxx"
AZURE_SEARCH_KEY="xxxxxx"
AZURE_SEARCH_INDEX="xxxxx"
```

開啟python檔案，填入以下程式碼
```
# Configure your data source
extension_config = dict(dataSources = [  
        { 
            "type": "AzureCognitiveSearch", 
            "parameters": { 
                "endpoint":azure_search_endpoint, 
                "key": azure_search_key, 
                "indexName": azure_search_index,
            }
        }]
    )
```

開啟 VS Code 整合式終端機
```
python ownData.py
```


#### 知識檢定
![image](https://hackmd.io/_uploads/r1MBlA5B0.png)


負責任衍生 AI 的基本概念
---
- [Link](https://learn.microsoft.com/zh-tw/training/modules/responsible-generative-ai/)

#### 學習目標
* 描述負責任的生成式 AI 解決方案開發的整體流程
* 識別與生成式 AI 解決方案相關的潛在危害並設定優先權
* 測量生成式 AI 解決方案中是否有危害
* 減輕生成式 AI 解決方案中的危害
* 準備負責任地部署及操作生成式 AI 解決方案

#### 規劃負責任生成式 AI 解決方案
* 找出與您計畫解決方案相關的潛在損害。
* 衡量解決方案所產生的輸出中是否有這些損害。
* 降低解決方案中多層的損害，以將其存在和影響降到最低，並確保對使用者的潛在風險溝通透明。
* 定義並遵循部署和作業整備計畫，以負責任地操作解決方案。

#### 識別潛在危害
* 識別潛在危害
* 優先處理已識別的危害
* 測試並確認已優先處理的危害
* 記錄並共用已驗證的危害

#### 測量潛在危害
* 準備輸入提示的各種有害的選取項目
* 將提示提交至系統並擷取所產生的輸出。
* 套用預先定義的準則來評估輸出，並根據它所包含的潛在危害層級加以分類。

#### 減輕潛在危害
* 模型
選取適合使用之解決方案的模型。 例如，雖然 GPT-4 可能是功能強大的多用途模型，但解決方案中只需要分類小型的特定文字輸入，較簡單的模型可能會提供具有較低有害內容產生風險的必要功能。
* 安全系統
例如，Azure OpenAI 服務包含內容篩選支援，這些篩選準則會根據內容分類為四個嚴重性層級來隱藏提示和回應 (安全、低、中，以及高)，搭配四種類別的潛在傷害 (仇恨、性、暴力和自我傷害)。
* Metaprompt 和基礎
1. 指定中繼提示或系統輸入，以定義模型的行為參數。
2. 套用提示工程，將基礎資料新增至輸入提示，將相關、非共用輸出的可能性最大化。
3. 使用擷取增強產生 (RAG) 方法來擷取信任資料來源的內容資料，並將其包含在提示中。
* 使用者體驗
設計應用程式使用者介面以限制特定主體或類型的輸入，或套用輸入和輸出驗證，可以降低潛在有害回應的風險。

#### 操作負責任的生成式 AI 解決方案
在發行生成式 AI 解決方案之前，請先識別組織和產業中的各種合規性需求，並確保適當的小組有機會檢閱系統及其文件。 常見的合規性檢閱包括：
* 法務
* 隱私權
* 安全性
* 網頁可及性

#### Lab

#### 知識檢定
![image](https://hackmd.io/_uploads/rJUuORiSC.png)

證書評量測驗
---
#### 前置作業

![image](https://hackmd.io/_uploads/rkDMgOhr0.png)
* 在虛擬機器中，您可以存取 OpenAI 版本 1.6.1 的 Python 用戶端程式庫和 .NET 版本 1.0.0-beta.12 的 Azure OpenAI 用戶端程式庫。
* 開啟瀏覽，登入Azure Portal，使用評量用的帳戶，並在現有的資源群組下，完成以下任務
1. 進入預設已建立的"資料群組"
2. 預設在該資源群組下已建立有　AI Search服務＋Azure Storage服務
3. 請在此資源組中以及與此資源組相同的區域中建立所有 Azure 物件。建立Azure OpenAI服務(Region請與預設已建立的AI Search服務相同)
![image](https://hackmd.io/_uploads/rkcWjDNUR.png)

4. 部署指定的模型，注意題目要求的配置值
GPT-35-turbo-16k 模型
在「部署模型」對話方塊中，您必須選擇「進階」選項並將「每分鐘令牌數速率限制（千）」設定設為 5K
還必須將啟用動態配額設定設定為停用。


* 使用VS Code開啟專案C:/files/AzureOpenAIPoc，安裝套件，請依題目要求的版本安裝
```
pip install openai==1.6.1
```

* 開啟.env檔案，填入Azure OpenAI/Azure AI Search 設定值
![image](https://hackmd.io/_uploads/HybjmqnHR.png)

* 開啟poc.py修改main方法
```
# Add OpenAI import. (Add code here)
from openai import AzureOpenAI
```

```
# Define Azure OpenAI client (Add code here)
client = AzureOpenAI(
                azure_endpoint = azure_oai_endpoint, 
                api_key=azure_oai_key,  
                api_version="2023-12-01-preview"
                )
```

#### Task 1: Validate PoC
修改sample-text.txt內容(prompt)
找到function1修改程式碼
```
# Build messages to send to Azure OpenAI model. (Add code here)
messages=[
        {"role": "user", "content": inputText}
    ]
```

```
# Define argument list (Add code here)
apiParams = {
    "model":aiModel,
    "temperature":0.5,
    "max_tokens":400,
    "messages": messages,
}
```

```
# Call chat completion connection. (Add code here)
# Use the call name and **apiParams to reference our argument list
response = aiClient.chat.completions.create(**apiParams)
```


#### Task 2: Company chatbot
修改sample-text.txt內容(prompt)
找到function2修改程式碼
```
# Build messages to send to Azure OpenAI model. (Add code here)
messages=[
    {"role": "system", "content": inputText},
    {"role": "user", "content": "What is the best way to find if a company is hiring?"}
]
```

```
# Define argument list (Add code here)
apiParams = {
    "model":aiModel,
    "temperature":0.5,
    "max_tokens":1000,
    "messages": messages
}
```

```
# Call chat completion connection. (Add code here)
# Use the call name and **apiParams to reference our argument list
response = aiClient.chat.completions.create(**apiParams)
```

修改sample-text.txt內容(prompt)
```
You are a customer service assistant at Contoso. You must abide by the following rules every time you answer user questions.

1. At the end of each reply, "Hope that helps! Thanks for using Contoso, Ltd."
2. The reply content must include English and Spanish, both languages

[Reference example]
user: Where can I find the company phone number?
assistant : You can find it on the footer of every page on our website. Hope that helps! Thanks for using Contoso, Ltd.
```


#### Task 3: Developer tasks
本題有二個任務要求
1. 第1個任務
修改sample-text.txt內容(prompt)
```
You are a python expert that helps programmers write code.
```
找到function3修改程式碼
```
# Build messages to send to Azure OpenAI model. (Add code here)
    
file = open(file="../../legacyCode.py", encoding="utf8").read()
prompt = "Add comments to my function  and generate documentation  \n [my function] \n " + file
messages=[
        {"role": "system", "content": inputText},
        {"role": "user", "content": prompt}
    ]
```

```
# Define argument list (Add code here)
apiParams = {
    "model":aiModel,
    "temperature":0.2,
    "max_tokens":1500,
    "messages": messages
}
```

```
# Call chat completion connection. (Add code here)
# Use the call name and **apiParams to reference our argument list
response = aiClient.chat.completions.create(**apiParams)
```

2. 第2個任務
修改sample-text.txt內容(prompt)
```
You are a python expert that helps programmers write unit test case code.
```
找到function3修改程式碼
```
# Build messages to send to Azure OpenAI model. (Add code here)
    
file = open(file="../../fibonacci.py", encoding="utf8").read()
prompt = "Write five unit tests case code for the following function.\n [my function] \n" + file
messages=[
        {"role": "system", "content": inputText},
        {"role": "user", "content": prompt}
    ]
```

```
# Define argument list (Add code here)
apiParams = {
    "model":aiModel,
    "temperature":0.2,
    "max_tokens":1500,
    "messages": messages
}
```

```
# Call chat completion connection. (Add code here)
# Use the call name and **apiParams to reference our argument list
response = aiClient.chat.completions.create(**apiParams)
```

#### Task 4: Use company data
修改sample-text.txt內容(prompt)
```
You are a helpful travel agent.
```

修改.env內容
```
SEARCH_ENDPOINT="從azure上的 ai search 取得"
SEARCH_KEY="從azure上的 ai search 取得"
SEARCH_INDEX="pocindex"
```

修改 Azure AI Search 認證方式
![image](https://hackmd.io/_uploads/ByeC8_E8A.png)

![image](https://hackmd.io/_uploads/S1HMw_4UA.png)

修改 Azure OpenAI Service 認證方式
![image](https://hackmd.io/_uploads/HJrZKOEU0.png)


確認 Azure AI Search 的 Access control (IAM)，授予 Azure OpenAI 以下 ROLE：Search Index Data Reader、Search Service Contributor

確認 Azure Blob Storage 的 Access control (IAM)，授予 Azure AI Search 以下 ROLE：Storage Blob Data Contributor

確認 Azure Blob Storage 的 Access control (IAM)，授予 Azure OpenAI 以下 ROLE：Storage Blob Data Contributor

確認 Azure OpenAI 的 Access control (IAM)，授予 Azure AI Search 以下 ROLE：Cognitive Services OpenAI Contributor

進到 Azure AI Search，選擇 Import data
![image](https://hackmd.io/_uploads/rJXOod480.png)

配置Connect to your data，其中Connection string 的部份，請直接選擇blob1即可，配置後直接按下一步，然後Skip to Customize target index
![image](https://hackmd.io/_uploads/BJEO3uN8R.png)
![image](https://hackmd.io/_uploads/Hk4T3O4LR.png)

Index name 填入 pocindex，配置後直接按下一步到最後即可
![image](https://hackmd.io/_uploads/SJhDadEIA.png)

完成後，請到Indexes中確認是否有資料
![image](https://hackmd.io/_uploads/BJQxCON8C.png)


找到function4修改程式碼
```
# Build messages to send to Azure OpenAI model. (Add code here)
messages=[
        {"role": "system", "content": inputText},
        {"role": "user", "content": "When is the best time to visit London?"},
    ]
  
```

```
# Define argument list (Add code here)
apiParams = {
        "model":aiModel,
        "temperature":0.2,
        "max_tokens":1500,
        "messages": messages
    }
```

```
# Call chat completion connection. (Add code here)
# Use the call name and **apiParams to reference our argument list
response = aiClient.chat.completions.create(**apiParams)
```

###### tags: `MicrosoftLearn` `AI`
