
1. 为什么我要把 Cursor 当成一个“项目”来用第一次用 Cursor 的人十有八九是把它当成“能聊天的 VS Code”。装完插件、打开侧边栏、敲一句“帮我写个登录页”然后看着它吐出一大段代码复制粘贴跑起来报错再问再改。折腾一下午代码是能跑了但你自己心里清楚这玩意儿没帮你省多少事反而多了一堆看不懂的代码。我用 Cursor 大概有半年多前两个月基本就在这个循环里打转。真正让我改变用法的是一个很朴素的念头别把它当补全工具把它当成一个刚入职、能力很强但完全不了解你项目的同事。这个同事记性很好、打字飞快、知识面广但他不知道你的目录结构、不知道你的命名习惯、不知道你上周为什么把那个函数拆成三个。你要做的不是“让他写代码”而是“让他先读懂项目再动手”。这个视角一换用法就完全不一样了。PStack 这个系列我一直想写的就是这种“把工具当项目来管理”的思路。这篇就围绕 Cursor 展开讲清楚我怎么用它、为什么这么用、哪些坑我踩过。适合两类人看一类是刚上手 Cursor、还在“聊天框里贴代码”阶段的朋友另一类是用了挺久但总觉得效率没提上去、想系统化整理工作流的人。全文不讲玄学只讲我实际跑通的流程和参数。2. 先搞清楚 Cursor 到底强在哪别用错力气2.1 它和普通补全工具的本质区别普通代码补全工具的核心能力是“预测你下一行要写什么”它的上下文窗口通常只有当前文件甚至当前几行。Cursor 的核心能力是“理解一个代码库的局部然后按你的意图生成或修改代码”。这个区别听起来很虚但落到操作上非常具体。举个我自己的例子。我有个项目里有个utils/format.ts里面有个formatCurrency函数处理了三种货币符号和两种小数位规则。普通补全工具在我写formatCurrency(的时候只能提示参数名。而 Cursor 在我选中一段调用代码、按CmdK输入“把这个调用改成支持日元小数位保留 0 位”之后它会去读formatCurrency的定义发现里面有个currencyMap对象然后自动往里面加日元配置再改调用处。它做的是跨文件的语义修改不是文本替换。这就是为什么我说“别用错力气”。如果你只让它补全单行那它的价值可能还不如一些轻量插件。它的价值在“理解 批量修改 跨文件重构”。2.2 三种交互模式对应三种完全不同的场景Cursor 的交互入口主要有三个我按使用频率排模式触发方式适合场景我的使用频率Tab 补全直接打字时自动出现写重复结构、补全参数、改错别字每天几百次行内编辑选中代码后CmdK局部重构、加注释、改逻辑每天几十次侧边栏对话CmdL或点侧边栏跨文件任务、问架构、生成新模块每天十几次很多人只用了第一个和第三个忽略了CmdK这个中间态。实际上CmdK是我用得最顺手的选中一段代码输入一句自然语言它直接在原地改改完你还能看 diff 决定接不接受。这个“原地改 diff 确认”的体验比在侧边栏里来回粘贴强太多。提示CmdK的输入框里可以写多行指令按ShiftEnter换行。我经常写两三行把约束条件列清楚比一句话效果好很多。2.3 上下文窗口不是越大越好关键在“喂什么”Cursor 支持把整个文件、整个目录甚至整个项目加进上下文。新手容易犯的错是“全选加进去让它自己找”。实测下来上下文塞太满反而会让它抓不住重点生成的东西开始“飘”。我的做法是只喂和当前任务直接相关的 2 到 4 个文件。比如我要改一个 API 的返回结构我会加三个文件路由定义、对应的 service、以及类型定义文件。这三个文件足够它理解数据流又不会让它分心。如果任务涉及更广我会先用侧边栏问一句“这个功能涉及哪些文件”让它列出来我再手动挑几个加进去。这个“先问范围再喂文件”的习惯是我踩了无数次“它改错文件”的坑之后养成的。3. 我的 Cursor 工作流从项目初始化到日常开发3.1 项目初始化阶段先写一份“给 AI 看的说明书”新项目或者刚接手一个老项目我做的第一件事不是写代码而是在项目根目录建一个.cursorrules文件。这个文件 Cursor 会自动读取相当于给它的“项目须知”。我自己的.cursorrules大概长这样你可以直接抄结构# 项目技术栈 - 前端React 18 TypeScript Vite - 状态管理Zustand禁止引入 Redux - 样式Tailwind CSS禁止写内联 style - 请求统一走 src/api/request.ts 封装禁止直接用 fetch # 代码规范 - 组件文件用 PascalCase工具函数用 camelCase - 所有导出必须显式写类型禁止 any - 注释用中文函数上方写一行说明用途 # 目录约定 - src/components 放通用组件 - src/pages 放页面级组件 - src/hooks 放自定义 hooks - src/utils 放纯函数工具 # 禁止事项 - 不要自动生成测试文件除非我明确要求 - 不要修改 package.json 里的依赖版本 - 不要动 .env 文件这份文件看起来简单但它解决了一个大问题每次对话不用重复交代背景。以前我每开一个新对话都要说“我们用 Zustand 不用 Redux”现在它自己知道。实测下来有了这份文件之后它生成代码的“返工率”至少降了一半。注意.cursorrules不要写太长控制在 50 行以内。写太多它反而会忽略部分内容。把最关键的约束放前面。3.2 日常开发把任务拆成“它能一次做对”的粒度这是我最想强调的一点。Cursor 不是不能做复杂任务而是复杂任务需要你拆。我见过有人直接输入“帮我实现一个完整的用户管理模块包含增删改查和权限控制”然后抱怨它生成的东西不能用。这不是它的问题是任务粒度的问题。我的拆法是这样的。假设要做一个用户列表页我会拆成四步每步单独对话第一步定义类型。输入“根据这个接口文档在src/types/user.ts里定义 User 类型和查询参数类型”。这一步只产出类型文件简单、可验证。第二步写 API 层。输入“在src/api/user.ts里写 getUserList 函数用 request.ts 封装参数用上一步的类型”。它读得到上一步的文件直接复用。第三步写 hooks。输入“写一个 useUserList hook调用 getUserList处理 loading 和 error 状态”。第四步写页面。输入“用 useUserList 写一个用户列表页用 Tailwind 做表格支持分页”。每一步的产出我都能快速看一眼、跑一下、确认没问题再进下一步。这样即使某一步它做错了我也只损失几分钟而不是推翻一整个模块。这个“四步拆解法”是我用得最顺的节奏。它的本质是让每一步的上下文都足够小、足够明确这样 Cursor 的准确率会高很多。3.3 重构场景用CmdK做“外科手术”重构是我觉得 Cursor 最值的地方。以前改一个函数的签名要全局搜索、逐个改、还要担心漏掉。现在我的流程是选中函数定义CmdK输入“把参数从对象改成三个独立参数并更新所有调用处”。它会先改定义然后提示“发现 7 处调用是否一并修改”。我点确认它逐个改每改一处我都能看 diff。这里有个细节改之前先提交一次 git。因为 Cursor 的批量修改偶尔会改错地方尤其是当有同名函数的时候。有 git 兜底改错了直接git checkout .重来心里不慌。还有一个技巧如果重构涉及的文件超过 5 个我会先在侧边栏问“这个函数被哪些文件引用了”让它列清单然后我手动确认清单对不对再让它动手。多这一步能避免它漏改或者改错。4. 那些让我效率翻倍的进阶用法4.1 用精确指定上下文在侧边栏对话时输入会弹出文件、目录、甚至符号的列表。我常用的三种文件路径精确加某个文件。比如src/utils/format.ts。目录路径加整个目录。比如src/components适合“这个目录下所有组件都加一个 props 校验”这种任务。符号名加某个函数或类。这个用得少但在大文件里定位很准。新手容易忽略直接在对话里说“那个 format 文件”。它可能找得到也可能找错。用是零成本的精确没理由不用。4.2 让它“先解释再动手”遇到不熟悉的代码我会先让它解释而不是直接改。比如选中一段复杂的正则CmdK输入“逐段解释这个正则的含义用中文”。它解释完我理解了再决定怎么改。这个习惯帮我避免了很多“它改完我看不懂、出了问题查不出”的情况。尤其是接手老项目的时候先让它当“翻译”比直接让它当“手术刀”安全得多。4.3 用对话历史做“决策记录”Cursor 的侧边栏对话是可以保存和命名的。我会把一些重要的技术决策对话命名保存比如“用户模块架构讨论”“支付流程重构方案”。过两周回头看能快速回忆起当时为什么这么设计。这个用法有点像“把 Cursor 当会议记录员”。它记录的不是结论而是推导过程。有时候我忘了某个设计的原因翻一下当时的对话比翻 git log 还快。5. 踩过的坑和排查技巧5.1 它改错文件了怎么办这是最常见的坑。表现是你让它改 A 文件它把 B 文件也改了或者改到了错误的函数里。排查思路分三步看 diff。Cursor 每次修改都会显示 diff养成“改完必看 diff”的习惯能拦住 90% 的错误。检查上下文。如果 diff 里出现了你没加进上下文的文件说明它“自作主张”了。这时候回退重新用精确指定文件。检查同名符号。如果项目里有两个handleSubmit它可能改错。解决方法是选中你要改的那个用CmdK而不是侧边栏因为CmdK的上下文是你选中的代码更精确。5.2 生成的代码跑不起来常见原因和解决方式我整理成表现象可能原因解决方式报“找不到模块”它用了不存在的依赖检查 package.json手动装或让它换方案类型报错它没读到类型定义文件把类型文件用加进上下文逻辑不对任务描述有歧义把任务拆小重新描述样式不生效它用了内联 style 而项目用 Tailwind在.cursorrules里写清楚样式规范5.3 对话越来越“飘”长对话到后面它开始忘记前面的约束生成的东西越来越离谱。这是上下文窗口的固有限制不是 bug。我的应对方式是一个任务一个对话。做完一个任务开新对话。如果任务确实很长我会在对话中间手动“复述约束”比如“注意我们仍然用 Zustand不要引入其他状态库”。这句话能把它拉回来。提示侧边栏对话右上角有个“新对话”按钮别舍不得开新对话。一个干净的上下文比一个塞满历史的上下文好用得多。5.4 关于隐私和代码安全这一点必须提。Cursor 会把你的代码片段发送到它的服务端处理。如果你的项目涉及敏感信息要么用它的本地模式如果版本支持要么对敏感部分做脱敏。我自己的做法是涉及密钥、内部地址、用户数据的代码不直接贴进对话。需要它帮忙时我会用占位符替换敏感值比如把真实地址换成API_BASE_URL让它基于占位符写逻辑我再手动替换回去。6. 我总结的一套“最小可用工作流”如果你只想记住一件事那就记住这个流程项目开始写.cursorrules把技术栈、规范、禁止事项列清楚。每个任务拆成 3 到 4 步每步一个对话每步产出可验证。改代码优先用CmdK原地改改完必看 diff。加文件用精确指定只喂相关的 2 到 4 个文件。长任务中间手动复述约束做完开新对话。敏感代码脱敏后再贴或者不贴。这套流程我跑了几个月最大的感受是Cursor 的上限不取决于它自己取决于你怎么用它。你把它当聊天框它就是个聊天框你把它当项目成员来管理它就能真的帮你干活。最后分享一个小技巧每周花十分钟回顾一下你这周和 Cursor 的对话看看哪些任务它一次做对了、哪些反复出错。出错多的任务类型往往是你描述方式有问题或者.cursorrules里缺了某条约束。把这个补上下周的效率又会高一点。这个“复盘”习惯比任何技巧都管用。