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
