Cursor用了一年,这些坑我帮你踩了
一线开发者真实使用Cursor一年的踩坑经验:上下文窗口谎言、代码审查盲区、Tab补全陷阱,以及真正好用的场景和配置建议。
# Cursor用了一年,这些坑我帮你踩了
去年这个时候,我信了营销文案的邪,花$20买了Cursor Pro。说是一线开发者的"第二个大脑",能理解整个代码库,重构就像改一行那么简单。
一年过去了,我确实每天都在用,但跟他们宣传的完全不是一回事。这篇文章就是想告诉你,Cursor真正能做什么,不能做什么,以及那些官方文档里不会写的坑。
先说结论:值不值$20/月?
值,但不是因为他们的营销卖点。
如果你指望Cursor能"理解你的整个项目"然后帮你从0写一个模块,趁早放弃。它的真正价值在于:**当前文件的上下文补全 + 来回对话式的代码审查 + 快速的样板代码生成**。
那些"AI帮我重构了整个系统"的推文,要么是玩具项目,要么就是没说清楚他们花了多少时间调试AI生成的代码。
第一个坑:上下文窗口的谎言
Cursor宣传说能"理解整个代码库",技术上没错——它确实会索引你的项目。但实际用起来,这个"理解"有两个致命问题:
**1. 索引是静态的**
你改了代码,它不会实时更新索引。我遇到过最离谱的情况:重构了一个函数签名,Cursor还在用旧签名生成调用代码。排查了半小时,才发现它读的是三天前的索引。
解决方法:每次开始重要会话前,手动触发重新索引(Ctrl+Shift+P → "Cursor: Rebuild Codebase Index")。但这个操作要花时间,大项目可能要等5-10分钟。
**2. 上下文窗口远比你想象的小**
官方说支持几万个token的上下文,但那是理想情况。实际测试中,超过15-20个文件引用后,生成质量就开始明显下降。它会出现"幻觉"——编造不存在的函数,或者把其他项目的代码模式混进来。
我现在的做法是:**永远手动指定关键文件**。不要让它"自动选择上下文",而是用 @文件名 显式告诉它看哪里。虽然麻烦,但生成的代码靠谱得多。
第二个坑:代码审查模式的盲区
Cursor的"Code Review"功能听起来很酷:选中一段代码,让它帮你找bug、提优化建议。
但实际用下来,它有两个严重盲区:
**盲区1:它只看代码,不看运行时**
比如这段Node.js代码:
async function getUserOrders(userId) {
const user = await db.users.findById(userId);
const orders = await db.orders.find({ userId });
return { user, orders };
}
Cursor会说"代码看起来不错"。但它发现不了这个致命问题:userId 如果是 null 或 undefined,findById 会返回整个用户表的第一条记录(取决于你的ORM实现)。这种bug只有跑起来才会暴露。
**盲区2:安全审查基本靠猜**
我特意测试过,让它审查一段有SQL注入漏洞的代码:
def search_users(keyword):
query = f"SELECT * FROM users WHERE name LIKE '%{keyword}%'"
return db.execute(query)
Cursor的回复是"建议用参数化查询",但没说为什么,也没指出这是SQL注入漏洞。对比之下,GitHub Copilot的安全扫描会直接标记这是CWE-89漏洞。
所以我的结论是:**Cursor适合做代码风格和逻辑审查,但安全和性能审查还得靠专业工具**。
第三个坑:Tab补全的"聪明"陷阱
Cursor的Tab补全确实比GitHub Copilot更激进——它会预测你下一行要写什么,甚至整个函数体。
但问题就出在"太激进":
**场景1:它会"记住"你项目里的坏模式**
我们有个遗留项目,错误处理是用 try-catch 包裹整个函数然后 console.log 了事。Cursor学会了这个模式,每次生成新代码都这么写。
我花了两周才意识到问题:它把我们的技术债当成了"最佳实践"在推广。
**场景2:补全建议会打断你的思路**
有时候你正在想一个算法,Cursor突然弹出一个补全建议,恰好戳中你的思维盲区,然后你就被它的思路带跑了。
我现在的设置是:**关闭自动弹出,改用 Alt+\ 手动触发**。虽然慢一点,但至少不会被带偏。
真正好用的场景
说了这么多坑,Cursor到底哪里值得用?
**场景1:写样板代码**
比如我要写一个Express中间件的骨架:
// 我输入:
// middleware for rate limiting using redis
// Cursor生成:
import redis from 'redis';
import { RateLimiterRedis } from 'rate-limiter-flexible';
const redisClient = redis.createClient({
host: process.env.REDIS_HOST,
port: process.env.REDIS_PORT,
});
const rateLimiter = new RateLimiterRedis({
storeClient: redisClient,
keyPrefix: 'middleware',
points: 10, // 10 requests
duration: 1, // per second
});
export async function rateLimitMiddleware(req, res, next) {
try {
await rateLimiter.consume(req.ip);
next();
} catch (rejRes) {
res.status(429).json({
error: 'Too many requests',
retryAfter: Math.round(rejRes.msBeforeNext / 1000),
});
}
}
这种代码它写得比我快,而且踩坑经验都在(比如 msBeforeNext 的单位是毫秒,它知道要除以1000)。
**场景2:重构命名**
选中一个变量名,按 F2,Cursor会帮你把所有引用都改掉——这功能VS Code也有,但Cursor更聪明:它会理解你的代码语义,有时候能给出更好的命名建议。
比如我把 data 重命名为 userSession,它会问:"要不要顺便把 data2 改成 cachedSession?"这种上下文理解是纯规则引擎做不到的。
**场景3:快速原型验证**
有时候我想验证一个想法,但不想从头写代码。比如"用WebSocket做个简单的聊天室",Cursor能10分钟内帮我搭出能跑的原型。
关键是:**原型代码不要直接上生产**。我用Cursor生成原型后,会先自己重写一遍,把它的代码当"参考实现"而不是"最终代码"。
配置建议(这些设置帮我少踩很多坑)
**1. 关闭"Auto-apply suggestions"**
让它在chat里生成代码,你手动复制粘贴。虽然麻烦,但能避免它偷偷改你不想要改的文件。
**2. 设置 .cursorignore**
把 node_modules、dist、build 这些目录加到 .cursorignore,避免它索引无用文件浪费上下文。
我的 .cursorignore 长这样:
node_modules/
dist/
build/
coverage/
*.min.js
*.map
package-lock.json
**3. 用 Rules for AI 设定项目规范**
在项目根目录创建 .cursorrules 文件,写上你们的代码规范。比如:
这比每次在chat里重复要求有效得多。
最后一句话
Cursor是个好工具,但它不是魔法。把它当成一个"比较聪明的代码补全器"来用,你会觉得物超所值;把它当成"AI结对程序员",你会失望。
我最喜欢的用法是:**写代码时开着它的Tab补全,遇到难题时切到Chat问它,代码写完后让它帮我review一遍**。这个工作流我用了一年,确实提升了不少效率。
但如果你指望买个订阅就能少写代码——省省吧,世界上没有这种好事。
*P.S. 如果你也在用Cursor,欢迎评论区分享你的坑。我们一起把官方文档里没写的那些细节补全。*
VkingAI