透過 Azure API Management 打造可靠的 Azure OpenAI 服務
· 閱讀時間約 8 分鐘
問題
雖然 Azure OpenAI 提供了很強大的服務,但它的一些使用限制,比如每分鐘的 Token 數量(TPM)和每分鐘的請求次數(RPM),對於一些需要大量使用 OpenAI 服務的應用程式來說,可能會造成瓶頸。
這些限制對一般使用者來說可能不太明顯,但對於大型系統卻是不能忽視的問題。
幸好,透過 Azure API Management 可以有效解決這些限制,提升應用程式的效能和穩定性。
- 提升使用者體驗 (UX):透過控制請求速度,避免因超出限制而導致的服務中斷,提供更穩定且一致的服務。
- 提高應用程式彈性:在遇到限制時,自動調整請求策略,確保應用程式可以持續運作。
- 強化錯誤處理:透過 API 管理提供的錯誤處理機制,您可以有效地處理各種錯誤狀態碼,並採取相應的措施。
- 優化模型選擇:您可以根據不同的需求選擇適當的 OpenAI 模型,並透過 API 管理進行有效管理。
- 靈活配置 API 策略:您可以根據實際情況調整 API 策略,例如設定不同的請求速率限制、控制權限等。
- 加強監控和記錄:透過 API 管理的監控功能,您可以追蹤 API 呼叫的流量、性能和錯誤狀況,並進行相關分析。
架構說明
透過 APIM 來管理 Azure OpenAI 服務,當使用者發送請求時,APIM 會根據設定的策略來控制請求速率,並根據服務的狀態來調整請求策略,確保服務的穩定性和可靠性。
當主要 OpenAI 服務發生錯誤時,APIM 會自動切換到次要服務,以確保服務的持續運作。
必要準備
- Azure 訂閱帳戶
- Azure OpenAI 服務
- Azure API Management 服務
- Azure OpenAI API 規格文件
準備 Azure OpenAI API 規格文件
首先我們需要先從官方 Github 中找到 Azure OpenAI API 的 OpenAPI 規格文件,並且下載到本機。
下載完成後,去掉 servers
這個欄位
{
"openapi": "3.0.0",
"info": {
"title": "Azure OpenAI Service API",
"description": "Azure OpenAI APIs for completions and search",
"version": "2024-02-01"
},
"security": [
{
"bearer": ["api.read"]
},
{
"apiKey": []
}
],
...
}
註冊多個 Azure OpenAI 服務到 Azure API Management Backends
- 進入 Azure API Management 服務,從側邊欄點擊
Backends
。 - 點擊
Add
- 填入
- Name: Backend 名稱
- Type:
Custom URL
- Runtime URL:
https://{aoaiHostname}.openai.azure.com/openai
- 點擊
Advanced
,勾選Validate certificate chain
和Validate certificate name
- 在
Authorization credentials
的Headers
新增- Key:
api-key
- Value: Azure OpenAI 服務的 API 金鑰,可以使用 APIM 的 Named value 來存取
- Key:
- 點擊
Create
上傳規格文件到 Azure API Management 建立 API
- 進入 Azure API Management 服務,從側邊欄點擊
API
。 - 點擊
OpenAPI Specification
。 - 點擊
Add a new OpenAPI specification
,然後選擇File
,選擇剛剛下載的 OpenAPI 規格文件 。 - 填入
Display name
和Name
。 - 在
API URL suffix
填入openai
。 - 點擊
Create
.
建立 API Policy
- API 建立完成後,點擊剛剛建好的 API。
- 點擊
All operation
。 - 點擊 Policies
</>
按鈕。 - 複製以下範例,並貼上到編輯器中後儲存。
<policies>
<inbound>
<base />
<!-- default values if wasn't specified by the caller -->
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<!-- 節流方案 https://learn.microsoft.com/zh-tw/azure/api-management/api-management-sample-flexible-throttling -->
<!-- 1. 限速着重於短時間內(例如每分鐘)的請求頻率,旨在防止短時間內過度使用資源。 -->
<!-- 2. 配額則關注於長時間內(例如每天、每月)的總請求量,確保長期內資源的合理分配與使用。 -->
<!-- By Ip 限制請求頻率 https://learn.microsoft.com/en-us/azure/api-management/rate-limit-by-key-policy -->
<!-- 範例中的 calls 屬性設定為 10,表示每個 IP 在 60 秒內最多可以發出 10 個請求。 -->
<rate-limit-by-key calls="10" renewal-period="60" counter-key="@(context.Request.IpAddress)" />
<!-- By Ip 限制使用量配額 https://learn.microsoft.com/zh-tw/azure/api-management/quota-by-key-policy -->
<!-- 範例中的 calls 屬性設定為 100,表示每個 IP 在 3600 秒內最多可以發出 100 個請求。 -->
<quota-by-key calls="100" renewal-period="3600" counter-key="@(context.Request.IpAddress)" increment-condition="@(context.Response.StatusCode >= 200 && context.Response.StatusCode < 400)" first-period-start="2024-01-01T00:00:00Z" />
<!-- By Ip 限制 TPM https://learn.microsoft.com/zh-tw/azure/api-management/azure-openai-token-limit-policy -->
<!-- 範例中的 tokens-per-minute 屬性設定為 5000,表示每個 IP 在每分鐘內最多可以發出 5000 token。 -->
<azure-openai-token-limit counter-key="@(context.Request.IpAddress)" tokens-per-minute="5000" estimate-prompt-tokens="false" remaining-tokens-header-name="remaining-tokens" tokens-consumed-header-name="consumed-tokens" />
<!-- 預設 backend service 名稱為 primary -->
<set-backend-service backend-id="primary" />
</inbound>
<backend>
<retry condition="@(context.Response.StatusCode == 429 || context.Response.StatusCode >= 500)" count="5" interval="1" delta="1" max-interval="8" first-fast-retry="false">
<!-- Failover logic below - uncomment to retry on secondary backend -->
<choose>
<!-- 若發生 aoai service 發生錯誤時,會呼叫另一台名稱為 secondary 的 backend service -->
<when condition="@(context.Response.StatusCode == 429 || context.Response.StatusCode >= 500)">
<set-backend-service backend-id="secondary" />
</when>
</choose>
<forward-request buffer-request-body="true" />
</retry>
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
將 API 加入 Product
- 點擊
Products
。 - 點擊
Add
。 - 填寫必填欄位。
- 加入剛剛建立的 API。
- 點擊
Create
.
測試 API
- 點擊側邊欄的
Subscription
。 - 找到剛剛建立的 Product,並且複製
Key
。 - 可以使用 Postman 或者其他工具來測試 API,下面範例使用 Python OpenAI SDK 來測試。
from openai import AzureOpenAI
apim_endpoint = "APIM 的 Gateway URL"
apim_product_name = "APIM 有註冊 OpenAI API 的 Product Name"
apim_product_subscription_key = "APIM 有註冊 OpenAI API 的 Product Key"
aoai_api_version = "OpenAI 的 API Version"
# 透過 Azure OpenAI SDK 來呼叫 APIM API
# 從 Azure OpenAI SDK 帶入 Product Key
# APIM 會從 Backend 服務選擇 適當的服務,並帶入 API Key,處理請求
aoai = AzureOpenAI(
azure_endpoint=apim_endpoint,
api_key=apim_product_subscription_key,
api_version=aoai_api_version,
default_headers={"Ocp-Apim-Subscription-Key": f"{apim_product_subscription_key};product={apim_product_name}"},
)
messages = [{
"role": "user",
"content": "What are you?"
}]
model = "gpt-35-turbo"
response = aoai.chat.completions.create(
messages=messages,
model=model
)