不想装环境:用 Codespaces 跑微软生成式 AI 入门课的完整步骤

2026-08-18

一、先说这条路解决的是什么麻烦

在 Windows 上开一门 Python 课,最容易卡住的从来不是课程内容,而是环境。generative-ai-for-beginners 自己的本地安装页 00-course-setup/02-setup-local.md 末尾那张排查表,把常见的几种翻车写得很直白:python not found 要你把 Python 加进 PATH 或重开终端;pip 在 Windows 上编译 wheel 失败,要你先 pip install --upgrade pip setuptools wheel 再重试;ModuleNotFoundError: dotenv 说明虚拟环境根本没装上;Docker 构建报磁盘不足要去 Docker Desktop 的资源设置里加盘。

这些坑和「生成式 AI」没有半点关系,但足以把人劝退在第一课之前。所以仓库单独给了一页云端启动路径 00-course-setup/01-setup-cloud.md,开头一句话就是它的定位:如果你不想在本地装任何东西,就用这一页。走这条路,你的浏览器就是 IDE,依赖装在别人的机器上。

下面这套步骤全部依据仓库 00-course-setup/ 下的 README.md01-setup-cloud.md03-providers.md 以及 .devcontainer/ 里的配置文件。课程持续更新,涉及路径、依赖与变量名的地方请以仓库最新内容为准。

二、前置条件(这一段别跳)

第一,你得先 fork。 00-course-setup/README.md 的第 1 步就是把整个仓库 fork 到自己的 GitHub 账号下,理由是你要改代码、做作业。第 2 步创建 codespace 时,两处文档都写明是在你的 fork 里操作:Code -> Codespaces -> New on main01-setup-cloud.md 里的措辞是 Code ▸ Codespaces ▸ Create codespace on main。直接在原仓库上开 codespace 不是文档给的路径。

第二,机器规格是写死在配置里的。 .devcontainer/devcontainer.json 里有一项 hostRequirements,下面挂着 cpus 并给了一个具体取值。仓库本身没有解释这一项,它的语义以 dev container 规范和 GitHub 的官方文档为准;对你的实际影响是,创建 codespace 时那个机器类型下拉框不是随便选的,配置里已经对宿主提了要求。这个取值随仓库版本可能变动,用之前自己打开文件看一眼。同一个文件里 image 指向 mcr.microsoft.com/devcontainers/universal 这个通用镜像并钉了具体 tag,01-setup-cloud.md 把它描述为预置了 Python 3、Node.js、.NET、Java 的开发容器。

第三,模型 provider 的账号要自己准备。 00-course-setup/03-providers.md 写得很清楚:这些练习要用你自己的账号;作业是可选的,你可以配置一个、全部或者一个都不配。文件里同时给出了作业文件名上的标签约定——oai 需要 OpenAI 的 endpoint 与 key,aoai 需要 Azure OpenAI 的 endpoint 与 key,hf 需要 Hugging Face token,githubmodels 需要 Microsoft Foundry Models 的 endpoint 与 key(该文件同时注明 GitHub Models 即将退役、由 Microsoft Foundry Models 接替)。缺凭据会怎样,原文一句话交代了:相关作业会直接报错退出。

这条约定的实际意义是:Codespaces 只解决依赖,不解决凭据。 容器起来了不等于代码能跑通。

三、容器起来的时候,到底在跑什么

.devcontainer/devcontainer.json 里有三个字段决定了这台云端机器的初始化顺序,值得单独看一眼:

字段
waitForonCreateCommand
updateContentCommandpython3 -m pip install -r requirements.txt
postCreateCommandbash .devcontainer/post-create.sh

也就是说,根目录的 requirements.txt 是主依赖清单,随后再执行 .devcontainer/post-create.sh。这个脚本里装的是这些:

pip install python-dotenv
pip install openai

pip install ruff black mypy pytest

有意思的是脚本里自带一条注释:# TODO: Check why this can't be done in requirements.txt。而根目录的 requirements.txt 里确实已经列了 python-dotenvopenai。两处放在一起看,这是同一批包被装了两遍,仓库自己也留了 TODO 标记这件事没理清——我们只指出这个事实,不替作者解释原因。脚本后半段那几个是开发工具,注释写明它们对应 .github/workflows/code-quality.yml 里跑的检查,方便贡献者在本地复现。

devcontainer.jsoncustomizations.vscode.extensions 里还预装了 Python、Pylance、Jupyter、black、ruff 等扩展;同一个文件的 settings 段把 editor.formatOnSave 设成了 true,并在 [python] 下把 editor.defaultFormatter 指向 ms-python.black-formatter。这两条配置放在一起,含义是保存时交给 black 格式化——所以如果你发现自己写的缩进、引号风格在保存后变了样,先回头看这两项配置,而不是怀疑自己的编辑器坏了。配置的含义以仓库当前的 devcontainer.json 为准。

四、密钥在云端怎么配:两个选项,选一个

01-setup-cloud.md 给了两条路。

选项 A:Codespaces secrets(文档标为推荐)。 操作路径原文写的是齿轮图标 → Command Palette → Codespaces : Manage user secret → 新建一条 secret,名字用 OPENAI_API_KEY,值粘贴你的 key。原文对结果的描述是:代码会自动取到它。

为什么能自动取到?看代码就明白。06-text-generation-apps/python/oai-app.py 里构造客户端的那一行是:

client = OpenAI()

没有传任何 key 参数——它依赖进程环境里已经有 OPENAI_API_KEY。而 Codespaces secret 正是以环境变量形式出现在容器里的,所以这条链路不需要任何本地文件。公共工具 shared/python/env_utils.py 也是同一套取值方式,get_required_env 内部就是 os.getenv(var_name),取不到时抛 ValueError,错误信息是「Missing required environment variable: …,请在你的 .env 文件或环境中设置」。

选项 B:.env 文件。 01-setup-cloud.md 给的两行是:

cp .env.copy .env
code .env         # fill in OPENAI_API_KEY=your_key_here

根目录的 .env.copy 是模板,里面按 provider 分了几段:OpenAI 段只有 OPENAI_API_KEY;Azure OpenAI 段有 AZURE_OPENAI_API_VERSIONAZURE_OPENAI_API_KEYAZURE_OPENAI_ENDPOINTAZURE_OPENAI_DEPLOYMENTAZURE_OPENAI_EMBEDDINGS_DEPLOYMENT;Microsoft Foundry Models 段有 AZURE_INFERENCE_ENDPOINTAZURE_INFERENCE_CREDENTIALAZURE_INFERENCE_CHAT_MODEL;最后是 HUGGING_FACE_API_KEY.env 本身在 .gitignore 里,02-setup-local.md 也强调了别提交它。

这里有一处值得留意的偏差:03-providers.md 正文中贴出的 .env.copy 内容,与根目录 .env.copy 实际文件并不完全一致——实际文件里多出了 AZURE_INFERENCE_CHAT_MODEL,注释说明它用于需要 temperature / top_p 的示例。以哪个为准?以你 fork 下来的那个实际文件为准。

五、云端和本地,差的是哪一行代码

很多人以为 Codespaces 和本地只是「机器不同」,其实取值链路也不同,而且差异就落在一行 load_dotenv() 上。

06-text-generation-apps/python/oai-app.pyaoai-app.py 的开头都有:

from dotenv import load_dotenv

# load environment variables from .env file
load_dotenv()

但同目录下的 githubmodels-app.py 没有这一行,它直接写 os.environ["AZURE_INFERENCE_CREDENTIAL"]os.environ["AZURE_INFERENCE_ENDPOINT"]。把这两处放在一起,结论就很明确:secret 这条路对两类文件都成立(因为变量本来就在进程环境里),而 .env 这条路只对显式调用了 load_dotenv() 的文件成立。你在本地照着 .env 配好却在某个示例上报 KeyError 时,先去看那个文件的开头有没有这一行。

另外 03-providers.md 第 4 条明确划了 secrets 的边界:这个选项只在你使用 GitHub Codespaces 时有效;如果你改用 Docker Desktop,仍然需要配置 .env 文件。

至于本地(Windows)那条路,02-setup-local.md 里的写法是分开给的,创建 .env 的命令 Unix 侧是 touch .env,Windows 侧是 echo . > .env;虚拟环境激活 macOS / Linux 是 source .venv/bin/activate,Windows PowerShell 是 .\.venv\Scripts\activate。走 Codespaces 的话这一段你都用不到——容器是 Linux,你的操作系统只负责开浏览器。

六、边界:哪些事仓库里没写

  • secret 的授权范围没有展开。 01-setup-cloud.md 走的是 Command Palette 里的「Manage user secret」(用户级),而 03-providers.md 的措辞是「与该仓库关联的 Codespaces secrets」。两处措辞不一致,仓库里没有进一步说明用户级 secret 如何对 fork 生效,只在 00-course-setup/README.md 里给了 GitHub 官方 Codespaces secrets 管理文档的链接。以那份官方文档为准。
  • Python 版本在仓库内部不统一。 根目录 .python-version.devcontainer/environment.yml(conda 那条可选路径)钉的版本并不一致,02-setup-local.md 的前置条件表里则写的是「Python 3.10 +」。走 Codespaces 时以镜像与 .python-version 为准,但这三处的差异确实存在。
  • 额度与计费不在本文范围。 01-setup-cloud.md 提到了免费额度并给了一条提示:闲置的 codespace 要停掉或删掉(View ▸ Command Palette ▸ Codespaces: Stop Codespace)。具体额度数字会变,请以 GitHub 官方说明为准。调用云端模型 API 同样会产生费用。
  • 没有 experimental 标记。 这条路径在文档里没有标注为实验特性;00-course-setup/README.md 中间夹了一段本应属于本地 .env 配置的编号步骤,编排上略显混乱,但内容与 02-setup-local.md 的第 3 节一致。

七、怎么验证配对了

容器起来之后,按这个顺序确认,能把问题定位到具体一层:

  1. 终端是否可用。00-course-setup/README.md 的排查表里有一条 python: command not found,给的处置是终端没挂上,点 + 新开一个 bash。
  2. 容器构建长时间卡住(这是那张表的头一条),处置是 Codespaces ➜ “Rebuild Container”;页面提示 “Dev container mounting…” 时刷新浏览器标签页即可,文档说明 Codespaces 有时会掉连接。
  3. notebook 找不到 kernel,走 Notebook 菜单 ➜ Kernel ▸ Select Kernel ▸ Python 3
  4. 变量到底有没有进来。02-setup-local.md 第 3 节给了最小验证代码,Codespaces 里同样适用:
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)

如果你走的是 secret 这条路且只配了 OPENAI_API_KEY,把变量名换成你实际配的那个再看。想要缺失时直接抛异常而不是打印 None,可以用公共工具里的写法,shared/python/env_utils.py 的 docstring 里给的示例是:

api_key = get_required_env("OPENAI_API_KEY", "OpenAI API authentication")

同一个文件里还有 validate_env_vars,可以一次校验多个变量并把缺的那几个一起报出来,适合 Azure OpenAI 这种需要 endpoint、key、deployment 三件套的路线。以上为按仓库代码中的接口语义组合的示例,未经实测,以仓库最新代码为准。

  1. 最后一层是凭据本身。排查表里 401 Unauthorized 对应的处置是 key 错了或过期;02-setup-local.md 的表里把 401 与 429 放在一起,提示检查 key 的值与请求速率限制。到这一层就不是环境问题了。

安全与合规相关做法请结合自身环境评估,本文不构成安全方案建议。密钥请只写在 secret 或 .env 里,别写进代码,也别提交到公开仓库。


本文依据 github.com/microsoft/generative-ai-for-beginners 仓库于 2026-08-18 的公开内容整理, 事实来自仓库内的课程正文与代码示例。我们没有跑过文中涉及的代码, 因此不涉及运行结果、耗时与生成质量的任何描述。 该课程持续更新,文中涉及的文件路径、依赖与接口写法随版本变动,请以仓库最新内容为准。 文中涉及的云端服务调用会产生费用并可能上传数据,请自行评估密钥与数据边界。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。