Skip to content

Prompt 编写原则

别问 AI "怎么写",要说 "想要什么 + 上下文"。
给上下文:项目结构、约束、风格、已有代码 — 上下文是 prompt 的一半。
AI 出错先复盘 prompt,再调 AI。错的多半是你说得不清,不是它不行。

良好的 Prompt 是 AI 辅助开发的基石。无论使用 Claude Code、Cursor 还是 GitHub Copilot,清晰、结构化的指令都能显著提升代码质量与开发效率。

核心原则

1. 清晰优于简洁

AI 模型不会"猜测你的意图"。每一个模糊词语都可能导致截然不同的输出。

模糊表达清晰表达
"写一个排序函数""用 TypeScript 写一个稳定排序函数,接受泛型数组和比较函数,返回新数组(不修改原数组)"
"优化这段代码""优化这段代码的时间复杂度,目标从 O(n²) 降至 O(n log n),保持函数签名不变"
"加个错误处理""为所有 async 函数添加 try/catch,网络错误抛出 NetworkError,业务错误抛出 AppError"

2. 分步骤描述复杂任务

当任务涉及多个步骤时,逐步拆解比一次性描述效果更好。

❌ 不推荐:
"帮我做一个用户认证系统"

✓ 推荐:
"我需要构建用户认证系统,请按以下顺序进行:
1. 先设计数据库 schema(users 表,含 id/email/password_hash/created_at)
2. 实现注册接口(POST /api/auth/register),包含邮箱格式校验和密码强度检查
3. 实现登录接口(POST /api/auth/login),使用 JWT 返回 token
4. 实现中间件验证 token
请先从第 1 步开始,完成后告诉我再继续。"

3. 提供示例(Example-Driven Prompting)

示例是最高效的约束方式,比文字描述更精准。

❌ 不推荐:
"写一个函数把驼峰命名转成下划线命名"

✓ 推荐:
"写一个函数把驼峰命名转成下划线命名:
输入: 'getUserName'  → 输出: 'get_user_name'
输入: 'HTTPSRequest' → 输出: 'https_request'
输入: 'getHTTPCode'  → 输出: 'get_http_code'
用 TypeScript 实现,并包含这三个测试用例。"

4. 明确约束条件

约束不是限制,而是帮助 AI 输出符合项目要求的代码。

常见约束维度:

技术栈:使用 React 18 + TypeScript 5,不使用 class 组件
性能:组件需要支持虚拟化,数据量可达 10万条
兼容性:需要支持 IE11(避免使用 ES2020+ 语法)
规范:遵循项目 ESLint 配置,函数命名用动词开头
测试:用 Vitest 写单元测试,覆盖边界情况

5. 指定输出格式

明确告知期望的返回格式,避免冗长解释和不必要的代码。

"只返回函数本体,不需要解释,不需要 import 语句,不需要示例调用"
"以 Markdown 表格形式列出所有 API 端点"
"只列出需要修改的代码行,标注行号"

5W Prompt 框架

系统化思考 Prompt 的结构化框架:

What(做什么):  明确任务目标和交付物
Why(为什么):   提供背景,帮助 AI 理解意图
Where(在哪):   指定文件、模块、代码位置
When(何时):    触发条件或使用场景
Which(哪些约束):技术选型、规范、限制

5W 框架实战示例

场景:为电商系统添加商品搜索功能

What:  实现商品全文搜索 API,支持关键词搜索、分类过滤、价格区间筛选
Why:   当前只能精确匹配商品名,用户搜索体验差,需要支持模糊搜索
Where: 修改 src/api/products.ts 中的 searchProducts 函数
When:  用户在搜索框输入并点击搜索时触发,支持防抖(300ms)
Which: 使用 PostgreSQL full-text search,不引入 Elasticsearch;
        返回结果按相关性排序;分页,每页最多 20 条;
        TypeScript 严格模式,所有参数类型需显式声明

好坏 Prompt 对比

案例一:代码重构

❌ 坏 Prompt:
"重构这段代码让它更好"

✓ 好 Prompt:
"重构以下函数,目标:
1. 消除重复逻辑(DRY 原则)
2. 将嵌套超过 3 层的条件提取为独立函数
3. 添加 JSDoc 注释(参数、返回值、异常)
保持函数签名和行为不变,附上重构前后的对比说明"

案例二:调试问题

❌ 坏 Prompt:
"为什么我的代码不工作?"

✓ 好 Prompt:
"以下代码在用户快速点击按钮时会触发多次 API 调用(竞态条件):
[粘贴代码]

错误现象:连续点击 3 次,发起了 3 次请求,最后一次的旧响应覆盖了正确结果
期望行为:只响应最后一次点击的请求,取消前面的请求
请使用 AbortController 修复,不改变函数签名"

案例三:生成测试

❌ 坏 Prompt:
"给这个函数写测试"

✓ 好 Prompt:
"为 calculateDiscount(price: number, coupon: Coupon) 函数写 Vitest 测试:
需要覆盖:
- 正常折扣(10% off)
- 固定金额减免(满100减20)
- 过期优惠券(应抛出 CouponExpiredError)
- 价格为 0 或负数(应抛出 InvalidPriceError)
- coupon 为 null 时返回原价
测试文件命名:calculateDiscount.test.ts,使用 describe/it 组织"

迭代优化策略

Prompt 工程是迭代过程。当结果不理想时:

  1. 追加约束"重新生成,这次不要使用 any 类型"
  2. 提供反例"不要生成类似 [具体示例] 这样的代码"
  3. 缩小范围"只处理 handleSubmit 这一个函数"
  4. 换角色视角"以高级前端工程师的视角,审查并改进这段代码"
  5. 要求解释"在修改每一处代码前,先解释为什么要这样改"

经验法则:如果需要超过 3 次迭代才能得到理想结果,通常意味着初始 Prompt 缺少关键约束——回头审视 5W 框架,找出遗漏的信息。