Cursor高阶用法(4):高效Prompt工程 — 让AI第一次就给出符合预期的代码
作者:企起期小编 阅读次数:

Cursor高阶用法(4):高效Prompt工程 — 让AI第一次就给出符合预期的代码

章节配图封面图

在本系列的第三篇文章中,我们探讨了如何使用Composer来提升我们的开发效率。今天,我们将深入探讨如何通过高阶Prompt工程,让我们的AI伙伴第一次就能给出符合预期的代码。

为什么大多数人的Prompt效率不高?

章节配图

许多开发者在使用Cursor时会陷入一个循环:发送一个简单的需求,AI生成"差不多"的代码,然后不断修正直至满意。这不是AI能力的问题,而是信息传递的问题。AI没有你的隐性知识,一个好的Prompt就是将这些隐性知识显性化,让AI在信息完备的情况下做出决策。

Prompt的五层结构

章节配图

高质量的Cursor Prompt通常包含五个层次,可以按需组合:

[角色/背景] + [任务描述] + [约束条件] + [参考上下文] + [输出格式]

不是每个Prompt都需要五层,但对于复杂任务,缺少任何一层都可能影响结果的质量。

第一层:角色与背景

告诉AI它在什么样的场景中工作:

// 差:没有背景
写一个缓存函数

// 好:有背景
在 Node.js + Redis 的微服务架构中,
为 API 网关层写一个带 TTL 的请求结果缓存装饰器函数

如果你已经写了 .cursor/rules,这一层通常可以省略(规则文件已经定义了背景)。

第二层:任务描述的精准度

最常见的错误:任务描述停留在"什么",没有说"怎样的什么"。

模糊描述精准描述
写一个分页组件写一个基于 URL query params 的无限滚动分页组件,使用 IntersectionObserver API,不依赖第三方库
优化这段代码只优化性能(降低时间复杂度),不改变函数签名和返回值类型
帮我处理错误把 try/catch 改为 Result 模式(返回 { data, error } 而不是抛异常),保持函数是 async 的

实用技巧:倒叙描述法

// 正序(容易模糊)
"帮我写一个函数,遍历数组,然后过滤,然后转换..."

// 倒序(目标清晰)
"期望结果:把 User[] 转换为 Map<string, string>,key 是 userId,value 是 userName。
使用函数式写法(Array.reduce),不用 for 循环,不用中间变量。"

第三层:约束条件

约束是Prompt中最容易被忽视的部分,但也是价值最高的部分。好的约束可以防止AI引入不需要的依赖,确保代码风格与项目一致,避免AI"发挥过度"。

5.1 技术约束

约束:
- 只使用 Array 原生方法,不引入 lodash 或 ramda
- 函数必须是纯函数(无副作用)
- 不能修改入参(如需转换,请先深拷贝)
- TypeScript 严格模式,所有参数必须有类型标注

5.2 范围约束

范围:
- 只修改 src/utils/date.ts 文件
- 不改动该文件中已有的 formatDate() 函数
- 新函数加在文件末尾

5.3 质量约束

质量要求:
- 边界情况处理:null/undefined 入参、空数组、超大数字
- 写 JSDoc 注释(@param、@returns、@example 各一个)
- 不写注释解释"是什么",只写"为什么"

第四层:参考上下文(最容易漏掉)

AI不知道你的代码库里已经有了什么,所以你需要主动告诉它。

6.1 告诉AI已有的相关代码

项目中已有以下工具函数,写新代码时直接引用,不要重复实现:

// src/lib/api.ts
export async function fetchWithAuth<T>(url: string): Promise<T>

// src/lib/cache.ts  
export function memoize<T>(fn: () => T, ttl: number): () => T

新函数:写一个带缓存的用户权限查询函数,引用上面两个工具。

6.2 提供期望的输入/输出示例

函数签名:parseMarkdownTable(markdown: string): TableData[]

输入示例:
"| Name | Age |\n|------|-----|\n| Alice | 30 |\n| Bob | 25 |"

期望输出:
[
  { Name: "Alice", Age: "30" },
  { Name: "Bob", Age: "25" }
]

边界情况:
- 空字符串 → 返回 []
- 没有数据行(只有表头)→ 返回 []
- 单元格有空格 → trim 处理

6.3 展示现有代码的样式,让AI模仿

项目中已有类似实现,请参考这个样式写新的函数:

@src/lib/validators.ts

用同样的模式写一个 validateEmail(email: string) 函数。

第五层:输出格式

明确你想要什么格式的输出,可以大幅减少废话:

// 直接给代码,不需要解释
只输出代码,不要说明你做了什么修改

// 只给 diff
只给出需要修改的行,用 +/- 标注,不要输出整个文件

// 需要解释
给出代码后,用 3 句话解释核心逻辑,不需要解释 TypeScript 基础知识

// 需要多个方案
给出 2 种实现方案,每种方案后面写一行优缺点对比

调试场景的Prompt技巧

章节配图

调试时,光贴错误信息往往不够。推荐的调试Prompt结构:

【错误现象】
调用 createOrder() 时,数据库抛出 "unique constraint violation"

【错误信息】(完整堆栈)
Error: duplicate key value violates unique constraint "ordersordernumber_key"
  at PostgresQuery.run (/node_modules/...)
  at ...

【相关代码】
@src/lib/order.ts(createOrder 函数)
@prisma/schema.prisma(Order model 定义)

【我的分析】
我猜测是 orderNumber 生成逻辑在高并发下产生了重复值,
但不确定应该在数据库层还是应用层解决。

【期望的帮助】
1. 确认我的分析是否正确
2. 如果是的话,给出两种解决方案(数据库锁 vs 应用层重试)及其取舍
3. 实现你推荐的那种方案

代码审查场景的Prompt技巧

章节配图

让AI帮你做代码审查,但要避免它给出"这段代码很好,只需要注意..."这种敷衍回答:

请以 Senior Engineer 的视角 Review 以下代码,
专注于以下几个维度(按优先级排序):

1. 安全漏洞(SQL 注入、XSS、权限绕过、敏感信息暴露)
2. 性能问题(N+1 查询、内存泄漏、不必要的同步操作)
3. 并发安全(Race condition、共享状态未保护)
4. 错误处理遗漏

对于每个发现的问题:
- 指出具体的代码行数
- 解释风险
- 给出修复建议(不需要写完整修复代码,思路即可)

如果代码没有明显问题,直接说"未发现明显问题",不需要找补。

@src/api/payment.ts

从"提需求"到"提约束"的思维转变

章节配图

大多数人对AI的习惯是"提需求",更高效的姿势是同时提约束

一个思维模型:每次写Prompt之前,问自己三个问题:

  1. AI 最可能往哪个方向偏?(用约束拦截这个方向)

  2. 哪些东西是绝对不能动的?(明确说出来)

  3. 我能给AI哪些参考,让它不用猜?(输入/输出示例、已有代码)

场景Prompt速查表

场景Prompt 关键要素
写新功能函数签名+输入输出示例+约束(不能引入哪些依赖)
重构代码明确不能改的部分+性能/可读性目标+测试要求
调试 Bug错误信息+相关文件+你的假设+希望的帮助类型
代码审查Review 维度优先级+具体格式要求+"无问题则直说"
写测试测试框架+覆盖要求+Mock 策略+边界用例清单
文档目标读者+文档类型(JSDoc/README/API 文档)+风格要求
技术选型项目规模+团队能力+不可妥协的约束+决策框架

小结

高效Prompt的本质是信息密度:在尽量少的字数里,传递AI做正确决策所需的完整信息。

不需要每次都写完整的五层结构,根据任务复杂度按需组合:

  • 简单任务:任务描述 + 1-2 个关键约束

  • 中等任务:任务描述 + 约束 + 参考上下文

  • 复杂任务:完整五层结构

最重要的习惯:养成写"不要做什么"的意识,这比写"要做什么"更容易防止AI走弯路。

在下一章,我们将探讨自定义模型与团队工作流集成:如何接入DeepSeek等国产模型,以及如何在团队中建立AI辅助开发的规范。感谢你的关注,我们下期再见!


返回列表

扫码关注不迷路!!!

郑州升龙商业广场B座25层

service@iqiqiqi.cn

企起期科技 qiqiqi

联系电话:187-0363-0315

联系电话:199-3777-5101