常见 Prompt 模式与反模式
Prompt 模式是经过实践验证的、可复用的指令结构。掌握这些模式,能让你在不同场景下快速构建高质量的 Prompt;了解反模式,则帮助你识别和规避常见错误。
常见 Prompt 模式
模式一:角色设定(Role Prompting)
通过给 AI 设定专业角色,激活特定领域的知识和思维方式。
使用场景:需要特定专业视角时,如代码审查、架构设计、安全审计。
❌ 未设定角色:
"检查这段 SQL 查询是否有问题"
✓ 设定角色后:
"你是一名 PostgreSQL DBA,有 10 年数据库性能优化经验。
请从以下角度审查这段 SQL:
1. 是否存在全表扫描(缺少索引)
2. 是否有 N+1 查询
3. 是否可以用 CTE 或子查询优化
4. 事务边界是否合理
[粘贴 SQL]"效果对比:未设定角色时 AI 只指出语法问题;设定 DBA 角色后,AI 会主动分析执行计划、建议索引策略。
模式二:思维链(Chain of Thought)
要求 AI 展示推理过程,适合复杂问题的分析和调试。
使用场景:调试复杂 Bug、架构决策、算法设计。
❌ 直接要结果:
"这个函数的时间复杂度是多少?"
✓ 思维链模式:
"分析以下函数的时间复杂度,请:
1. 先逐行说明每部分的操作次数
2. 识别嵌套循环和递归
3. 推导出最终的大 O 表示法
4. 说明最好/平均/最坏情况
function findDuplicates(arr) {
const result = [];
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (arr[i] === arr[j] && !result.includes(arr[i])) {
result.push(arr[i]);
}
}
}
return result;
}"输出效果:AI 会逐步分析,发现 result.includes 导致的额外 O(n) 操作,最终得出 O(n³) 的正确结论,并建议用 Set 优化到 O(n)。
模式三:少样本学习(Few-Shot Prompting)
通过提供 2-5 个输入输出示例,让 AI 学习特定的转换模式。
使用场景:代码风格转换、数据格式化、批量重构。
✓ Few-Shot 模式:
"按照以下示例的模式,将旧版 API 调用转换为新版:
示例 1:
旧:fetchUser(userId, callback)
新:await userService.getById(userId)
示例 2:
旧:createPost(title, content, userId, callback)
新:await postService.create({ title, content, authorId: userId })
示例 3:
旧:deleteComment(commentId, callback)
新:await commentService.delete(commentId)
现在请转换以下代码:
updateCourse(courseId, { title, description }, instructorId, callback)"AI 输出:
typescript
await courseService.update(courseId, {
title,
description,
instructorId
})模式四:分步分解(Step-by-Step Decomposition)
将复杂任务分解为有序步骤,每步明确输入输出。
使用场景:功能开发、数据处理流水线、重构计划。
✓ 分步分解:
"实现文件上传功能,请按以下步骤进行,每步完成后等待我确认再继续:
步骤 1:设计 API 接口
- 输出:POST /api/upload 的请求/响应格式(Markdown 表格)
步骤 2:实现后端接口
- 输入:步骤 1 的接口设计
- 输出:Express 路由处理函数,支持 multipart/form-data
步骤 3:添加文件验证
- 输入:步骤 2 的代码
- 输出:在原代码基础上添加类型检查(只允许图片)和大小限制(5MB)
步骤 4:实现前端上传组件
- 输入:步骤 1 的接口设计
- 输出:React 组件,含进度条和错误提示"模式五:约束规格(Constraint Specification)
明确列出所有约束,形成 AI 的"检查清单"。
使用场景:需要符合特定规范的代码生成。
✓ 约束规格模式:
"实现用户密码重置功能,约束如下:
技术约束:
- 框架:Express.js + TypeScript
- 邮件:使用已有的 emailService.send() 方法
- Token:用 crypto.randomBytes(32) 生成,有效期 1 小时
安全约束:
- Token 在数据库中存储哈希值(sha256),不存明文
- 无论邮箱是否存在,返回相同响应(防止用户枚举)
- 同一邮箱 1 小时内最多发送 3 次
代码约束:
- 所有数据库操作在 try/catch 中
- 日志记录操作(不记录 token 明文)
- 不修改 src/lib/auth/ 以外的文件"常见反模式
反模式一:指令模糊
症状:使用"更好"、"优化"、"改进"等不可量化的词语。
❌ 反模式:
"帮我让这个页面加载更快"
问题:AI 不知道当前加载时间、目标时间、可用的优化手段、哪些不能动
✓ 修正:
"当前页面首屏加载 4.2 秒(LCP),目标降至 2 秒以内。
已知瓶颈(通过 Chrome DevTools 分析):
1. 主 bundle 文件 1.8MB(未分割)
2. 首屏加载了 3 个不需要的第三方库
3. 图片未压缩(最大图片 2.4MB)
请针对这三个问题提供具体的优化方案和代码实现。"反模式二:过度约束
症状:约束之间相互矛盾,或约束过多导致无法满足。
❌ 反模式:
"实现一个函数,要求:
- 不能使用任何第三方库
- 必须兼容 IE8
- 使用 async/await
- 运行时间不超过 1ms(处理百万级数据)
- 代码不超过 10 行"
问题:async/await 不兼容 IE8;百万级数据 1ms 内完成几乎不可能;
这些约束彼此冲突
✓ 修正:
梳理约束优先级,识别硬性约束(不可违背)vs 软性约束(尽量满足),
删除互相矛盾的条件,与需求方确认真实优先级。反模式三:需求冲突
症状:在一个 Prompt 中提出逻辑上矛盾的需求。
❌ 反模式:
"实现一个缓存系统,要求:
- 数据实时更新(无延迟)
- 使用缓存减少数据库查询
- 缓存永不过期
- 数据修改后立即反映最新状态"
问题:缓存永不过期 vs 数据修改后立即更新 是矛盾的
✓ 修正:
"实现一个带失效机制的缓存系统:
- 默认缓存时间:5 分钟
- 数据修改时主动使相关缓存失效(Cache Invalidation)
- 使用 Redis,key 格式:{entity}:{id}
不需要实现实时推送,5 分钟的数据延迟可以接受。"反模式四:假设 AI 记住上下文
症状:在新的对话或长对话后期,引用早期讨论的内容而不重新提供。
❌ 反模式(新开一个对话窗口):
"继续完善之前的用户模块"
"按照我们说的规范处理错误"
"用那个数据库连接方式"
问题:新对话中 AI 没有任何之前的上下文
✓ 修正:
在每次对话开始时提供必要的背景:
"继续开发用户模块。项目使用 Express + TypeScript + Prisma。
错误处理规范:所有 async 函数使用 try/catch,
业务错误抛出 AppError(message, statusCode),
统一由 errorMiddleware 处理。
当前需要完善:用户信息更新接口(PUT /api/users/:id)"反模式五:不提供示例
症状:用文字描述期望的输出格式,而不是直接给出示例。
❌ 反模式:
"生成一份 JSON 格式的配置文件,包含数据库连接信息,
支持多环境,键名使用小写下划线,值类型包括字符串和数字"
问题:AI 可能生成多种合理但不符合你预期的结构
✓ 修正:
"生成一份多环境数据库配置文件,格式如下:
{
"development": {
"host": "localhost",
"port": 5432,
"database": "myapp_dev",
"pool_size": 5
},
"production": {
// 相同结构
}
}
为 development、production、test 三个环境生成配置,
production 的 pool_size 设为 20。"反模式速查表
| 反模式 | 症状 | 修正方法 |
|---|---|---|
| 指令模糊 | 使用不可量化的词语 | 提供具体数字、明确标准 |
| 过度约束 | 约束间相互矛盾 | 梳理优先级,删除冲突约束 |
| 需求冲突 | 逻辑上不可同时满足 | 重新分析需求,找出核心诉求 |
| 假设记忆 | 引用未提供的上下文 | 每次提供必要背景 |
| 不提示例 | 仅文字描述格式 | 用实际示例代替文字描述 |
| 任务过大 | 一次请求做太多事 | 拆分为独立的子任务 |
| 缺少约束 | 不指定技术栈/规范 | 明确所有相关约束 |
模式组合实战
在真实场景中,通常需要组合多个模式:
"你是一名资深 TypeScript 工程师(角色设定),
请审查并重构以下代码,按步骤进行(分步分解):
步骤 1:找出所有问题(列出,不修改代码)
步骤 2:修复类型安全问题(优先级最高)
步骤 3:优化性能(基于步骤 1 的分析)
步骤 4:更新测试(确保重构后测试通过)
约束(约束规格):
- 不改变函数的公共 API
- 不引入新的依赖
- 重构后必须通过现有测试
参考以下重构风格(少样本学习):
// 重构前
const x = users.filter(u => u.age > 18).map(u => u.name)
// 重构后
const adultNames = users
.filter((user): user is AdultUser => user.age > 18)
.map(user => user.name)
[粘贴待重构代码]"