1. 先说个反直觉的现象:Cursor 明明"看得到"你的代码,为什么经常答非所问
这两年我几乎每天都在用 Cursor 写代码,但很长一段时间里,我对它的真实评价是"一个能聊天的自动补全插件"。写代码敲 Tab、遇到报错把日志贴进对话框、让它补个函数,这类轻量用法确实舒服。可一旦碰上稍微复杂一点的需求,AI 给出的方案经常让我血压升高:用 A 模块的思路去改 B 模块的代码,看起来逻辑自洽,跑起来全是坑。更让人恼火的是,你明明把相关代码都贴给它看了,它还是给出一种"好像懂了、又好像完全没懂"的答案。
最典型的一次翻车,是我让 Cursor 给一个维护了两年的后端服务加"批量导入"接口。它非常认真地把导入逻辑、字段校验、日志记录全写了,唯独用了项目里已经废弃的一套旧工具类。代码能跑,但风格、依赖、异常处理方式跟现有代码完全脱节,代码审查时被同事直接打回。当时我的第一反应是"模型太笨了"。后来我做了个实验:在对话里手动 @ 了项目里最新的工具类文档,又补了一句"项目里已废弃 XXX,统一使用 YYY"。结果它给出的方案当场就靠谱了,不仅选了正确的工具类,还顺带提醒我旧工具类里有两个已知的边界问题。
这个实验让我想明白一件事:多数时候 Cursor 不是在"读不懂"你的代码,而是你从没给过它读懂的机会。这篇文章要讲的,就是我怎么把 Cursor 从一个"自动补全插件"调教成一个真正理解项目上下文的"结对程序员",以及这套方法如何复用到团队协作里。内容不涉及复杂的理论,都是我在真实项目里踩过坑之后验证过的做法,可以直接照抄。
1.1 索引不等于理解,看到不等于参考
Cursor 启动后会扫描项目文件、建立代码库索引,这让它在回答问题时能检索到相关代码片段。但"检索到"和"生成代码时真的参考了"完全是两回事。模型每次生成时能携带的上下文是有限的,它不可能把整个项目从头到尾读一遍再回答你。
打个比方:你给新同事开了整个代码仓库的权限,但他面对十万行代码根本不知道先看哪里。你要做的是告诉他"这个项目是前后端分离的,后端用了什么框架,鉴权逻辑在哪个目录,数据库表结构在哪个目录,你先看这几个文件"。Cursor 也是这样——你负责指路,它负责干活。很多人忽略了"指路"这一步,直接把一堆代码丢过去,期待 AI 自己领悟,结果自然不理想。
1.2 上下文窗口有物理上限,你才是信息的筛选者
这里要提一个绕不开的概念:上下文窗口。Cursor 底层调用的模型在单次生成时能"同时看到"的 token 数量是有限的。虽然现在上下文窗口越做越大,但一个成熟项目可能有好几十万行代码,一个大型前端项目的 node_modules 就有上万个文件。你不可能把整个仓库都塞进去。
这个物理限制决定了使用 Cursor 的正确姿势不是"模型全知全能",而是"人负责筛选信息,模型负责生成代码"。选择哪些文件、哪些文档、哪些约束喂给它,恰恰是工程师的核心价值。很多"AI 编程翻车"案例里,AI 栽在的都是那些"你觉得是常识、但从没写进任何文档"的项目隐规则上——你的工作,就是把隐规则显式化。这也是整套实践方法的起点:先让 AI 看到正确的上下文,再让它动手。
2. 理解 Cursor 的三种项目上下文机制
在讲具体实践前,先把 Cursor 里最常用的三种"让 AI 读代码"的机制说透。很多人天天在用,但不清楚它们各自的能力边界,用错场景自然效果差。
2.1 代码库索引:Cursor 的长期记忆
Cursor 会定期扫描仓库建立索引,让你在对话时可以直接问"这个导出功能在哪个文件里",它会在整个代码库里检索相关内容。比如你问"当前项目的用户登录逻辑是怎么实现的",它能顺藤摸瓜找到 controller、service、model 各层的相关文件。索引是 Cursor 的基础记忆层,但它擅长的是"定位"而不是"深度理解"。
实际操作中你需要留意几点:
- 索引默认会排除
.gitignore里的目录,但很多项目的.gitignore写得并不完整 - 可以通过
.cursorignore文件自定义排除项,语法和.gitignore保持一致 - 如果某个文件老是检索不到,很可能是被索引排除掉了,去 Settings 里查看索引状态即可
索引的作用是让 AI"知道项目里有这个东西",但想让它真正"看懂"某段逻辑,还需要靠下面这种显式引用来喂细节。
2.2 @ 引用:指哪看哪的显式上下文
输入框里输入@,可以引用文件、文件夹、文档、搜索结果等。这是我认为最被低估的功能。很多人知道它能引用文件,但不知道什么场景该引用哪些内容。我按场景整理了用法:
| 场景 | 做法 | 说明 |
|---|---|---|
| 修单个文件的 bug | 直接 @ 该文件 | 上下文精简,AI 能精准聚焦 |
| 跨模块改造 | 多选 @ 相关文件 | 控制在 3~5 个核心文件内 |
| 让 AI 了解全局 | @ README、架构文档 | 相当于先给 AI 一张地图 |
| 让 AI 搜索代码 | 使用 Codebase 搜索 | 适合"这个功能在哪儿"类问题 |
有个技巧很关键:不要一次性把 20 个文件全 @ 上来。先 @ 核心文件,让 AI 给出初步思路,再按需补充。一开始堆太多文件,AI 反而会"贪多嚼不烂",生成的代码容易张冠李戴,把 A 模块的命名混进 B 模块。
2.3 Rules:把规范和约束刻进 AI 的长期习惯
Rules(在 Cursor Settings 里配置,也可以在项目根目录.cursor/rules下配置)相当于给 AI 预设的"行为准则"。它和 @ 引用的关键区别在于:@ 引用只管当前这一次对话,Rules 则是对项目里所有新对话都生效的"长期记忆"。也就是说,你可以在任何新对话里重复使用它,不需要每次手动强调。
我建议每个项目都放一份.cursor/rules,内容大致包括四类:
- 技术栈说明:前端用 Vue3 + TypeScript + Vite,不要写 Vue2 风格;后端用 FastAPI,路由统一走
/api/v1前缀 - 强制约束:不要修改 public/ 下的文件;新增 API 必须写 JSDoc;不允许引入新的第三方库
- 代码风格:组件文件名用 PascalCase;工具函数用 camelCase;缩进统一 2 空格
- 提交规范:commit message 使用 conventional commits 格式
要注意 Rules 不是越长越好。太长的规则会在模型脑子里"互相稀释",关键约束反而容易被忽略。我的经验是控制在 20 条以内,每条尽量一句话说清楚,宁可多拆几个文件,也不要堆一个巨型规则文件。
3. 一套可直接照搬的项目上下文配置方案
理解机制之后,我们来看怎么把组合起来。以下是我在多个项目里验证过、可以直接照抄的配置方案,核心就一句话:给 AI 做好岗前培训。
3.1 新项目接入时,花 20 分钟做"破冰"
拿到一个已有项目,尤其是接手老项目,我建议先别急着让 AI 干活,花 20 分钟做三件事:
第一,写一份简短的ARCHITECTURE.md。不用长篇大论,几百字即可,但要说清楚这几件事:项目是单体还是微服务、核心模块有哪几个、请求从入口到数据库的链路大概什么样、哪些目录是自动生成不要碰。比如这样:
# 架构说明 - 单体应用,Python FastAPI + PostgreSQL - 用户模块:负责注册、登录、权限校验,入口在 app/api/users.py - 业务模块:负责订单、支付、退款,入口在 app/api/orders.py - 数据库迁移:所有表结构变更写在 migrations/ 目录 - 不要手动修改 app/schemas/ 下自动生成的 Pydantic 模型第二,在项目根目录创建.cursor/rules,把技术栈、约束、风格写进去。第三,检查.gitignore和.cursorignore,确认node_modules、dist、__pycache__等目录不会被索引。
这三步做完,Cursor 在回答问题时就像拿到了一张项目地图,不再是盲人摸象。特别是接手老项目时,有了一份架构说明,AI 给出的方案会明显更贴合现状,而不是泛泛地套用通用代码模板。
3.2 规则文件的写法比你想的更讲究
写规则文件很像写新人 onboarding 文档,核心原则是"具体、可验证、不矛盾"。我踩过的坑包括两类典型写法:
- 错误写法:"代码质量要好"——这不是规则,是废话,AI 无法据此判断对错
- 正确写法:"所有公共函数必须有 JSDoc/TSDoc 注释,包含参数说明和返回值说明"
- 错误写法:"尽量不用 any"——边界模糊,AI 不知道什么时候算"尽量"
- 正确写法:"禁止显式使用 any;确实无法避免时,必须加 eslint-disable 并写明原因"
我更推荐"禁止 + 例外 + 例子"的句式。举个例子:
禁止直接修改 database/migrations/ 下的表结构文件; 如果确需变更表结构,先创建新的迁移文件,并确保新旧版本兼容。因为模型本质是在做概率预测,给出明确的前后约束,比一句模糊的方向可靠得多。如果团队里有代码规范文档,可以直接把它精简后塞进规则文件,但你自己的口头禅和"潜规则"也要写进去——那些才是 AI 最缺的信息。
3.3 索引排除项:别让 AI 在产物目录里迷路
.cursorignore文件建议至少包含这些目录:
node_modules dist build coverage .next __pycache__ *.min.js *.map排除它们不只是为了提升索引速度。更重要的原因是:自动生成的文件不代表项目真实写法,AI 看了反而会误解架构。比如.next目录里有大量编译产物和压缩后的命名,AI 一旦检索到,就会把那些风格当作输出范本,生成一些看起来"不太对劲"的代码。.map文件也同理,它们是源码的映射,对理解业务逻辑没有任何帮助。
注意:改完
.cursorignore后建议重启 Cursor 让索引重新建立。如果你发现 AI 对某些代码风格的判断突然异常,优先检查索引里是不是混入了产物文件。
4. 从需求到提交:一套围绕 Cursor 的编码工作流
工具配置好了,关键看干活时怎么用。下面这套工作流我在团队里推了几个月,上手成本很低,但效率提升是肉眼可见的。
4.1 把模糊需求翻译成 AI 能执行的指令
大多数 AI 翻车的根源,不是模型不够聪明,而是指令太模糊。对比两种说法:
- 差:"给用户模块加个导出功能"
- 好:"在用户管理页新增一个导出按钮,点击后调用 /api/users/export 接口,按当前筛选条件导出 CSV;导出过程中按钮禁用并显示 loading;失败时弹出错误提示,提示文案为'导出失败,请稍后重试'"
显然,后者的可执行性高了一个量级。我自己总结了一个"指令五要素",每次都按这个结构来写:
| 要素 | 要回答的问题 |
|---|---|
| 目标 | 做什么,明确到动词和对象 |
| 范围 | 哪些做、哪些明确不做 |
| 约束 | 技术栈、风格、依赖限制 |
| 输入输出 | 接口入参出参、页面交互、异常处理 |
| 验收标准 | 怎么做才算完成 |
这不是什么高深理论,就是把你平时跟同事沟通需求时脑子里那套信息,显式地摊给 AI。你会发现,很多时候你写不清 prompt,根源不是不会用 Cursor,而是你自己的需求还没想清楚。
4.2 先让 AI 出方案,再让 AI 写代码
遇到复杂需求,我一般会先让 Cursor 出实现方案,而不是直接让它写代码。具体做法是在对话里说:
"先不要写代码。分析现有用户模块的数据流,给出一个按当前筛选条件导出 CSV 的实现方案,包括涉及的文件、依赖关系、潜在风险。"
这一步的价值非常大:AI 先生成方案,就会先去检索代码库、梳理调用关系,而不是从第一个文件开始埋头写。你可以在方案阶段纠正它的方向,比如"不要改 service 层,应该新增一个 export service"。方向对了,代码质量才有底线。
在实际操作中,我甚至会给 Cursor 下一条规则,让它默认就按"先给方案、再写代码"的方式来响应复杂需求。这样即使团队里有人忘记交代,AI 也会自己先想清楚再动手。
4.3 AI 生成的代码,必须走一遍"候选人审查"
AI 写完代码,我从不直接 commit。固定做两件事:
第一,让 AI 自检一遍。在对话里补一句:"检查你刚才生成的代码,找出潜在的边界问题、错误处理遗漏、和现有代码风格不一致的地方。" 这一步能滤掉不少低级 bug,比如数组越界、空指针、并发安全等。
第二,自己快速看一遍 diff。重点检查四个方面:有没有引入意外依赖、有没有改到不该动的文件、异常分支是否覆盖完整、有无把调试代码混进去。
团队协作时还有一个实际问题:AI 生成的代码格式可能和项目统一格式不一致。不要指望 AI 靠"意念"遵守缩进规则,跑一次格式化工具(Prettier、Black、gofmt 等)是必须的。把它当候选人来审查和校准,代码库质量才能稳定。
5. 我踩过的坑,和最终沉淀下来的几个习惯
这节是我自己用 Cursor 大半年后留下的记忆点,写出来帮大家少走点弯路。每一件都是真金白银换来的教训。
5.1 上下文给多给少都不行,怎么判断?
刚开始我总觉得多引用几个文件,AI 就会更懂项目。结果它经常在多个文件之间"左右逢源",把 A 模块的命名混进 B 模块。后来我找到一个判断信号:如果 AI 的回答出现"张冠李戴"式的命名错误,多半是上下文太多导致混淆;如果回答很泛、没有针对你项目的具体细节,就是上下文太少。
根据这个信号动态调整 @ 引用的文件数量,比每次机械地"堆文件"可靠得多。另外一个辅助手段是:在对话时让 AI 自己列出"它用了哪些文件作为依据",如果它列出的文件里有明显无关的,就及时移除,保持对话干净。
5.2 AI 改崩了代码,最快的恢复方式不是 Ctrl+Z
Cursor 的多文件改动可能一次碰 5 个文件,其中一个改坏,而编辑页早关掉了,想恢复只能靠 Git。所以我给自己定了一条铁律:所有 AI 辅助的大改动,动手前先切一个新分支。然后每完成一个小改动就提交一次,commit message 写清楚。
有这样一个分支,哪怕 AI 改崩了某个环节,一行git checkout就能回到上一个稳定点,不用陪它复盘"到底是哪一步出的问题"。如果团队里多人协作,建议再加一条:AI 生成的代码统一走 PR 流程,不要让 AI 的改动直接推到主干。这个习惯能帮你挡掉一大半的"AI 闯祸"。
5.3 不同技术栈下,Cursor 的表现差异比想象中大
Python 和 TypeScript 项目里用 Cursor 的感受完全不同。TypeScript 有类型系统,AI 很容易推断函数签名和调用关系,生成质量明显高;Python 项目如果缺类型标注,AI 在边界情况处理上就容易飘,经常漏掉空值判断或类型转换。
所以我的建议是:如果项目类型标注薄弱,要么用规则强制 AI 生成代码时补充类型标注,要么就做好预期管理——AI 更适合做"思路参考",代码把关还得靠自己。这不是模型不行,而是语言本身携带的静态信息量不一样。了解了这个差异,你就不会对 AI 在某些项目里的表现过度失望。
5.4 把好用的 Prompt 沉淀成自己的"方言库"
最后一个非常推荐的习惯:每当我发现一类 Prompt 在项目里特别好用,就会把模板存到一个ai-prompts.md文件里。比如:
- "帮我重构这个函数,保持对外签名不变"
- "给这段逻辑补充错误处理,错误信息用中文并带上上下文"
- "只改这几个文件,不要动其他模块"
- "先列出这三段代码的差异,再解释为什么会有这些差异"
这些模板的好处是,它们是你在真实项目里验证过、贴近自己代码风格的"方言",比网上抄来的通用提示词有效得多。积累半年之后,这个文件就是你的私人 AI 使用手册。我每隔一段时间会回头翻一翻,删除过时的,补充新的,对我来说它比大部分教程都有用。