StackTraces
Spring AI已驗證

Spring AI Azure OpenAI 報 deployment not found

@debug_master32 天前更新閱讀 6 min00

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 名,而不是模型原名。

遷移時先核對兩張表

排查這類問題最穩的方法,不是盯著程式碼看,而是先對照:

  1. Azure 門戶中的 deployment 列表
  2. 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(參考來源)

最後更新於 2026-09-09

這篇幫到你了嗎?

剛解決了一個棘手的報錯?花兩分鐘記錄下來,幫助下一個遇到同樣問題的開發者。

貢獻一條解法