跳转至

第 2 讲:提示词工程基础

上课时间:2026 年 10 月 20 日(第 6 周,周二 19:20–20:55)
所属板块:基础方法

这一讲讲两件事:怎么把需求说清楚,怎么把背景材料给对。课上分三部分:提示技术、面向代码任务的提示技巧、上下文工程。

上讲回顾与检查点 1 反馈

25 位同学全部完成了检查点 1,有几个问题比较集中:

  1. 选题写得太简略,或者直接拿以前的科研项目、旧作品当选题,没有说明这门课准备做什么;
  2. 关键概念和功能边界不清楚,读者判断不了实际目标;
  3. 直接粘贴 AI 生成的内容,缺少自己的判断和整理;
  4. 和 AI 的交互只有一两次,过程记录不够;
  5. 环境配置、Git 启动这些基础信息没有交代。

一、提示工程在做什么

提示是人机协同的接口。同一个模型、同一个任务,提示不同,结果可能差很多。可以把 AI 当成新同事:任务说清楚,它才做得好。

LLM 会先把提示切成词元(token),再根据这些词元续写。提示里的每个词都会影响输出,包括看起来无关的内容。

Token 是模型处理文本的最小单位。英文单词大约 1 个词元,中文一个汉字平均约 1.2 个词元,具体会有出入。Token 数量影响 API 成本和响应速度,所以上下文不是越多越好。

文本 约合词元
Hello World! 约 3 个
你好世界 约 4 个
function add(a, b) 约 7 个

二、好提示的四要素

要素 要写清的内容
意图 要做什么、给谁用、解决什么问题
约束 语言、框架、版本、代码风格、禁止事项
格式 输出成函数、类还是脚本,带不带测试和注释
上下文 相关代码、接口、报错信息

三、五种提示技术

Zero-shot:直接描述任务

不给示例,直接说任务、输入输出和要求。适合常见、标准的任务。

用 Python 实现一个二分查找函数:
- 输入:已排序的整数列表 nums、目标值 target
- 输出:目标元素下标;不存在时返回 -1
- 要求:仅用标准库,带类型注解与 docstring

Few-shot:给几个示例

先给 2–5 个“输入 → 输出”示例,再给新输入。适合格式转换、风格统一和项目里的私有约定。示例质量比数量重要。

把错误码统一成项目风格(K=2):
输入:参数缺失 → 输出:E1001 参数缺失:{name}
输入:权限不足 → 输出:E1002 权限不足:{role}
新输入:文件不存在 → 按同样风格输出错误码

Chain-of-Thought:先推理再作答

要求模型先给出推理步骤,再给结论。复杂逻辑任务的正确率会明显提升,简单任务收益有限。

先分析这段代码的问题,再修复,最后给 diff:
1. 逐条列出问题,说明触发条件与影响
2. 说明修复思路,为什么这样改
3. 只输出修改处的 diff,不重写整个文件

Self-consistency:多生成几次再比较

同一个问题多次采样,或者换一种措辞重问,比较答案是否一致。也可以让 AI 给出多个实现方案,交叉比较后择优。

任务:统计日志中每种 ERROR 的出现次数
要求:给出 3 种实现——字典计数 / Counter / pandas
每种说明:性能、可读性、额外依赖
最后:推荐一种,并说明理由

多次结果一致,通常更可信;分歧的地方正好是需要人工检查的地方。

Reflexion:生成后自评再改

流程是生成、自评、修正、再生成。适合代码审查和迭代改进。

第 1 轮:实现 parse_config(path),解析 ini 并返回 dict
第 2 轮:审查你刚生成的代码,指出 3 个潜在问题
第 3 轮:按自评逐条改进,重新输出完整代码

任务越复杂、越不标准,越需要详细的提示技术。

四、代码任务的提示习惯

先写清需求和接口

需求至少包括输入、输出、边界条件和异常处理。可以先把函数签名和数据结构定下来,确认后再实现。

“优化一下”“好看一点”这类说法,AI 只能猜。平时可以积累一些专业词汇,比如 UI/UX、接口、验收、架构,表达越具体,AI 猜的空间越小。

用结构化提示

课上用了医院排队预测的例子。原来的提示是一段混在一起的话:

在医院排队做 CT,估计要等数小时。想做个 HTML 小程序:输入我的号码和当前叫号,
每听到一个号点一下按钮,估算还要等多久。

问题在于信息混杂、边界模糊、没有技术约束。改成结构化的写法后,可用度会明显提高:

# 角色
你是一位资深的前端开发工程师,擅长开发移动端友好的单页应用。

# 背景
我正在医院排队等待检查,需要一个工具来根据当前的叫号速度,预估我还需要等待多久。
这个工具将在手机浏览器上运行。

# 目标
请编写一个单文件的 HTML 小程序(包含 CSS/JS),用于追踪排队进度并预测时间。

# 功能需求
1. 初始化设置:允许用户输入「我的号码」和「当前叫号」
2. 核心交互:提供一个显眼的「过号」按钮,每点击一次,「当前叫号」加 1,并记录当前时间戳
3. 预测逻辑:
   - 采用移动平均法:优先计算最近 10 次叫号的平均时间间隔
   - 预测「剩余等待时间」= (我的号码 - 当前叫号) * 移动平均时间
   - 至少有 3 次点击数据后,才开始显示预测结果
4. 状态显示:实时显示当前叫号、我的号码、预计还需要等待的时长(分钟)、预计叫号时间点

# 技术要求
- 单文件 HTML(内嵌 CSS 和 JS)
- 移动端友好,按钮要大
- 使用 localStorage 保存数据,刷新页面不丢失

# 约束
- 代码简洁,易于理解
- 添加必要的注释

结构化的作用是先把事情想清楚,也让 AI 少猜。常见的分节是角色、背景、目标、功能需求、技术要求、约束。

约束、分步和迭代

写约束时,把语言和版本、命名和注释要求、类型注解、禁止事项都写上。例如“Python 3.12,仅标准库”“不要引入新依赖”“不要修改公共接口”。

先让 AI 讲方案,认可后再写;先搭骨架,再逐个实现。这样错误暴露得早,过程也可控。

结果不符合预期时,具体指出哪里不对。还可以让 AI 用自己的话复述需求,或者让它反过来追问你还没想清楚的地方。需求阶段用后者往往很有效。

五、上下文工程

上下文窗口是模型一次能“看见”的内容上限。项目里的私有约定、接口和错误现场,不会自动出现在它眼前。给的材料质量差,生成结果也不会好。

长会话还会带来几个问题:模型处理更多上下文,响应变慢;需要综合考虑更多上下文,生成质量下降;成本也会增加。

该给什么

  • 相关的源码和接口定义,而不是整个仓库;
  • 项目约定,比如目录结构、命名规范、技术栈版本;
  • 错误现场,包括报错信息和日志;
  • 已经试过的方法,避免 AI 重复推荐无效方案。
类型 示例
需求描述 “做一个待办事项应用”
领域知识 “餐厅点餐系统”
技术约束 “Python 3.12 + Flask”
代码上下文 “auth.py 已有认证模块”
业务规则 “VIP 用户享 8 折”
数据约束 “用户年龄必须大于 18”

报错和日志

报错栈一般包含错误类型、消息、位置(文件:行号)和调用链。把完整报错栈和相关代码一起交给 AI,让它解释原因。

日志先做剪裁,按时间窗或 ERROR 级别提取关键片段,不要整屏粘贴。

以下是报错与相关代码,请解释原因并给出修复建议。

给多给少的平衡

上下文太多,关键信息会被稀释,成本上升,注意力也会分散;上下文太少,AI 只能猜接口和约定,容易产生幻觉。

实际做法是按相关性筛选,用 @文件 或索引引用代替全文粘贴。

六、提示模板

常用的提示可以整理成模板,结构是任务、约束、上下文、输出格式、验收标准。

〔任务〕给 students.csv 每行计算平均分并写回
〔约束〕Python 3.12,仅标准库;不修改已有列
〔上下文〕数据格式见样例;复用现有 load_csv()
〔输出格式〕单个函数,带 docstring 与类型注解
〔验收标准〕空数据不报错;平均分保留 1 位小数

把常用的提示存下来,时间长了就是自己的提示库。团队或项目层面可以用 AGENTS.md 这类行为文件,第 5 讲会详细讲。

七、课堂演示:三连对比

任务:给学生成绩表写一个统计脚本。

轮次 提示 结果
第一遍 “帮我写个统计成绩的脚本” 字段、规则、格式全凭 AI 猜
第二遍 明确列、规则与输出格式 结构可用,细节还要来回改
第三遍 精确提示加上下文,贴数据样例和现有函数 接近直接可用,修改轮次最少

观察的是输出可用度和修改轮次。

八、课堂实操

下载第 2 讲课堂实操 handout(zip,约 114 KB)。压缩包里有两份练习材料,互不依赖。

练习 内容 入口
练习一:提示策略对比 用至少两种提示策略实现一个不依赖标准库 JSON 模块的 JSON parser,再用 JSONTestSuite 评测 part1-json-parser/
练习二:构造提问上下文 让 AI 回答 billing 代码库的 4 个问题,比较三种上下文构造方式 part2-context/

练习一

每种提示策略至少运行 3 次,每次生成一个 json_parser.py。提示词保存到 strategy1/、strategy2/ 目录,用 evaluate.py 做正确性评测,最后填两种策略的对比表。

每次尝试用独立的空目录和新会话,不要让后一次看到前一次的结果。如果发现 agent 读到了上一次的产物,清空目录重跑。

练习二

三组做法:

  1. A 组:在仓库里放开 read / glob,让 agent 自己找;
  2. B 组:禁用工具,由你挑选相关代码放进提示词;
  3. C 组:禁用工具,把全部代码放进提示词。

问题在 part2-context/questions.md,答案分别保存为 answer-a.json、answer-b.json、answer-c.json,用 grade_answers.py 按 ground_truth.json 自动批改。

对比正确性、幻觉、提示词规模、工具调用次数和耗时。

A/B/C 三组各用新会话。A 组在 repo/ 里运行,B/C 组在禁工具的 run-tools-off/ 里运行。A 组依赖 repo/.opencode/opencode.json 限制读取范围,不要删除。

需要交的记录

  • 两种提示策略的提示词、至少 3 个 json_parser.py,以及 evaluate.py 的评测输出;
  • 两种策略的过程和结果对比表;
  • 练习二的三组实际使用的提示词、答案 JSON 和对比表;
  • 全程的提示词与输出记录。

九、检查点 2

截止 10 月 27 日(周二)23:59。需要提交含 Git 版本历史的代码仓库、用本讲技巧生成的骨架代码,以及提示词和上下文实践记录。

另外,按检查点 2:初始进展的要求,用会话 fork 完成至少一组不同提示词或不同上下文的对比,保留两组完整记录。

相关材料