iT邦幫忙

2026 iThome 鐵人賽

DAY 4
0
AI Engineering

Backend 工程師的 Azure GenAI 實戰系列 第 4

Day 4:Azure OpenAI 的 resource、deployment、model——搞懂哪些名字會進你的 config

  • 分享至 

  • xImage
  •  

現在隨手一搜,還是很容易搜到教你寫 AzureOpenAI(api_version="2024-xx-xx", ...) 的舊文章。但 2026 年開新專案,這已經不是首選寫法。今天要把 Day 3 骨架的第一個真實下游依賴接上 Azure OpenAI;在寫 code 之前,先回答 backend 工程師接任何下游服務都會問的問題:連線設定長什麼樣、哪些名字會進 config、哪些名字改了會弄壞系統?

讀完這篇,你能畫出 Azure OpenAI 的三層結構、分清楚哪些設定屬於 runtime、哪些屬於 provisioning、說出 quota 的完整 scope,並用現行的 v1 API 把設定接進骨架。

三層結構:resource、deployment、model

接一般的下游服務,你的 config 通常是一組 (endpoint, credential)。Azure OpenAI 多一層:

Subscription
└── Resource(例:aoai-<project>,kind=OpenAI)
    ├── endpoint:https://<name>.openai.azure.com/
    ├── region:japaneast(建立時決定,不可改)
    └── Deployment(例:chat-mini)← 名字由你取
        └── Model(例:gpt-5-mini, version 2025-08-07)
            + deployment type(GlobalStandard)+ 分配的 capacity(50K TPM)

Azure OpenAI 三層結構:config 裡的名字對應到哪裡

  • Resource 是計費與存取控制的單位:endpoint、key、region 都掛在這裡。
  • Deployment 是你把某個模型「部署」到 resource 上的實例,名字由你自己取。API 呼叫時 model 參數填的是 deployment name,不是模型名。這是新手最常撞的一面牆。
  • Model 是 Microsoft 託管的模型本體,帶明確版本號。

用 backend 的語言說:deployment name 是一個 CNAME。你的 code 指向 chat-minichat-mini 指向 gpt-5-mini 2025-08-07;哪天要換模型,建新 deployment 後改一行環境變數切換(比原地更新模型版本更安全的做法),application code 一行不動。

Azure 上你命名的東西很多(resource、resource group 也都是你取的名),但 deployment name 特別的地方在於:它是 application runtime 與模型版本之間唯一由你控制的間接層。名字應描述用途而非綁死型號,例如 chat-mini,而不是 gpt-5-mini-deploy

但類比有失真的地方:換 CNAME 指向,下游行為不變;換 deployment 指向的模型,回應行為一定會變。間接層保護的是 Day 3 說的 transport contract(你的 code 不用改),不保護 semantic contract(答案的風格與品質)。換模型仍然是一次要驗證的變更,不是一次改 DNS。

Region、deployment type 與 quota:resource 建在哪,不等於模型在哪裡算

Quota 的完整 scope 是 subscription × region × model × deployment type:每個訂閱在每個 region,針對特定模型與部署類型,各有一個可分配的 TPM(tokens per minute)總額度(查核 2026-07,quota 文件)。

而且它的運作方式是建立時分配,不是執行時分食:建 deployment 時你從這個 pool 劃出一份 capacity,成為該 deployment 自己的 TPM/RPM rate limit;所有 deployment 分配到的 TPM 總和不能超過額度。

所以選 region 不只是選 latency:是在選你拿得到多少額度、以及那個 region 能建哪些模型與部署類型模型與 region 對照)。

本系列的 resource 建在 japaneast。這個訂閱在該 region 能建 gpt-5-mini 的 GlobalStandard deployment,額度也夠;本次從可用 quota 中分配 50K TPM 給 chat-mini,單人開發綽綽有餘。Region 在 resource 建立時就固定,之後要換等於重建,這是少數「第一天就要想清楚」的決定。

一個容易誤會的點:deployment type 是 GlobalStandard 時,推論會由 Azure 全球基礎設施動態路由,prompt 可能在任何 region 的機房處理(查核 2026-07,deployment types 文件)。

https://ithelp.ithome.com.tw/upload/images/20260804/201682881pvihpLhSl.png
忍喵:「resource 在日本,推論不一定在日本——這句值得回頭再讀一次,尤其你家法務坐你隔壁的話。」

那 japaneast 到底保證了什麼?data at rest 留在該 geography、control plane 的位置,以及前面說的 quota 與模型可用性。不是「推論就在日本算」,也不能直接推論低 latency。

如果有單一 region 的資料處理要求,要用 Standard;要限制在 APAC 資料區域,看 DataZoneStandard。Region、deployment type、資料處理邊界——是三件不同的事。

建立資源用的是 repo 裡的 script(Azure CLI 兩條指令的封裝,含防呆;macOS + Azure CLI,2026-07 對 japaneast 實際執行過):

AZ_SUBSCRIPTION_ID=<your-sub> AZ_RESOURCE_GROUP=rg-<yours> \
AZ_LOCATION=japaneast AZ_OPENAI_NAME=aoai-<yours> \
./infra/scripts/create-openai.sh

兩件事值得說。其一,script 強制指定 subscription ID,不吃 az 的預設 context,多訂閱環境下這救過我一次。其二,每個 create script 都有配對的 delete-openai.sh,這是本系列的成本紀律(Day 1 說過的 ephemeral-by-default)。

不過 Standard / GlobalStandard 部署純 token 計費、沒有閒置成本(查核 2026-07,定價頁),所以這顆資源可以常駐:不呼叫就不花錢。建立前先設好 budget alert,我的順序是:預算警報 → 第一顆計費資源,永遠不要反過來。

命名排雷:你查到的文件可能在講同一個東西

寫這篇時最花時間的不是技術,是名詞。這個平台兩年內改了兩次名:Azure AI Studio → Azure AI Foundry(2024-12)→ Microsoft Foundry(2026-01 生效,官方文件)。現在的對照表(查核 2026-07):

你查到的舊名 現在的名字 對你的意義
Azure OpenAI Service Azure OpenAI in Microsoft Foundry Models 服務本體沒變,standalone resource 照樣能開
Azure AI Studio / AI Foundry portal Microsoft Foundry portal(ai.azure.com) 部署模型、看 quota 都在這裡
Azure OpenAI Studio(oai.azure.com) 導向 Foundry portal 舊書籤會自動轉

實務建議:搜尋資料時把「Azure OpenAI」當關鍵字仍然有效(API 與 CLI 層面這個名字都還在,--kind OpenAI),但看到 portal 截圖跟你的畫面對不上時,先確認文章日期,再確認它講的是不是改名前的介面。

https://ithelp.ithome.com.tw/upload/images/20260804/20168288BupDl7W9Zl.png
忍喵:「兩年改兩次名,查資料像在考古。關鍵字照用 Azure OpenAI,畫面對不上先看發文日期。」

v1 API:不用再每月追 api-version 了

過去接 Azure OpenAI 有兩個著名的摩擦點:要用 Azure 專屬的 AzureOpenAI client,以及每月更新的 api-version 字串(功能一更新就得追版號)。2025-08 起的 v1 API 讓兩者對新專案都不再必要(GA,查核 2026-07,官方遷移文件);舊寫法仍受支援,但沒有理由讓新 code 揹著它。

先用同步版 OpenAI client 看最小呼叫(本系列的 FastAPI adapter 用的是同介面的 AsyncOpenAI,避免在 async handler 裡阻塞 event loop):

import os
from openai import OpenAI  # 不是 AzureOpenAI

client = OpenAI(
    api_key=os.environ["AZURE_OPENAI_API_KEY"],
    base_url="https://<your-resource>.openai.azure.com/openai/v1/",
)

response = client.chat.completions.create(
    model="chat-mini",  # deployment name,不是模型名
    messages=[{"role": "user", "content": "ping"}],
)

三個表面差異:標準 OpenAI client 直接用、endpoint 後面接 /openai/v1/不再需要 api-version。SDK client 與主要呼叫形狀更接近 public OpenAI API,但 Azure 特有的 deployment name、認證、quota、region/model 可用性、deployment type 與服務行為仍然存在,還是得靠 adapter 隔離。少掉 api-version,則確實讓 config 少一個會過期的欄位。

這也直接改了我們的骨架。Day 3 的 config.py 裡有一行 azure_openai_api_version: str = "2025-01-01-preview",寫 skeleton 時照舊慣例放的,今天的 milestone 把它拿掉:

class Settings(BaseSettings):
    # ...
    # v1 GA API (2025-08): plain OpenAI client against <endpoint>/openai/v1/, no api-version
    azure_openai_endpoint: str | None = None
    azure_openai_api_key: SecretStr | None = None
    azure_openai_deployment_name: str | None = None

    use_fake_llm: bool = Field(default=True)

新增的 key 欄位用 Pydantic 的 SecretStr:它的 repr 印出來是 **********,log 或錯誤訊息不小心把 settings 倒出來時,key 不會跟著出去。

adapter 端則是把 Day 3 的 fake 佔位換成真假雙軌:use_fake_llm=true(預設)走 fake;提供 endpoint、API key、deployment name,並關掉 flag,才建立真的 client。選擇發生在 composition point,handler 裡沒有任何 if use_fake

完整 wrapper 雛形見 day-04 tag;真正的 chat API 合約是 Day 5 的事。

順帶一提:官方現在推薦 Azure OpenAI 模型優先用 Responses APIclient.responses.create),chat completions 仍完整支援。要選哪個當本系列的 API 基礎,牽涉到 streaming 與工具呼叫的合約設計,留到 Day 5 一起決定。

常見誤解快查

  1. model 參數填模型名」:填的是 deployment name。錯了會拿到 404 DeploymentNotFound,而不是一個好懂的錯誤訊息。
  2. 「quota 是訂閱層級的一個全域數字」:不是。Quota 依 subscription、region、model 與 deployment type 區分,同一 scope 下的 deployments 從同一個額度 pool 分配 capacity(建立時劃走,不是執行時分食)。japaneast 用完,不代表 eastus 的額度也用完;GlobalStandardStandard 也不是同一份 quota。
  3. 「要用 AzureOpenAI client + api-version」:v1 GA 之後標準 OpenAI client 即可。看到教學在傳 api_version 參數,先看發文日期。
  4. 「resource 建在哪,模型就在哪算」GlobalStandard 的推論可能在任何 Azure region 處理;region 保證的是 data at rest 與 control plane。有資料處理位置的要求,要選對 deployment type,不是只選對 region。
  5. 「開著資源就在燒錢」:Standard/GlobalStandard 純 token 計費,閒置為零;會產生閒置成本的是之後的 AI Search 與 PTU 這類預留容量,不是這裡。

小結

今天把 runtime 與 provisioning 的設定邊界弄清楚了:application runtime 需要的是 endpoint、credential、deployment name 三個值;region、model version、deployment type 與 capacity 屬於建立資源時的 control-plane 設定,不進 application code。

deployment name 是 runtime 與模型版本之間由你控制的間接層;quota 的 scope 是 subscription × region × model × deployment type;v1 API 讓 api-version 從 config 消失。

骨架的 config.py.env.example 已更新成 v1 風格,wrapper 雛形就位,完整程式碼在 day-04 tag,該 tag 上 CI 是綠的。

明天(Day 5)開始設計第一個 chat API——不是把 SDK 包一層轉手就好:request/response schema、timeout、retry、error boundary,Day 3 鎖下的 error envelope 終於要接到真的錯誤上了。

(本篇新增雲端資源:Azure OpenAI resource + gpt-5-mini deployment,GlobalStandard 純 token 計費、無閒置成本;建立前已設 US$20 budget alert。)

工程需求 Azure / Microsoft 對應服務 本篇怎麼用
LLM 推論的資源與額度管理 Azure OpenAI in Microsoft Foundry Models 建立 resource(japaneast)與 deployment(gpt-5-mini, GlobalStandard,分配 50K TPM),以 v1 API 接進 FastAPI 骨架的 config

本文由作者規劃與撰寫,AI(Claude)協助草稿整理與程式碼驗證;技術內容與觀點由作者確認並負責。


上一篇
Day 3:FastAPI + uv 專案骨架——第一個 commit 就把合約與成本鎖住
下一篇
Day 5:第一個 Chat API——不是把 SDK 包起來,是決定上游到你為止
系列文
Backend 工程師的 Azure GenAI 實戰5
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言