微软生成式 AI 入门课第 3 课的负责任 AI:不是口号,是可执行动作

2026-08-18

翻 generative-ai-for-beginners 的时候,第 3 课 03-using-generative-ai-responsibly/README.md 是最容易被跳过的一章——整章没有一个代码块,没有 python/ 子目录,没有作业脚本,通篇是概念和图。看完你大概率记住了「要负责任」,然后翻页去看第 4 课的提示工程。

但如果你带着一个具体问题回来看这一章,它就不一样了。这个问题是:这一章说的每一条缓解动作,在这个仓库里到底落在哪个文件的哪一行? 我把整个仓库按这条线索翻了一遍,结论是:缓解层里有三层能找到确切的代码落点,一层在仓库里只有文字描述,还有一层要翻到第 14 课才见着影子。下面按这条线走一遍。

先看这一章自己说了什么

第 3 课把风险分成三类,都有小标题:Hallucinations、Harmful Content、Lack of Fairness。这三个词是原文标题,不是我的归纳。Harmful Content 那一节还给了一份定义清单,包括自伤或伤害特定群体的指导、仇恨或贬损内容、协助策划攻击与暴力行为、如何获取非法内容或实施违法行为的指导、露骨性内容。

然后是缓解。这里有一处值得先记下来:README 在 “How to Use Generative AI Responsibly” 开头写的是 let's look at 4 steps we can take to build our AI solutions responsibly,但它下面实际只有三个小节标题——Measure Potential Harms、Mitigate Potential Harms、Operate a Responsible Generative AI solution。而在 Mitigate Potential Harms 一节里,正文写的是 We can look at this in 4 different layers,紧接着的 bullet 列表却有五条:Model、Safety System、Metaprompt、User Experience、Evaluate model。

正文的数字和实际条目对不上,两处都是白纸黑字。我不去替作者解释是排版遗留还是有意为之,只是提醒你:读这一章时按标题和 bullet 数,别按正文里那个数字数。 落到实际工作上,你要挨个落地的是那五条,不是四条。

Model 层:落在 .env.copy 的两个变量上

第一层写的是「为对的场景选对的模型」。这句话在仓库里的落点非常具体,就是根目录的 .env.copy。这个文件是配置模板,00-course-setup/03-providers.md 让你把它复制一份成 .env 再填。

值得注意的是里面有两个不同的模型变量:AZURE_OPENAI_DEPLOYMENTAZURE_INFERENCE_CHAT_MODEL.env.copyAZURE_OPENAI_DEPLOYMENT 下面直接写了一句注释,说 gpt-5-mini 是 reasoning 模型,不支持 temperature/top_p,用 max_output_tokens 而不是 max_tokens;要试 temperature,就用下面那个 Llama 模型的变量。

第 6 课 06-text-generation-apps/README.md 把这层讲得更明确:当前 Microsoft Foundry 上未废弃的模型是 reasoning 模型(GPT-5 家族、o 系列),不支持 temperaturetop_p,也不支持 max_tokens;文档写明如果你把 temperature 传给 gpt-5-mini,会收到「参数不支持」的报错。所以「选模型」这个动作在代码层面的后果不只是换个名字——你的采样参数写法会跟着变。这也是为什么模板里要单开一个 AZURE_INFERENCE_CHAT_MODEL:温度那个例子得指到一个还支持采样控制的模型上。

顺带说一句这一层最容易踩的坑。仓库里有一批 githubmodels- 前缀的示例,这个前缀现在名不副实了:00-course-setup/02-setup-local.md00-course-setup/03-providers.md00-course-setup/README.md.env.copy 以及 06-text-generation-apps/python/githubmodels-app.py 的注释都写明,GitHub Models 已于 2026 年 7 月底退役,直接替代者是 Microsoft Foundry Models。所以第三条路线现在应当理解为 Microsoft Foundry Models(原 GitHub Models 路线),实际要配的是 AZURE_INFERENCE_ENDPOINTAZURE_INFERENCE_CREDENTIAL,不是 GITHUB_TOKEN。这个时间点出自仓库文档,今天已经过去了。

配置文件的准备,00-course-setup/03-providers.md 给的原文命令是 cp .env.copy .env。Windows 下 PowerShell 里 cpCopy-Item 的别名可以直接用,cmd 下要写成 copy .env.copy .env——这一句是通用做法,不是仓库官方内容。

Metaprompt 层:落在第 9 课的 disallow_list

第 3 课说 metaprompt 是「用系统输入定义模型的边界」。这句话的代码落点在 09-building-image-applications/README.md 的 “Setting boundaries with metaprompts” 一节,里面给的写法是把一段约束文本拼在用户 prompt 前面:

disallow_list = "swords, violence, blood, gore, nudity, sexual content, adult content, adult themes, adult language"

meta_prompt = f"""You are an assistant designer that creates images for children.

The image needs to be safe for work and appropriate for children.
The image needs to be in color, in landscape orientation, and in a 16:9 aspect ratio.

Do not consider any input that is not safe for work or appropriate for children, including:
{disallow_list}
"""

prompt = f"{meta_prompt}\nCreate an image of a bunny on a horse, holding a lollipop"

disallow_list 里的那串词是仓库里的示例值,不是什么标准清单,你自己的场景要自己定。这一节末尾仓库文档自述了一句:把它和 Microsoft Foundry 内置的内容过滤组合起来做纵深防御。也就是说,metaprompt 这一层在文档里被明确定位成「不单独成立」的一层。

同一层的另一种写法在 docs/SECURITY_GUIDELINES.md 的 Prompt Injection Prevention 一节,那里给的是结构化 messages:把约束放进 role: system 的那条消息,把 sanitize_prompt_input 清洗过的用户输入放进 role: user,而不是拼成一个大字符串。同一节还把「直接把 input() 结果插进 f-string」这种写法标成了 DANGEROUS,并给了一个越权 prompt 作为例子。

第 6 课的 06-text-generation-apps/python/githubmodels-app.py 用的正是这种结构,client.complete(...)messages 里是 role: systemrole: user 两条。这里有个读代码才看得见的细节:这个文件顶部从 azure.ai.inference.models 导入了 SystemMessageUserMessage,但下面调用时传的是普通 dict,这两个导入的符号在文件里没有再出现过。你照抄这个文件时会连那行 import 一起抄走,知道它当前没被用到,改写起来心里有数。

User Experience 层:落在 shared/python/input_validation.py

第 3 课把「限制用户能发什么」放在 User Experience 层。仓库里这层有专门的共享模块:shared/python/input_validation.py,里面定义了 validate_number_inputvalidate_text_inputsanitize_prompt_inputvalidate_emailvalidate_url

这里先记一个容易踩空的地方:包入口 shared/python/__init__.py__all__ 只把前三个再导出去,validate_emailvalidate_url 不在里面。想用后两个,得直接从 shared.python.input_validation 这个模块导,别指望从包名一层拿到。

其中 sanitize_prompt_input 是直接冲着提示注入去的。它的做法是先剥掉空字节和控制字符,再对一组模式做 re.sub 剔除:\{\{.*?\}\}(模板注入)、\$\{.*?\}(变量替换)、<script.*?>.*?</script>javascript:。另外它有个 strict 参数,默认是 False(这是仓库当前代码里的默认值,随版本可能变动),打开后会再做一次白名单过滤,只留下有限的字符集。这些函数在 tests/test_input_validation.py 里有对应的测试类,想确认某个分支的行为,直接看那里的断言比看文档快。

这里有一处值得你自己去核的差异。 第 6 课的 06-text-generation-apps/python/aoai-app-recipe.py 做了输入校验,但它没有 import 上面这个共享模块,而是在文件顶部自己又写了一份 get_required_envvalidate_number_inputvalidate_text_input,函数名一样,行为不一样。

本地这份 validate_text_input 先用 re.sub(r'[<>{}[\]|\\`]', '', value) 删掉一批字符,再用 ^[\w\s,.\'-]+$ 对整体做一次匹配,匹配不上就抛 Input contains invalid characters。按这个正则的写法,问号、冒号、括号都不在允许集合里。

而共享模块里同名的 validate_text_input 根本不看字符内容:它的参数是 max_lengthmin_lengthallow_emptyfield_name,做的事情是 strip 之后判空、判长度上下限,然后原样返回。字符级的清洗在共享模块里是另一个函数 sanitize_prompt_input 的活。也就是说,同一个函数名在两处的语义完全不同——一处是「字符集不合规就拒绝」,另一处是「只管长度,字符一概不问」。你要是先读了共享模块、以为 validate_text_input 会替你挡注入,那就是记错了地方。

更值得注意的是同一课的另一条路线:06-text-generation-apps/python/oai-app-recipe.py(OpenAI 路线)里没有任何校验,三个 input() 的结果直接插进 f-string 拼成 prompt。两个文件放在同一个目录下,文件名只差一个前缀。

我不去猜为什么只有 Azure 那份做了加固。但对你有直接影响的结论是:别默认这个课程仓里同名的示例安全等级一致。 你照着哪个文件抄,就得看清那个文件里有没有这一层。

Safety System 层:仓库里只有文字

第三层 Safety System,第 3 课的描述是「模型服务平台侧的一组工具与配置」,举的例子是 Azure OpenAI 服务的内容过滤系统,并说这类系统还应当能识别越狱攻击和机器人请求。这一层在仓库里我没有找到可运行的代码示例——Tools 一节给的是 Azure AI Content Safety 的文档链接,说它能通过 API 请求检测有害内容与图片;13-securing-ai-applications/README.md 里也只有一句「确保你的 AI 基础设施支持内容过滤」这样的要求。

照实说:这一层写的是平台侧的能力,而仓库里我们没有找到与之对应的可运行示例。你要落地它,得去看服务侧自己的文档。

Evaluate model 层与最后那一步

第五条 bullet 是 Evaluate model。14-the-generative-ai-application-lifecycle/README.md 把评估摆到了生命周期里,并写明 LLM 的生命周期不同于常规 MLOps,评估指标是新的一组:Quality、Harm、Honesty、Cost and Latency——注意 Harm 是被当成一类指标列出来的,跟质量并列。

至于第 3 课的最后一节 Operate a Responsible Generative AI solution,它讲的是上线前要和法务、安全一起把合规过一遍,并准备好交付、事故处理和回滚的方案。这一节没有代码落点,但它是唯一一条明确要求你在发版流程里留位置的。

最后补一个跨全仓的细节:这套课程的 Python 示例调用 Responses API 时普遍带着 store=False 这个参数,06-text-generation-apps/python/ 下的几个脚本都是这么写的。这算是数据边界在代码里的一个可见落点,你自己动手改示例时别顺手把它删了。

如果你只想记一件事:第 3 课的价值不在它讲了什么,而在于它给了你一张核对表——拿着 Model、Safety System、Metaprompt、User Experience、Evaluate model 这五个词回去翻自己的项目,每一层问一句「我的代码里这层在哪个文件」。这个仓库自己有一层是空的,你的项目大概率也有。


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

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

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