Cursor 辅助编码实战:用 AGENTS.md 和提示词工程让 AI 真正读懂项目代码
发布时间:2026/9/14 7:12:50 作者:尧图编辑部 阅读量:1,286

如果你刚接触 Cursor大概率会有两种体验一种是惊叹“这玩意儿居然能预测我下一页要写什么”另一种是在反复修改提示词后崩溃——“它怎么就是不懂我的代码结构呢”。我属于后一种而且是反复崩溃过很多次之后才慢慢摸到门道的那种。后来我在一个 10 人左右的开发团队里引入了 Cursor 辅助编码发现一个特别扎心的事实这套工具的效果不取决于你用的是新模型还是老模型也不取决于工具有没有付费升级而是取决于你怎么喂给它上下文、怎么下指令、怎么约束它的行为边界。说白了同样是 AI 辅助编码有人用成了“自动补全”有人用成了“结对编程”差距全在实践方式上。所以今天这篇文章不聊安装不聊快捷键更不聊所谓的“咒语”就聊一套我自己整理出来的、任何项目都能直接用的 Cursor 辅助编码实践。核心目标只有一个让 AI 真正读懂你的代码而不是在你的代码里瞎猜。1. 先搞清楚AI 为什么总在你最需要它的时候掉链子我一直觉得很多人在 Cursor 上的第一个错觉就是“它应该有常识”。是模型预训练的时候看过海量 GitHub 代码但那是通用常识不是你项目里的“私有常识”。你的项目里那个getCustomerStatus()函数为什么叫这个名字、为什么状态字段用的是字符串而不是枚举、为什么老代码里有一堆从 PHP 时代留下来的命名习惯——这些东西模型看不到也不应该指望它猜得到。1.1 大部分“AI 读不懂代码”其实是人的输入问题我在团队里做过一个小实验给同一段代码让两个不同基础的人分别去 Cursor 里提问。A 的提问是“帮我把这个抽出来重构一下”B 的提问是“帮我把src/utils/formatPrice.ts里面的formatPrice函数改造成支持Intl.NumberFormat的实现并且保持原有单测通过”。结果非常典型A 拿到的是 Cursor 返回的一堆泛泛的、甚至是破坏性的建议B 拿到的是完全可以直接落地的补丁。这暴露了一个核心问题AI 读不懂代码往往是因为人没有给出足够的定位信息。你的代码库里可能有几十个叫handleClick的函数有几百个TODO注释有无数种“状态流转”的实现方式。你不指明精确的“经纬度”它就只能靠猜而猜的准确率和你代码注释的质量、函数命名的清晰度、目录结构的可读性呈正相关。1.2 三个最隐秘的“上下文杀手”第二个问题更隐晦。我把过去半年里遇到的“AI 突然开始胡说八道”的场景复盘了一遍发现几乎全是下面这三种情况在作怪。第一上下文窗口被无关内容塞满了。Cursor 的上下文窗口虽然越来越大但当你打开一个大型前端项目把所有打开的文件都暴露给 AI 时它实际上能有效关注的“重点”会被大幅稀释。模型是平均注意力的它会平等地看待你贴进去的每一个文件——包括那个 3000 行的constants.ts。我见过最夸张的一次是 AI 在我没提任何要求的情况下把src/constants/colors.ts里的主题色变量全部替换掉原因仅仅是因为那个文件排在上下文的最前面。第二对话历史里的错误假设会无限蔓延。Cursor 的 Composer 是保留多轮历史的。你说“把那个接口改成 POST”它会记住这句。下一个问题你问“帮我看下这个接口的调用方”它会下意识地认为所有调用方都该改成 POST然后给你生成一堆根本不需要的改动。这个问题的本质是你没有一个机制来重置对话状态或者明确告诉 AI“哪些话是过去的哪些是现在的”。第三项目的全局约束从来没有被传达过。比如你团队规定“不允许将业务逻辑写在组件里”“所有 API 请求必须走统一的request封装”“新代码必须兼容 Node 16”这些规则你心里清楚但你从没告诉过 Cursor。于是它理所当然地给你生成一个直接在useEffect里 fetch 的组件——因为网上 90% 的示例代码就是这么写的。它根深蒂固地认为一个组件就是一个能自给自足的“小宇宙”。2. 让 AI“看懂全局”的代码环境准备AGENTS.md 与项目档案很多人不知道Cursor 有个隐藏的“读说明书”机制AGENTS.md。这个文件放在项目根目录也可以放子目录Cursor 在每次对话时都会自动读取它当作项目级的高优先级上下文。它的作用和为实习生准备的《项目环境初始化文档》一模一样——让一个不了解你的人用最短的时间掌握你的规矩。2.1 AGENTS.md 到底该写什么我先给你看我这边一个真实前端项目的AGENTS.md长什么样你就明白这东西的价值了# 项目概述 这是一个面向中小商户的进销存管理后台技术栈为 React 18 TypeScript Vite Zustand。服务端接口通过 OpenAPI 生成类型所有请求都封装在 src/services 下禁止在组件内直接调用 fetch/axios。 # 代码结构约定 - src/pages页面级组件只负责路由与页面状态编排。 - src/components可复用 UI 组件禁止写业务逻辑。 - src/features业务模块包含模块内的组件、hooks、store。 - src/services所有 HTTP 请求的封装层返回 Promiseany。 - src/types全局类型定义API 类型请从这里 import。 # 代码风格 - 组件使用函数式组件写法hooks 优先。 - 样式使用 TailwindCSS禁止写 CSS Modules。 - 不注释废话不写日志代码。 - 所有日期时间统一用 dayjs不放 Date。 # 常用命令 - pnpm dev启动开发服务器 - pnpm build构建 - pnpm test跑单测 - pnpm lint代码检查必须通过不要禁用 eslint 规则 # 特别注意 - 依赖版本锁定不要升级时顺手改 package.json 里无关的包。 - Zustand store 必须遵循 create() devtools 模式。 - 所有自定义 hooks 放 src/hooks函数名以 use 开头。看到了吗这东西不复杂五分钟就能写完但它的作用非常大。Cursor 读了它之后会在生成代码前先“过一遍规矩”。你不需要在每次对话里重复“不要用 CSS Modules”“不要在组件里 fetch”它自己就知道。2.2 一份够用的项目档案模板如果你觉得上面的例子太前端、太具体没关系我拆一个通用的骨架给你套到任何项目里都能用技术栈与版本语言、框架、核心库以及你必须保持兼容的最低版本。目录结构与职责边界什么代码放哪里什么层能做什么事什么层严禁做什么事。工程化约定包管理器、构建命令、测试框架、代码检查规则。常见业务概念这个项目里独有的业务名词、状态枚举、权限定义——AI 不看你产品测试文档但只要你写进 AGENTS.md 里它就会遵守。反例清单明确写清楚“不要做什么”比“要做什么”更能防止 AI 在不经意间破坏你的项目。2.3 我把 .cursorrules / .cursor/rules 用到什么程度你如果搜过 Cursor 的玩法可能还听过.cursorrules和.cursor/rules这两个东西。我的建议是不要过度依赖但也不要完全忽略合理分层是性价比最高的用法。AGENTS.md负责“项目级硬约束”它随仓库走团队成员共享人人都能维护。.cursor/rules适合放“多人协作但不用跟库走”的团队级规范比如“代码里不要出现中文注释”“包名必须全小写连字符”。而那种“具体的、一次性的任务描述”完全没有必要写进规则文件里直接放在提问时一次性说清楚就行。我的经验是规则文件不是越厚越好。厚度超过一定阈值Cursor 在读取上下文时会产生“注意力疲劳”该遵守的反而可能被忽略。最好的状态是——能用几句话讲清楚的事绝不写成长篇大论。3. 把“想法”翻译成 AI 能执行的“规格”提示词工程化写到这里你应该已经理解Cursor 不会读心术它的上限全看你输入的品质。那接下来这一步就是关键了怎么把脑海里模糊的“我想要它做一个 xxx”翻译成 AI 能精确执行的规格。3.1 描述意图但更要描述验收标准我做了一个小小的对比实验这是我自己早期和后期写提示词的差别你应该能一眼看出问题阶段提示词写法结果早期“帮我把登录页面优化一下”AI 回了一堆“建议使用 Form 组件、增加 Loading 状态、使用 useCallback 优化”之类的车轱辘话后期“优化src/pages/Login.tsx的表单提交逻辑要求表单未填完整时点击登录按钮给出对应字段的报错提示提交过程中按钮禁用并显示 Loading请求失败时保留用户已填写的内容用 Form 的 onFinish 处理提交”AI 直接生成 diff改动小、可读性高、改动点全部符合预期差别在哪后期那个写法里包含了四个关键信息操作对象具体文件、行为逻辑什么时候做什么、异常分支失败时怎么办、约束条件用什么 API 实现。你不给这四样东西AI 就会默认按“最通用”的方式去做——而“最通用”往往意味着“不符合你的项目”。3.2 给 AI 设定“思考约束”除了描述功能我还强烈建议你在提示词里加上“禁止项”。AI 和初级程序员一样有一种习惯性的“顺手优化”冲动你让它把接口从 POST 改成 PUT它可能顺手把你的函数命名也改了、把代码格式也换了、把注释也删了。这些“顺手”的改动往往是code review 里最让人血压升高的部分。所以我现在写提示词几乎必定携带下面这类句式请只修改与问题相关的部分不要重构无关代码。 不要更改现有函数签名和导出方式。 不要修改测试文件。 不要引入新的第三方依赖。这五句话写上去很啰嗦但效果立竿见影。它把 AI 的行为从“自由发挥”变成了“任务执行”从根上杜绝了它给你制造一堆无关 diff 的坏习惯。3.3 让 AI 自己说方案Plan 模式的妙用最容易被忽略的还有 Cursor 的“先计划后执行”能力。以前我打开 Composer写一句“帮我重构这个文件”它就开始直接改代码经常改到一半你发现方向错了跟它说 “No no no我不是这个意思”它已经手快改了一堆东西。后来我的习惯是凡是改动面超过一个文件的活儿我一定先让 AI 给我出计划确认无误后再动手。比如我会问在开始改代码之前先用列表形式整理你的改动计划 1. 你打算修改哪些文件 2. 每个文件的改动点是什么 3. 涉及哪些函数/组件/接口的调用方 4. 有什么潜在风险 确认后我再让你开始执行。这段提示词的魔力在于它逼迫 AI 把注意力放在“理解问题”而不是“生成代码”上大大降低了它跑偏的概率。而且它给你的计划本身就是一份极佳的 review 材料——你可以在它动手前拦住一半的错误。4. 小步跑起来Composer / Tab 补全 / Reference 的正确打开方式很多初学者搞不清楚一个问题Tab 补全和 Composer对话窗口到底有什么区别什么时候该用哪个这个我直到用了三个月才真正想明白。4.1 Tab 补全和 Composer 的边界Tab 补全的本质是“预测你的下一个动作”它适合那些你已经明确知道怎么写、只是懒得打字的场景——写完函数名补全参数写完参数补全返回值写完一个模块让 AI 帮你补下一个类似的模块。这种场景下 AI 的准确率极高因为你给了它大量的“前缀”作为约束它几乎没有自由发挥的空间。Composer 则完全不同它的本质是“理解一个问题并生成解决方案”适合你要做一件事但还没想清楚具体代码长什么样的场景。但你用 Composer 的时候必须意识到它是在更大范围内做概率生成而概率生成就必然带有随机性和不可控性。我见过很多人的错误用法是在 Tab 补全场景里打开 Composer然后把代码复制进去再让 AI 改。拜托Tab 补全的反馈速度是毫秒级的Composer 生成的代码需要人肉 review 一遍才能合进去两者各有各的适用面用反了就是灾难。4.2 用 Reference 锁定上下文范围Composer 里有一个很容易被忽略的功能#引用Reference。它的价值在于你可以显式地把某个文件、某个符号或某个目录设为上下文告诉 AI “你只需要关注这些东西别的都不是重点”。这看起来不起眼但实际用起来效果惊人。举个例子你让 AI “帮我把这个函数改掉”如果不 Reference它可能会参考整个项目的所有打开文件你如果 Reference 了src/pages/order.tsx和src/services/order.ts两个文件它的注意力就会被精确锁定在这两个文件上生成的代码质量会高一个量级。我的习惯是任何时候在 Composer 里准备做改动时都要检查一遍右上角的上下文列表把无关的文件全部移除只留最相关的 2 到 3 个。这是个强迫症一样的习惯但它真的能规避掉 80% 的“AI 发疯”事件。4.3 交互式确认不要让它一口气改十个文件早期踩的一个大坑就是让 AI “一口气把所有页面都加上错误边界”它真的给你一口气改了十个文件然后其中两个因为 import 路径写错直接跑挂。那次之后我学乖了凡是一批改动必须拆成单文件级别去让 AI 逐个完成且每个文件完成后我必须亲自看一眼 diff 再让它继续。我和团队现在默认的方式是这样在 Composer 里让 AI 先只处理一个文件改完我按一次接受然后继续让它处理下一个文件再按一次接受。这个过程是慢了一点但它让每一次改动都成为“可控的一小步”而不是“失控的一大跳”。如果过程中某个文件 AI 改得不对我还能及时喊停不让错误扩散到下一波生成里。另外多说一句隐私和安全——我知道网上有“cursor 提示词泄露”之类的热搜词。我自己在团队里推了一套起码的底线任何情况下不要把数据库连接串、云厂商 AccessKey、真实用户手机号、内部密钥写进 Composer 的对话里。在敏感项目中尽量打开 Cursor 的隐私模式并且设置规则要求 AI 在生成代码时一律使用脱敏的占位数据。AI 辅助编码再好用也不能拿数据合规开玩笑。5. AI 改坏代码时的止损方法论有一句我在实战中反复验证过的话AI 的代码一定会有错只是时间问题。这不代表它不好用而是说你需要一套比手动编码更严密的流程来对冲它的随机性。过去半年里我自己就在队友面前遭遇过三次大型翻车现场依稀有印象的都值得拿出来复盘。5.1 入场前就做好“失败准备”如果你要在 Composer 里让 AI 做大改动先说清楚失败预案。这不是怂这是纪律。我自己的习惯是改动前先记录当前项目的可运行状态。比如我用 Git 打标签或者在本地 stash 一份保险分支再比如先把当前项目完整跑一遍测试保证改前是绿的可能不现实但至少我知道基线长什么样。然后在 Composer 里跟 AI 说在开始之前先检查 git status确认当前工作区是干净的。 如果生成代码后pnpm test 无法通过请自行回滚到改动前的版本。这句话不是设置奇奇怪怪的“防御性魔法”而是给 AI 一个行为默认值告诉它“你如果在执行中出错首选策略是回退而不是在错误的基础上继续修”。相信我AI 在错误基础上继续修能把一个 2 分钟能解决的问题变成一个 1 小时都拆不完的炸弹。5.2 经典翻车现场还原以及怎么救我印象最深的一次是让 AI 优化一个订单详情页的取数逻辑。原始代码里请求了三次接口我想让 AI 合并一下但它直接在src/services/order.ts里新写了一个接口函数然后改掉了所有页面里的调用方式顺便还改了接口返回的 TypeScript 类型定义。那一刻我的血压是飙升的——改动面完全失控而且它还顺手把两个其他页面正在用的类型定义给改了。那次怎么救的其实很简单我第一时间没有跟 AI 说“你错了重新来”而是把一个检查清单丢给它请逐步对比改动前后的差异把以下内容列出来 1. 你新增的函数是什么 2. 你修改了哪些文件的哪些函数 / 类型 3. 原页面中原来引用旧接口的位置现在是否都用了新接口 4. 有没有遗漏的调用方 5. 请给出这些差异的修改 diff。这段提示词的作用是把 AI 从“执行者”拉回“分析者”的位置。很多时候AI 犯错不是因为能力不够而是因为它在“执行模式”下根本无暇顾及全局影响你让它停下来以“审查者”视角重新审视自己的改动它能更大概率地找到自己埋的坑。那次最终是合并了但多花了 15 分钟来做“AI 自我 review”比我自己全盘手动反攻快很多。5.3 让 AI“解释差异”代替“直接回滚”团队的另一个高频场景是AI 改完后你不确定新代码是不是对的只想确认“它变了什么”。这时候千万不要直接让它撤销重来——它可能会把你原来想要的改动也一起撤掉。更好用的组合拳是先让它逐条列出差异你定位到可疑点后再让它单独修正。我用一个例子来结束这个小节。一次我让 AI 修改一个关于文件上传进度的组件结果它在依赖数组里顺手加了一个uploadProgress变量导致每次进度更新都会重新初始化整个上传流程。当我看到那个文件后我没有回滚而是指着那个地方问它这个 effect 依赖数组里为什么会有 uploadProgress它会导致组件在进度更新时重新执行 effect你可能需要去掉这个依赖。请你对这个问题做一个解释并给出最小修复方案。这个“解释差异”的流程比“直接回滚”更可控因为 AI 的生成逻辑是基于你追问的方向去收敛的它不会把之前的正确逻辑一并推翻。6. 把这套实践固定在团队里可复用的工作流模板最后一部分我想聊聊怎么把上面这些经验固化成一套团队可复用的工作流。毕竟一个人掌握技巧不算本事能带着团队整体提速才叫真有效。6.1 我长期在用的最小化模板我每接手一个新项目第一周肯定会先写好AGENTS.md和一份核心规则文件。然后我会把下面这个“提问模板”同步给所有协作的队友让大家照着套。任务背景我现在需要你帮助完成 [一句话描述问题]。 文件位置主要涉及 [文件路径1]、[文件路径2]相关调用方在 [文件路径3]。 当前行为[描述现状比如页面点击按钮后没有任何反应]。 期望行为[描述预期比如点击后应弹出确认框确认后调用创建接口创建成功后刷新列表]。 约束条件[有哪些不能改的比如不要动公共组件、不要改依赖、兼容旧接口]。 验收标准[怎么算做完比如pnpm test 通过启动后手动点击验证]。没有高深词汇没有玄学措辞但这个模板把前面所有技巧浓缩进去了。我一个后端写得不多的队友靠这个模板也能让 Cursor 生成出可直接 merge 的前端改动这是一件让我非常有成就感的事。6.2 让队友“复制粘贴”不出错的方法但光有模板还不够团队协作中最容易出问题的其实是“上下文漂移”。我见过队友在 A 分支上用 Cursor 改了代码切到 B 分支后没清理对话历史直接让 AI“继续”结果把 A 分支的代码结构特征混到 B 分支的生成里。这种事用嘴强调没用必须用纪律约束。现在我们团队有个硬性约定每次切换分支、每次开始新任务前必须新建一个 Composer 对话并且建议把之前的对话归档或关闭。我是认真的一定要让队友把“对话生命周期”当成“Git 分支生命周期”来管理——它俩在语义上是等价的。否则对话里的旧历史就会像地上的胶水一样不知道什么时候就把你粘回旧方向。还有一点是关于 code review 的。我强烈建议凡是 Cursor 自动生成的代码过 review 的时候要提高警惕但也别一杆子打死。我一般要求队友提交 PR 时标明哪些区块是 AI 生成的这样 review 时可以直接跳过那些逻辑简单但代码冗长的部分比如重复的表单校验集中火力看 AI 最容易翻车的部分——数据清理、类型边界、状态清理、默认值处理。6.3 经验沉淀每周让 AI 帮你写一份 code review 总结这里再分享一个进阶玩法。我们现在每周五会让 AI 基于本周所有 merge 的 PR 生成一份简短的 code review 总结请它分析哪些改动模式本周出现频率较高哪些函数边界最容易写错哪些模块是改动热点AI 生成的总结也许不算完全准确但它能帮你快速定位出团队的常见问题区域下一周就可以在写提示词的时候提前给 AI 打“预防针”。比如如果这周有三个 PR 都因为“接口类型变化但调用方没同步更新”而出 bug那下周一所有人的提示词模板里就会多一句“修改接口类型定义时请同时检查所有调用方并更新其类型引用”。这是把 AI 从“执行工具”变成“团队管理者”的用法——它未必聪明到能自己发现问题但它足够快能帮你把模式识别出来。我自己的体会是用 Cursor 辅助编码的核心不在于学习更多快捷键也不在于研究哪个模型更强而在于把它当成一个“能力很强但刚入职的工程师”来管理。你给它清晰的项目手册、明确的验收标准、可控的任务边界和及时的反馈日志它就能成为一个每天帮你写几千行代码且不喊累的队友你什么都不给纯靠它自由发挥那就只能时常体验惊喜与惊吓交替出现的刺激感。如果你目前正处在“装了 Cursor但用起来总觉得鸡肋”的阶段先别急着卸载也别急着换工具试着按上面这套实践从写一份AGENTS.md开始。哪怕别的都不做只是这一件小事你和 AI 协作的顺畅度应该都能有肉眼可见的提升。这套实践之所以叫“可复用”是因为它本质上一套与具体模型、具体工具无关的协作方法——把方法固化下来以后不管工具怎么变、模型怎么升级你都能比大多数人更快地用上手。