微软生成式 AI 入门课的 githubmodels-app.py 连的是 Foundry Models
打开 generative-ai-for-beginners 的 06-text-generation-apps/python/ 目录,你会看到同一个示例有三套文件:oai-app.py、aoai-app.py、githubmodels-app.py。文件名前缀就是 provider 路线的标记,00-course-setup/03-providers.md 里专门列了这套约定:oai 需要 OpenAI 的 endpoint 和 key,aoai 需要 Azure OpenAI 的,hf 需要 Hugging Face token,githubmodels 这一条——按该文件的原话——需要的是 Microsoft Foundry Models 的 endpoint 与 key,并在括号里注明 GitHub Models 将于 2026 年 7 月底退役。
这就是第一个容易踩空的地方:前缀还叫 githubmodels-,但它已经不再对应 GitHub Models 的凭据了。仓库根目录的 AGENTS.md 在「General Conventions」一节里自述了这件事,写明 githubmodels- 前缀是 GitHub Models 时代保留下来的历史命名。所以如果你照着老教程去找 GITHUB_TOKEN,会在 .env.copy 里一无所获。
前置条件:先确认三件事
Python 版本。 00-course-setup/02-setup-local.md 的 Prerequisites 表格写的是 Python 3.10 及以上,Git 用最新版,VS Code 与 Docker Desktop 都标为可选(Docker 只在走 Dev Container 那条路时才需要)。
虚拟环境。 同一份文档的 Option A 给了原样的命令,两个平台分开写:
python -m venv .venv # make one
source .venv/bin/activate # macOS / Linux
.\.venv\Scripts\activate # Windows PowerShell
Windows 侧就是最后那一行,PowerShell 里执行。文档接着提示,激活成功后命令行提示符前面会带上 (.venv)。
依赖装哪一份 requirements。 这里有个值得注意的细节:06-text-generation-apps/python/requirements.txt 里只有 openai 与 python-dotenv 两项,并没有 azure-ai-inference;而 githubmodels-app.py 第一行 import 的恰恰是 from azure.ai.inference import ChatCompletionsClient。这个包出现在仓库根目录的 requirements.txt 里。两处放在一起看,结论很直接:只装课程目录下那份 requirements,githubmodels-app.py 的 import 就会缺件。02-setup-local.md 的 Option A 第三步给的也正是根目录那条:
pip install -r requirements.txt
步骤:两个环境变量,一个 client
03-providers.md 的「Create .env file」一节说得很清楚,先从模板复制:
cp .env.copy .env
文档同时注明 .env 已被 gitignore,所以密钥不会被提交上去。Windows 侧仓库没有给出对应的复制命令,02-setup-local.md 里只给了一条新建空文件的写法,并明确标注为 Windows:
echo . > .env
至于在 Windows 上如何复制 .env.copy,仓库里没有找到相关说明,你可以直接手工复制这个文件。
打开 .env 之后,这条路线只需要填两个值。.env.copy 里对应的两行原样是这样的(右侧是占位说明,不是真值):
AZURE_INFERENCE_ENDPOINT='<add your Microsoft Foundry project endpoint here, e.g. https://<resource-name>.services.ai.azure.com/models>'
AZURE_INFERENCE_CREDENTIAL='<add your Microsoft Foundry Models API key here>'
这两个值从哪来?03-providers.md 的「Configure Microsoft Foundry Models: From Portal」给了四步:进 Microsoft Foundry 创建或打开一个 Foundry 项目、在模型目录里部署一个模型、在项目的 Overview 页面复制 endpoint 与 API key、把它们分别填进上面两个变量。githubmodels-app.py 的代码注释也重复了同一句出处提示——去 Foundry 项目的 Overview 页面拿。
接下来是 client 初始化。githubmodels-app.py 里这段是原样的:
import os
from azure.ai.inference import ChatCompletionsClient
from azure.ai.inference.models import SystemMessage, UserMessage
from azure.core.credentials import AzureKeyCredential
token = os.environ["AZURE_INFERENCE_CREDENTIAL"]
endpoint = os.environ["AZURE_INFERENCE_ENDPOINT"]
model_name = "gpt-5-mini"
client = ChatCompletionsClient(
endpoint=endpoint,
credential=AzureKeyCredential(token),
)
三个点要说明。第一,key 不是直接塞进构造函数的,而是包一层 AzureKeyCredential(token) 再作为 credential 传入。第二,model_name 在这个 .py 文件里是硬编码的字符串 "gpt-5-mini"——这只是仓库里的示例值,你部署的模型叫什么就填什么。第三,取环境变量用的是 os.environ["..."] 的下标写法,变量不存在时直接抛 KeyError,而不是返回 None。
发起请求与取结果:
response = client.complete(
messages=[...],
model=model_name,
# Note: gpt-5 reasoning models don't accept temperature/top_p; leave them at their defaults.
)
if response.choices and response.choices[0].message is not None:
print(response.choices[0].message.content)
messages 是 role / content 组成的字典列表,model 在调用时再传一次。注释那一行是文件里原样带着的,别忽略它——下一节会讲到它牵出的坑。
运行方式在 AGENTS.md 的「Running Python Examples」里,先切到课程目录再执行脚本文件(示例中给的是 python aoai-app.py,换成本文这条路线的文件名即可)。
和 OpenAI 路线差在哪
把 oai-app.py 放在旁边对照,差别不止是变量名。
SDK 不是同一个。 OpenAI 路线 import 的是 from openai import OpenAI,GitHub Models 这条走的是 azure.ai.inference。前者的 client 构造在 oai-app.py 里干脆是空参的 OpenAI(),构造函数里一个凭据都没传——该文件开头调了 load_dotenv(),而 03-providers.md 写明 OpenAI 的 key 要填进 .env 的 OPENAI_API_KEY;后者必须显式把 endpoint 与 credential 都传进去。
调用的 API 面不同。 oai-app.py 调的是 Responses API:client.responses.create(model=deployment, input=prompt, store=False),取结果用 response.output_text 一行拿到。githubmodels-app.py 调的是 client.complete(...),取结果要走 response.choices[0].message.content,而且原代码在取之前先判了 response.choices 非空、message 不为 None。同样一次文本生成,两边的返回结构不一样,照抄另一条路线的取值写法必然报错。
.env 的加载时机不同。 这点最隐蔽:oai-app.py 和 aoai-app.py 都 import 了 dotenv 并在开头调用 load_dotenv(),而 githubmodels-app.py 没有 这两行。也就是说,把值写进 .env 之后直接执行这个脚本,环境变量并不会被自动读进来,os.environ["AZURE_INFERENCE_CREDENTIAL"] 会抛 KeyError。仓库里两个文件白纸黑字就是这么写的,我们只指出这个差异,不替作者解释原因。要么在自己的 shell 里先导出这两个变量,要么按 02-setup-local.md 第 6 步的写法自己补上 load_dotenv()。
顺带说一句 Azure OpenAI 那条:aoai-app.py 用的仍是 openai 包,只是把 base_url 拼成了 f"{os.environ['AZURE_OPENAI_ENDPOINT'].rstrip('/')}/openai/v1/"。所以三条路线里,真正换了 SDK 的只有 githubmodels- 这一条。
边界:这些地方仓库明说了不行
temperature 和 top_p 传不得。 06-text-generation-apps/README.md 与 AGENTS.md 都写明,当前课程默认的 gpt-5-mini 属于 reasoning 模型,不支持 temperature / top_p,也不用 max_tokens(Responses API 用 max_output_tokens,chat completions 用 max_completion_tokens);README 里直接写了,给 gpt-5-mini 发 temperature 会得到 parameter not supported 的报错。
要演示 temperature,得换模型。 同一目录下的 githubmodels-assignment.ipynb 走的是另一套取值:model_name = os.environ.get("AZURE_INFERENCE_CHAT_MODEL", "Llama-3.3-70B-Instruct")。注意它用的是 os.environ.get 带默认值,和 .py 文件里的硬编码不一样;那个默认值是仓库当前代码里的写法,随版本可能变动。.env.copy 里也确实为此多留了一个 AZURE_INFERENCE_CHAT_MODEL 变量,注释写明要填一个支持采样控制的非 reasoning 模型部署名。
示例输出别当预期结果。 notebook 里贴的那大段菜谱输出是仓库写好的示例,文件里紧跟着一句提示,说明 LLM 是非确定性的。我们没有运行过这些代码,也不对返回内容做任何承诺。
凭据与费用。 03-providers.md 明确写了这些练习要用你自己的账号,作业是可选的;缺凭据时相关作业会直接报错退出。这条路线的每次调用都会把 prompt 发到云端服务,请自行评估密钥保管与数据边界。安全与合规相关做法请结合自身环境评估,本文不构成安全方案建议。
.env 不是唯一出路,但替代方案有条件。 03-providers.md 的第 4 点提到,如果你用 GitHub Codespaces,可以把这些值存成与仓库关联的 Codespaces secrets,从而不必建本地 .env;但它同时用加粗强调了限制条件——这个办法只在 Codespaces 下成立,改用 Docker Desktop 的话仍然要老老实实配 .env 文件。
实在不想连云端的话
如果两个 AZURE_INFERENCE_* 变量你一个都拿不到,03-providers.md 末尾还有一节「Offline / Local Providers」,列了两条本地路线:Foundry Local 与 Ollama。关于前者,该文件写明它会自动选择执行 provider(NPU、GPU 或 CPU),并暴露一个 OpenAI 兼容的 endpoint,因此课程里大部分示例代码只需少量改动就能复用;安装命令两个平台都给了,Windows 侧是 winget install Microsoft.FoundryLocal,macOS 侧是 brew install microsoft/foundrylocal/foundrylocal。文档把动手示例指向了 19-slm/README.md 那一课。
需要留意的是,本文这条路线的代码用的是 azure.ai.inference,而「OpenAI 兼容 endpoint」这个说法对应的是 openai 包那一侧的写法。仓库里没有找到把 ChatCompletionsClient 直接指向 Foundry Local 的示例,别默认能照搬。
怎么确认配对了
最省事的验证不是直接执行完整示例,而是先只读变量。00-course-setup/02-setup-local.md 第 6 步给了原样的片段:
from dotenv import load_dotenv
import os
# Load environment variables from .env file
load_dotenv()
# Access the Microsoft Foundry Models variables
endpoint = os.getenv("AZURE_INFERENCE_ENDPOINT")
token = os.getenv("AZURE_INFERENCE_CREDENTIAL")
print(endpoint)
打印出 endpoint 说明 .env 的路径与变量名都对了。如果你想让缺变量时的报错更明确,仓库自带 shared/python/env_utils.py,里面有 get_required_env(var_name, description=None)、validate_env_vars(*var_names) 和 get_env_with_default(var_name, default) 三个函数——前两个在变量缺失或为空时抛 ValueError,消息里会带上变量名并提示去 .env 里设置,比一个光秃秃的 KeyError 好读。比如:
from shared.python.env_utils import validate_env_vars
env = validate_env_vars("AZURE_INFERENCE_ENDPOINT", "AZURE_INFERENCE_CREDENTIAL")
print(env["AZURE_INFERENCE_ENDPOINT"])
以上为按仓库代码中的接口语义组合的示例,未经实测,以仓库最新代码为准。
如果卡在 ModuleNotFoundError: dotenv,02-setup-local.md 的 Troubleshooting 表格给的处置是执行根目录的 pip install -r requirements.txt——通常意味着虚拟环境里依赖没装上。这张表还列了 Windows 上 pip 无法 build wheels 的情况,给的处置是先 pip install --upgrade pip setuptools wheel 再重试。
最后提醒一句:这条路线的命名与凭据来源在仓库里正处于迁移状态,文件前缀、环境变量、推荐模型都可能继续调整。动手前先看一眼 03-providers.md 和 .env.copy 的当前内容,以仓库最新内容为准。
本文依据 github.com/microsoft/generative-ai-for-beginners 仓库于 2026-08-18 的公开内容整理,
事实来自仓库内的课程正文与代码示例。我们没有跑过文中涉及的代码,
因此不涉及运行结果、耗时与生成质量的任何描述。
该课程持续更新,文中涉及的文件路径、依赖与接口写法随版本变动,请以仓库最新内容为准。
文中涉及的云端服务调用会产生费用并可能上传数据,请自行评估密钥与数据边界。