Azure OpenAI 的
model參數本質上填的是 deployment name,不是底層模型名。你把gpt-4o、text-embedding-3-large這類模型名直接塞進去,最常見的結果就是 404 或deployment not found。
Issue & Env(案發現場與環境)
- 業務場景:項目原來連 OpenAI,後來切到 Azure OpenAI,仍然沿用原有的模型名設定。
- 常見環境:Spring AI 2.0.0-M5 之後,Azure OpenAI 接入建議統一走 OpenAI Chat 接口;底層 endpoint 換成 Azure,但設定心智還是 OpenAI 的寫法。
StackTrace(堆疊日誌)
最典型的報錯是 Azure 直接返回 404,錯誤響應原文:
{
"error": {
"code": "DeploymentNotFound",
"message": "The API deployment for this resource does not exist."
}
}
在 Java 客戶端或 Spring 應用日誌裡,通常會被包裝成 HttpClientErrorException$NotFound。報錯原文:
org.springframework.web.client.HttpClientErrorException$NotFound: 404 Not Found on POST request for "https://my-resource.openai.azure.com/openai/deployments/gpt-4o/chat/completions"
完整堆疊,從 HTTP 客戶端一路回到業務調用:
org.springframework.web.client.HttpClientErrorException$NotFound: 404 Not Found on POST request for "https://my-resource.openai.azure.com/openai/deployments/gpt-4o/chat/completions"
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:123)
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:103)
at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63)
at org.springframework.web.client.RestClient$DefaultResponseSpec$DefaultBodySpec.evaluate(RestClient.java:1187)
at org.springframework.ai.chat.client.DefaultChatClient$DefaultChatClientRequestSpec$InternalChatClientRequest.call(DefaultChatClient.java:686)
at com.example.demo.chat.AzureOpenAiService.chat(AzureOpenAiService.java:31)
at com.example.demo.chat.ChatController.chat(ChatController.java:19)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
Reproduce(復現程式碼)
很多項目是這樣遷移過來的:
spring:
ai:
openai:
base-url: https://my-resource.openai.azure.com/openai
api-key: ${AZURE_OPENAI_API_KEY}
chat:
options:
model: gpt-4o
如果你在 Azure 門戶裡真實創建的 deployment 名字叫 prod-gpt4o-chat,上面這個設定就會炸。因為 Azure 認的是 deployment name,而不是底層模型標識。
Root Cause(根因分析)
Azure OpenAI 和原生 OpenAI 看起來都在用同一個客戶端接口,但模型尋址方式不一樣。
OpenAI 認模型名
在原生 OpenAI 裡,model="gpt-4o" 就是指這個模型本身。
Azure OpenAI 認 deployment name
微軟文檔把這個差異寫得很明確:當你通過 Azure OpenAI 調 API 時,model 參數必須對應你在 Azure 裡創建的 deployment name。官方文檔裡很多示例會故意把 deployment 名起得和模型名一樣,只是為了教學方便,不代表生產環境必須這麼命名。
這也是為什麼問題遷移時特別隱蔽:
- 你把 endpoint 切到了 Azure;
- key 也換成 Azure 的了;
- 程式碼編譯沒問題;
- 但請求裡還在傳 OpenAI 世界裡的“模型名語義”;
- Azure 收到後找不到這個 deployment,於是直接 404。
The Fix(解決方案)
設定裡填 deployment name,不要填底層模型名
假設 Azure 門戶裡部署名叫 prod-gpt4o-chat,那你就該這樣寫:
spring:
ai:
openai:
base-url: https://my-resource.openai.azure.com/openai
api-key: ${AZURE_OPENAI_API_KEY}
chat:
options:
model: prod-gpt4o-chat
如果是 embedding,也同理。你部署名就算背後綁定的是 text-embedding-3-large,請求參數裡也該寫 deployment 名,而不是模型原名。
遷移時先核對兩張表
排查這類問題最穩的方法,不是盯著程式碼看,而是先對照:
- Azure 門戶中的 deployment 列表
- Spring 設定裡實際傳出去的 model 值
只要這兩個不一致,就不用再猜網絡、鑑權、地區或 API version 了。
團隊裡統一命名策略
如果你希望開發和運維都少踩坑,最簡單的做法是讓 deployment 名直接貼近模型名,比如:
gpt-4o
text-embedding-3-large
這樣雖然本質上仍然是 deployment name,但認知成本最低。否則一旦你起成 chat-prod-001 這類業務名,程式碼和 Azure 門戶就很容易脫節。
升級到 Spring AI 新版本時順手複查接入方式
Spring AI 官方文檔已經明確說明:從 2.0.0-M5 起,Azure OpenAI 推薦通過 OpenAI Chat 接口來訪問 Azure 部署。升級時如果你只看“接口統一”這一層,沒同步吸收“Azure 仍然認 deployment name”這個差異,就很容易在版本切換後把 404 誤判成 SDK 迴歸。
小結
- Azure OpenAI 的
model參數,本質上填的是 deployment name。 - 報
DeploymentNotFound時,先別懷疑 Spring AI,先去 Azure 門戶核對部署名。 - 從 OpenAI 遷到 Azure,最容易漏掉的不是 endpoint,而是“模型名語義變了”。
- 想減少這類坑,最好讓 deployment 名和模型名儘量保持一致。
References(參考來源)
- Azure OpenAI Chat — Spring AI 官方文檔spring-docs
- OpenAI Chat — Spring AI 官方文檔spring-docs
- How to switch between OpenAI and Azure OpenAI endpointsazure-docs
- Work with chat completions modelsazure-docs
