七种高级技法只有一种落进 aoai-solution.py:微软生成式 AI 入门课第 5 课

2026-08-18

第 5 课 05-advanced-prompts/README.md 一口气列了七种技法:zero-shot、few-shot、chain-of-thought、generated knowledge、least-to-most、self-refine、maieutic prompting。读完之后大部分人的第一个问题是同一个:这些东西写进代码里长什么样?

这一课的答案比你想的窄得多。整课只有一个 Solution 链接,指向 05-advanced-prompts/python/aoai-solution.py,而 python/ 目录下总共就两个文件——aoai-assignment.pyaoai-solution.py。也就是说,七种技法里真正有代码落点的只有 self-refine 那一条。下面就顺着这个文件走一遍,看看每一处改动分别对应哪句话。

先说清楚这个文件不是什么

打开 aoai-solution.py,第一件让人意外的事是:**它里面没有任何模型调用。**没有 OpenAI 客户端,没有 load_dotenv(),没有 client.responses.create(...)

对比一下第 6 课的 06-text-generation-apps/python/aoai-app.py,那才是典型的 aoai- 文件形态——顶上 from openai import OpenAI,然后用 os.environ['AZURE_OPENAI_API_KEY']os.environ['AZURE_OPENAI_ENDPOINT'] 拼出 base_url,再走 client.responses.create(model=deployment, input=prompt, store=False)

00-course-setup/03-providers.md 里写明,文件名里的这几个 tag 是凭据标记:aoai 表示需要 Azure OpenAI 的 endpoint 与 key,oai 表示需要 OpenAI 的,hf 表示需要 Hugging Face token,githubmodels 表示需要 Microsoft Foundry Models 的 endpoint 与 key。按这个约定,第 5 课的两个文件带 aoai- 前缀却不需要任何凭据。把这两处放在一起就能看出来:这一课的 solution 是提示的产物,不是发提示的脚本——它是你拿 GitHub Copilot 或 ChatGPT 对着 assignment 做完 self-refine 之后,代码应该变成的样子。知道这一点,你就不会白配一遍 .env 了。

三条建议,三处落点

aoai-solution.py 的开头是一段注释,原样保留了 AI 给出的三条改进建议:输入校验、用环境变量存敏感信息、加错误处理。这正是 README 里 self-refine 四步的第三、四步——你批评它的答案,它带着批评重答一遍。妙的地方在于,这个文件把「批评」和「重答」都留在了同一个文件里,所以每条建议都能在下面的代码里找到对应位置。

**第一条:输入校验。**建议里点名了 flask-wtf,代码里就落成了一个表单类:

class HelloForm(FlaskForm):
    name = StringField('Name', validators=[DataRequired(), Length(min=3)])
    email = StringField('Email', validators=[DataRequired(), Email()])
    submit = SubmitField('Submit')

校验规则挂在 validators 里,触发点在路由里的 form.validate_on_submit()。注意 Length(min=3) 这个 3 只是仓库示例里的取值,不是什么推荐阈值。

**第二条:环境变量。**落点只有一行:

app.config['SECRET_KEY'] = os.environ.get('FLASK_SECRET_KEY', os.urandom(32))

这里有个值得停一下的错位:注释里的建议说的是「数据库凭据、API key 之类的机密」,而代码实际动的是 Flask 的 SECRET_KEY——因为改完之后要用 FlaskForm,而 FlaskForm 需要 SECRET_KEY。建议文本和落点并不是一一对应的。这恰恰是 self-refine 用起来最需要留神的地方:模型给的建议是通用条目,落到你这份代码上会变形,得你自己对一遍。

**第三条:错误处理。**建议里点名了 @app.errorhandler() 装饰器,代码结尾就是:

@app.errorhandler(400)
def bad_request(error):
    return 'Bad request', 400

三条之外还多出来的东西

如果 solution 只做了上面三处,那它就是三条建议的直译。但它没有。代码里还有几处带 # SECURITY: 注释的改动,在开头那三条建议里根本没提:

  • markupsafe 引入 escape(),返回前把 form.name.dataform.email.data 包一层,注释写明是防 XSS
  • render_template_string(FORM_TEMPLATE, form=form) 渲染,而不是手工拼 HTML
  • 模板里的 {{ form.hidden_tag() }},也就是 CSRF 那个隐藏字段

再对照 aoai-assignment.py 就更明显了。原始版本只有一个路由,从查询串里取名字:name = request.args.get('name', 'World'),然后 return f'Hello, {name}!'。到了 solution,路由签名变成 @app.route('/', methods=['GET', 'POST']),GET 参数被换成了 POST 表单。接口形态被改掉了——这已经超出「改进三处」的范围。

所以这个 solution 更像是多轮 self-refine 叠加之后的结果,而不是一轮的产物。README 的 Solution 一节给了一句提示:让它改进时最好限定改几条,也可以限定往哪个方向改,比如架构、性能、安全。文件里这几处安全相关的加法,方向感和那句提示是对得上的。

JS 那一份把「多轮」写在了明面上

同一课还有 05-advanced-prompts/javascript/solution.js,README 里没有链接它,但它其实更完整地展示了 self-refine 的循环结构:starter code 在最上面,接着一段注释写明提示是「找出三处改进并应用」,AI 的三条回答原样贴着,然后是改好的一版;再往下又是一轮,提示换成「让代码更安全」,又是三条回答,又是改好的一版。两轮之间代码是接力关系。想看 self-refine 迭代痕迹的,读这一份比读 Python 那份直观。

顺带提一句这个文件里的一处现状:文件末尾附了一条生成自签名证书的 openssl 命令,而它是连同 markdown 代码围栏一起原样写在 .js 文件里的。看到别觉得是自己下载错了。

剩下六种技法在这一课有没有代码

照实说:没有。05-advanced-prompts/ 下只有 README.mdimages/javascript/python/ 四项,python/javascript/ 里各只有 assignment 与 solution。

README 正文里唯一还带「可复制素材」性质的是 generated knowledge 那一节——它给了一个用 {{variable}} 占位的模板,以及一次优化前后的对比:优化前直接列产品和预算,模型多推荐了一份人寿险;优化后给每行加上 type:cost: 字段名,并在预算那行加上 restrict choice to types 这样的措辞。这两版 prompt 文本是能直接抄走改的,但它们不是文件,是 README 里的两个代码块。chain-of-thought、least-to-most、maieutic 这三节则只有对话片段,这一课里没有对应的可运行文件。

temperature 那一节,现在要配着第 6 课读

第 5 课「Vary your output」一节写着:temperature 取值在 0 到 1 之间,0 最确定、1 最发散,默认值 0.7;文档接着分别以 0.1 和 0.9 各给了两次输出做对照。这句默认值是仓库当前文档里写的,随版本可能变动。

但第 6 课 06-text-generation-apps/README.md 里有一段说明,方向和上面这节是有张力的:它写明当前 Microsoft Foundry 上未废弃的模型是 reasoning 模型(GPT-5 家族、o 系列),不支持 temperaturetop_p,也不支持 max_tokens(要改用 max_output_tokens;把 temperature 发给 gpt-5-mini 会拿到参数不支持的报错。它给的替代路径是:想试 temperature 就指向仍支持采样控制的模型,文档里举的例子是 Microsoft Foundry 模型目录里的 Llama-3.3-70B-Instruct,走 Foundry Models / Azure AI Inference endpoint 调用——也就是 githubmodels-* 样例的那条路。同一段还写明 temperature/top_p 在 Llama、Mistral、Phi 以及 GPT-4.x 家族上仍然有效,但 GPT-4.x 正在废弃中。

这两处我只把它们并排放在这里,不替作者解释。实用结论只有一条:读第 5 课这一节时,别把 temperature 当成对所有模型都通用的旋钮。

顺便把 provider 那条路也说准:githubmodels- 这个前缀现在名不副实。00-course-setup/03-providers.md 写明 GitHub Models 已在 2026 年 7 月底退役,替代者是 Microsoft Foundry Models;.env.copy 里对应的变量已经是 AZURE_INFERENCE_ENDPOINTAZURE_INFERENCE_CREDENTIAL。所以今天要走第三条路线,配的是 Microsoft Foundry Models 的 endpoint 与 key,而不是 GITHUB_TOKEN。这个日期出自仓库文档。

想在本地执行 solution,先看这两处

第 5 课这两个文件不需要模型凭据,但它们需要依赖,而这里有个坑:aoai-solution.py 里 import 了 flask_wtfwtformsmarkupsafe,仓库根目录的 requirements.txt 里我们没有找到这几项,05-advanced-prompts/ 目录下也没有单独的 requirements.txt。也就是说按 00-course-setup/02-setup-local.md 的常规流程装完,这份 solution 的依赖仍然是缺的,得自己补。

环境本身按那篇文档走,Windows 和 Unix 的激活命令不一样,文档里两条都写了:

python -m venv .venv          # make one
source .venv/bin/activate     # macOS / Linux
.\.venv\Scripts\activate      # Windows PowerShell

以上为仓库文档中原样给出的命令。同一篇文档的排障表里还列了一条 Windows 专属的:pip 在 Windows 上构建 wheel 失败时,先 pip install --upgrade pip setuptools wheel 再重试。

最后一句提醒:这一课的价值不在那七个技法名词——那些名词到处都能查到——而在于 aoai-solution.py 把「AI 给的建议」和「建议落到了哪一行」摆在了同一个文件里。你要是想给自己的项目建一套 self-refine 的工作方式,照着这个文件的形态留痕就够了:批评写在注释里,改动写在代码里,两者对得上号,对不上号的那几处(比如上面 SECRET_KEY 那一处)就是你需要人工判断的地方。该课程持续更新,以上文件路径、依赖与代码内容以仓库最新内容为准。


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

安全与合规相关做法请结合自身环境评估,本文不构成安全方案建议。

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