Cursor 用了半年,我总结了这些反直觉的经验
Cursor 半年实战踩坑总结:Tab 补全陷阱、提问技巧、行内编辑与 Chat 的选择。
# Cursor 用了半年,我总结了这些反直觉的经验
半年前开始把 Cursor 作为主力编辑器,从最初的"哇好神奇"到现在的"就这?",中间踩了不少坑,也发现了一些违反直觉的事情。
别把 AI 当编译器
这是新手最容易犯的错误:写一堆烂代码,然后让 AI "修复"。
AI 不会让你的烂代码变好,它只会让你的烂代码看起来不像烂代码。代码质量的上限取决于你给它的上下文。
**正确姿势:先自己写清楚,再让 AI 补全。**
// ❌ 错误示范
function process(data) {
// TODO: implement
}
// ✅ 正确示范
interface UserRecord {
id: string;
email: string;
lastLogin: Date;
tier: 'free' | 'pro' | 'enterprise';
}
async function processUserRecords(
records: UserRecord[],
config: { includeInactive: boolean; maxResults: number }
): Promise<UserRecord[]> {
// 先写清楚函数签名和注释意图
// AI 基于这个上下文补全实现
}
函数签名和注释就是上下文。上下文越清晰,AI 的输出越可靠。
Tab 键的陷阱
Cursor 的 Tab 补全功能很强,但有个坑:它倾向于给出"最可能的下一个 token",而不是"最正确的实现"。
当你写到一个关键决策点时,Tab 补全可能会把你引向一个看似合理但实际有问题的方向。
**我的策略:只在简单重复代码时用 Tab,逻辑决策点必须自己敲。**
比如在写 API 路由时,Tab 补全可能会给你一个标准的 CRUD 模板,但如果你需要加权限校验或者数据转换,就必须自己写。
不要过度依赖 Chat
Cursor 的 Chat 功能很方便,但有个问题:你问得越宽泛,它答得越正确但越没用。
"帮我优化这段代码" → 得到一个正确的但泛泛的回答
"这段代码在并发场景下有 race condition,怎么修" → 得到一个精确的可执行方案
**提问技巧:给出具体约束和场景。**
# 坏问题
这个函数怎么改更好?
# 好问题
这个函数在每秒 1000 请求的负载下会出现连接池耗尽,
当前用的是 default 配置。帮我改成连接池复用方案,
不要引入新的依赖。
好问题让 AI 在正确的约束下工作,输出质量天差地别。
行内编辑 vs Chat:什么时候用哪个
行内编辑(Cmd+K)适合:
Chat 适合:
我的日常比例大概是 7:3,行内编辑占绝大多数。Chat 用来处理那些我不确定怎么下手的问题。
一个反直觉的发现:AI 写测试比写业务代码更可靠
这可能是最违反直觉的一点。
业务代码涉及很多上下文依赖和边界条件,AI 容易忽略。但测试代码有明确的输入输出,AI 更容易生成正确的用例。
**所以我的策略是:让 AI 多写测试,少写业务逻辑。**
// 让 AI 生成的测试,准确率出奇地高
describe('UserService.create', () => {
it('should reject duplicate email', async () => {
await userService.create({ email: 'test@example.com' });
await expect(userService.create({ email: 'test@example.com' }))
.rejects.toThrow('Email already exists');
});
it('should hash password before saving', async () => {
const user = await userService.create({
email: 'test@example.com',
password: 'plaintext123'
});
expect(user.password).not.toBe('plaintext123');
});
});
这些测试用例覆盖了业务代码中容易遗漏的边界条件,而且生成质量很高。
最后:Cursor 是工具,不是替代品
用半年了,我的结论是:Cursor 能显著提升效率,但不能替代思考。
它帮你省去的是打字的时间,不是设计的时间。架构决策、模块划分、接口设计——这些还是得自己想清楚。
把 Cursor 当成一个反应很快但有时候会跑偏的初级工程师。你可以信任它的执行力,但不要盲信它的判断。