跑微软生成式 AI 入门课报模型不存在:多半是 provider 选串了
跑 generative-ai-for-beginners 的第六课时,有一类卡点特别常见:环境装好了、.env 也填了,一运行却告诉你模型 / 部署找不到。多数时候不是账号问题,而是你手里那个 .py 文件和你填进 .env 的那组变量,压根不属于同一条 provider 路线。
先说清楚边界:这类报错的原文与错误码,我们在仓库里没有找到收录。仓库有两张排障表(00-course-setup/README.md 和 00-course-setup/02-setup-local.md 各一张),列的是 401 / 429、ModuleNotFoundError: dotenv、Windows 下 pip 构不出 wheel、Docker 空间不足、Conda 报错这些条目,没有一条是模型或部署找不到。所以下面不会给你「报错长什么样」,只按仓库代码写明的语义,倒推它可能来自哪一层。
一、三套文件的命名规律,仓库自己写明了
AGENTS.md 的命名约定一节里逐字写着:aoai- 前缀对应 Azure OpenAI,oai- 对应 OpenAI API,githubmodels- 对应 Microsoft Foundry Models——并且括号里注明这个前缀是「GitHub Models 时代保留下来的历史命名」。同一份文件在「新增代码示例」的流程里把规则写成 {provider}-{example-name}.{py|ts|js}。
00-course-setup/03-providers.md 从作业侧又说了一遍:作业文件名里会带 aoai、oai、hf、githubmodels 这几个标签之一,分别要求 Azure OpenAI 的 endpoint 与 key、OpenAI 的 endpoint 与 key、Hugging Face token、Microsoft Foundry Models 的 endpoint 与 key。同一节还写明:你可以只配其中一条、全配、或者一条都不配,缺凭据的作业会直接报错。
也就是说,前缀不是给人看着好分类的,它是「这份文件要读哪几个环境变量」的声明。
二、怎么确认是路线串了:三个可执行的判定动作
动作 1:打开你正在跑的那个文件,只看 import 和客户端构造这两处
以 06-text-generation-apps/python/ 下的三套为例,差异全在开头几行:
| 前缀 | 客户端 | 凭据来源 | model 值从哪来 | 发请求的方法 |
|---|---|---|---|---|
oai- | OpenAI()(无参构造) | 隐式读 OPENAI_API_KEY | 文件里硬编码的模型名 | client.responses.create |
aoai- | OpenAI(api_key=..., base_url=...) | AZURE_OPENAI_API_KEY + AZURE_OPENAI_ENDPOINT | AZURE_OPENAI_DEPLOYMENT,是部署名 | client.responses.create |
githubmodels- | ChatCompletionsClient | AZURE_INFERENCE_CREDENTIAL + AZURE_INFERENCE_ENDPOINT | 文件里硬编码的 model_name | client.complete |
第三行和前两行连 SDK 都不是同一个:githubmodels-app.py 里 import 的是 azure.ai.inference 的 ChatCompletionsClient,凭据用 azure.core.credentials 的 AzureKeyCredential 包一层,方法名叫 complete,不是 responses.create。所以只要看到文件顶上写着 from azure.ai.inference import ChatCompletionsClient,就别再去 .env 里找 AZURE_OPENAI_* 那几行了,它不读那些。
aoai- 那条线的 base_url 是拼出来的,这是最容易被抄漏的一处:
client = OpenAI(
api_key=os.environ['AZURE_OPENAI_API_KEY'],
base_url=f"{os.environ['AZURE_OPENAI_ENDPOINT'].rstrip('/')}/openai/v1/",
)
06-text-generation-apps/README.md 在「Setup configuration Azure」一节解释了这个写法:base_url 是 Foundry 资源的 endpoint 再接 /openai/v1/,走这个稳定的 v1 端点就不用再管 api_version。如果你把 endpoint 直接原样丢进去、少了尾巴那一段,路由到的就不是同一个地方。
动作 2:别信注释,信代码
这一条是真会咬人的。oai-study-buddy.py 和 oai-app-recipe.py 这两个文件里,客户端上方的注释写的是 # configure Azure OpenAI service client,但下一行是 client = OpenAI(),无参构造——它走的是 OpenAI 路线,不是 Azure。同目录的 oai-app.py 和 oai-history-bot.py 注释才是 # configure OpenAI service client。按注释来分类,你会在 .env 里填错一整组变量。
动作 3:确认 model 传出去的到底是模型名还是部署名
oai- 和 githubmodels- 两条线传的是模型名,仓库示例里写的是 gpt-5-mini(这是仓库当前示例里的值,随课程更新可能变动)。aoai- 传的是 AZURE_OPENAI_DEPLOYMENT,也就是你自己在 Foundry 门户里给这次部署起的名字。03-providers.md 对这一点的说法是:部署名通常和模型名相同,除非你显式改过。
「通常相同」这四个字就是坑的来源——一旦你部署时改过名字,或者把 Azure 的部署名抄进了 OpenAI 路线的文件,model 这个字段的值就落在了一个对面不认识的命名空间里。判定办法很直接:在调用之前先把实际要发出去的 model 和 base_url 打印一遍,看它是不是你以为的那个(这是通用的调试做法,不是课程内容)。
三、处置:按你手上的文件对齐变量
- 用
oai-*:.env里填OPENAI_API_KEY。注意这条线是OpenAI()无参构造,key 是靠load_dotenv()把.env灌进环境变量之后被隐式读走的,.env没加载成功就等同于没填。 - 用
aoai-*:填AZURE_OPENAI_API_KEY、AZURE_OPENAI_ENDPOINT、AZURE_OPENAI_DEPLOYMENT(以及需要向量检索时的AZURE_OPENAI_EMBEDDINGS_DEPLOYMENT)。model位置必须是部署名。 - 用
githubmodels-*:这个前缀今天已经名不副实了。 仓库在00-course-setup/03-providers.md、.env.copy以及06-text-generation-apps/python/githubmodels-app.py的注释里反复写明:GitHub Models 将于 2026 年 7 月底退役,直接替代者是 Microsoft Foundry Models;00-course-setup/02-setup-local.md与00-course-setup/README.md里的那两处说得更明确,退役的是「GitHub Models 连同它的GITHUB_TOKEN变量」,AGENTS.md的环境变量一节也把AZURE_INFERENCE_CREDENTIAL标成「replaces the retiringGITHUB_TOKEN」。今天已经过了这个时间点。所以这条线实际要配的是AZURE_INFERENCE_ENDPOINT和AZURE_INFERENCE_CREDENTIAL,值取自 Foundry 项目 Overview 页的 endpoint 与 API key,不要再去找GITHUB_TOKEN。
.env.copy 里还多出一个 AZURE_INFERENCE_CHAT_MODEL,注释说明它是专门给 temperature 示例用的、支持采样参数的非 reasoning 模型部署名。这条和「模型不存在」无关,但下一节会用到。
四、验证:用最短的那个文件单点验证
三条线各自都有一个「只发一次请求、只打印一行」的最小文件,先跑它,不要拿带 input() 交互和多轮拼接的 recipe 版本去验证配置:
- OpenAI 路线:
06-text-generation-apps/python/oai-app.py - Azure OpenAI 路线:
06-text-generation-apps/python/aoai-app.py - Foundry Models 路线(原 GitHub Models 路线):
06-text-generation-apps/python/githubmodels-app.py
前两个的判定信号是 print(response.output_text) 出了内容,第三个是 response.choices[0].message.content 出了内容——注意这两条取结果的路径本身就不一样,前者是 Responses API,后者是 chat completions 形态。
Windows 侧还有两处仓库明确分开写了的差异。一是虚拟环境激活,06-text-generation-apps/README.md 的练习步骤给的是 source venv/bin/activate,紧跟一条注记:Windows 下改用 venv\Scripts\activate。二是建 .env,00-course-setup/02-setup-local.md 给的是 Unix 用 touch .env、Windows 用 echo . > .env;而 03-providers.md 里从模板拷贝的写法是 cp .env.copy .env。另外 02-setup-local.md 的排障表里单列了一条 Windows 专属项:pip 构不出 wheel 时先 pip install --upgrade pip setuptools wheel 再重试。
五、什么情况说明不是这个原因
最后这一段比前面都重要,省了就会有人把好好的配置改坏。
报的是 401 或 429。 这是凭据或限流,两张排障表都逐字列了:00-course-setup/README.md 写 401 Unauthorized 对应 key 错了或过期,02-setup-local.md 写 OpenAI 的 401 / 429 去查 OPENAI_API_KEY 的值和请求速率。此时 model 传得对不对还轮不到讨论。
报的是 ModuleNotFoundError。 这是依赖没装齐,不是模型问题。这里有一处值得单独指出来的不一致:06-text-generation-apps/python/requirements.txt 里只有 openai 和 python-dotenv 两项,不包含 azure-ai-inference;而仓库根目录的 requirements.txt 里是有 azure-ai-inference 的。而 githubmodels-app.py 的第一屏就写着 from azure.ai.inference import ChatCompletionsClient——这个 import 所需要的包,不在同目录那份依赖清单里。这两处摆在一起看就够了,我们不替作者解释为什么这样分,也不替你预判解释器会怎么报。
报的是参数不被支持。 06-text-generation-apps/README.md 明确写了:当前 Foundry 上未废弃的模型是 reasoning 模型(GPT-5 家族、o 系列),它们不支持 temperature 和 top_p,也不用 max_tokens(Responses API 用 max_output_tokens);文档原话是,给 gpt-5-mini 传 temperature 会拿到「parameter not supported」这类报错。AGENTS.md 的模型约定一节说得更死:不要给调用 gpt-5-mini 的示例加 temperature / top_p / max_tokens;要演示 temperature,改用 Foundry 目录里支持采样控制的模型,也就是 AZURE_INFERENCE_CHAT_MODEL 那个变量的用途。同一节还提到第 18 课微调仍保留 gpt-4.1-mini(因为 GPT-5 那边只支持强化微调,不是那一课演示的监督微调),第 20、21 课因为面向 Mistral / Llama 模型所以保留 temperature 与 max_tokens。这些都是模型能力差异,不是路线串了。
你要找的文件根本不存在。 三套示例并不是每课都齐。按仓库当前的文件分布:第 8、9、11 课只有 oai- / aoai- 两套,第 18 课的 python/openai/ 下只有 oai- 一套,这四课都没有 githubmodels- 版本;第 20、21 课反过来,只有 githubmodels- 版本;第 5 课只有 aoai- 版本。三套齐全的是第 4、6、7 课。另外 03-providers.md 在标签清单里列了 hf,但我们在仓库的示例目录里没有找到以 hf 为前缀的代码文件——这一点只作陈述,不做推测。
还有一类纯粹是文件名。 第 6、7 课里有几个 notebook 的名字少了一个字母,是 oai-assigment.ipynb 而不是 -assignment,第 7 课还有 aoai-assigment-simple.ipynb 和 oai-assigment-simple.ipynb。照着 README 里的名字去敲路径会找不到文件,那跟 provider 配置没有半点关系。
判断顺序建议就按这个来:先看报错属不属于上面五类,都不属于,再回到第二节的三个判定动作去对齐路线。
以上代码片段与文件路径均按仓库代码中的接口语义引用与组合,未经实测,以仓库最新代码为准。
本文依据 github.com/microsoft/generative-ai-for-beginners 仓库于 2026-08-18 的公开内容整理,
事实来自仓库内的课程正文与代码示例。我们没有跑过文中涉及的代码,
因此不涉及运行结果、耗时与生成质量的任何描述。
该课程持续更新,文中涉及的文件路径、依赖与接口写法随版本变动,请以仓库最新内容为准。
文中涉及的云端服务调用会产生费用并可能上传数据,请自行评估密钥与数据边界。
安全与合规相关做法请结合自身环境评估,本文不构成安全方案建议。