第 1 课:在 VS Code 里装好 Copilot、装上 FlyPython Skill、让 Agent 取回课程
目标
本课结束时,GitHub Copilot 已在 VS Code 里跑起来,会话控件已设成适合
受监督工作的状态,FlyPython Skill 可供它使用,Agent 已把本课文件取回你
的工作目录——你没有手动下载任何东西。文件夹就位后,你运行课程的客观
检查命令,并解释「starter 失败」在测试名里的含义。本课不改任何代码。
第 1 步——在 VS Code 里把 Copilot 跑起来
安装 VS Code,按 VS Code 的提示登录 GitHub Copilot,然后
File → Open Folder 打开一个空工作目录。打开 Chat 视图,在对话
输入框里设置这些控件:
| 控件 | 选择 | 原因 |
|---|
| Session Target | Copilot | 在你本机运行的日常 Copilot harness |
| Agent | Agent | 它能读文件、跑命令 |
| Permissions | Manual permissions | 命令与工具调用都等你批准 |
如果 Agents 窗口给出 Code isolation 选项,选 Folder:New Worktree
会话固定是 Allow all,会去掉本课程依赖的批准提示。
第 2 步——(可选)预装 FlyPython Skill
这一步可选:第 3 步的开课句子会直接从 URL 读取 Skill,不装也能上课——
预装只是在之后的会话里省掉一次权限往返。
VS Code 从 .github/skills/<name>/SKILL.md 发现 Agent Skills,而且文件夹名
必须与文件里的 name 字段一致,否则 skill 不会加载。FlyPython Skill 的
名字是 flypython-challenges:
mkdir -p .github/skills/flypython-challenges
curl -s https://flypython.com/skills/flypython/SKILL.md -o .github/skills/flypython-challenges/SKILL.md
如果你的环境禁网,就用浏览器下载这个文件,存到同一路径。Skill 只是一个
文件,在每个工具里都一样:它告诉 Agent 如何为你授权、取课程文件、验证、
提交认领码。
第 3 步——让 Agent 取回本课文件(你不下载)
在工作目录里新开一个对话会话,粘贴这一句话:
Read https://flypython.com/skills/flypython/SKILL.md and start the FlyPython course hands-on-with-github-copilot.
Copilot 抓取 URL 前、每条命令运行前都会询问——读清每个请求再批准。
Agent 会给你一个授权链接和一组短码。打开链接、登录、核对码与 Agent
显示的一致后点「允许」,然后对 Agent 说「好了」。它取一次 token,把本课
文件写到 courses/hands-on-with-github-copilot/。
前提:这些课程需要一个能执行命令并且能联网的编码 Agent。
只能聊天的网页 AI 做不了。
为什么有这一课
AI 写的 Python 大多是同一种死法:演示输入能跑,真实输入一到,脚本
在第 3 行崩掉——或者更糟,悄悄算出一个错的数。修复不从更好的
提示词开始,而从把「坏了」变成一条任何人都能跑、且得到相同答案的
命令开始。在 Manual permissions 下,Copilot 只在你读过这条命令之后
才运行它。
热身(2 分钟)
在编辑器里打开 starter/report_tool.py,从头读到尾。它看起来很
合理:带 docstring 的函数、类型标注、CLI。这正是 AI 生成代码的
样子——表面干净、行为缺失。现在打开 TASK.md,放在手边。
本课内容
本课文件现在已经位于 courses/hands-on-with-github-copilot/——你这边
没有发生任何下载。让 Agent 先只读不动手:
“读 COURSE.md——它是本文件夹的教学契约。再读 TASK.md 和
starter/report_tool.py。不要改任何文件。告诉我测试期望哪些行为、
starter 缺了哪些。”
它请求运行学员命令时批准——整个课程你只需要这一条检查命令:
python verify.py
你会看到 starter 复现五类真实世界故障,外加两个端到端后果——共七个
具名失败测试——并与测试名一一对应:
| 失败的测试 | 真实含义 |
|---|
test_load_json_records_returns_list_of_dicts | 工具只处理 CSV;API 场景直接崩 |
test_unsupported_suffix_raises_value_error | 一个 .xlsx 上传变成莫名其妙的崩溃,而不是清楚的拒绝 |
test_invalid_records_are_isolated_with_reasons | 一个空单元格中止整个运行——没有部分报告,没有原因 |
test_group_totals_are_rounded_to_two_decimals | 0.1 + 0.2 在报告里打印成 0.30000000000000004 |
test_write_report_creates_missing_parent_directories | 工具无法写进新建的输出目录 |
test_run_scenario_writes_report_file、test_main_prints_summary_and_returns_zero | 上述问题的端到端后果 |
想看缺失行为对应的失败测试名,维护者命令会打印它们:
python verify.py starter --expect-failure
(参考答案 solution/ 是给维护者证明目标可达用的。你不需要运行
它,它也从来不是完成标准——你的实现(starter/)才是。)
练习
挑一个你最有代入感的场景皮肤(excel-report、data-monitor 或
api-tool),打开它的数据文件,找出会被拒绝的行。先不看运行
结果,写下每个坏行会触发哪个测试,再对照上面的表自查——并让
Agent 确认,而不是让它修。
检查点
在课程文件夹里运行 python verify.py。不看材料能回答下面三个
问题即算通过:
- 哪五个行为把 starter 和 solution 区分开?其中哪两个失败测试是它们的端到端后果?
python verify.py 为什么故意以非零退出——它在报告什么状态?
为什么这是成功条件而不是报错?
- 你在练习里找到的那一行会让 starter 崩溃、被隔离,还是悄悄
通过?
能回答之后,用 python verify.py --attest l01 认领本检查点。
预期证据
默认命令的完整输出记录,加你的三个答案。保留好——第 4 课还会
用到。