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

这篇帮到你了吗?

刚解决了一个棘手的报错?花两分钟记录下来,帮助下一个遇到同样问题的开发者。

贡献一条解法