ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

上下文工程实战:让Cursor真正读懂你的代码库

上下文工程实战:让Cursor真正读懂你的代码库 接手这个项目之前我和很多人的状态一样装了 Cursor用了两周最大的感受是它像个打字很快但脑子不太清楚的新人。让它补全样板代码没问题可一旦涉及业务逻辑重构、跨文件修改、理解项目的设计意图它就经常答非所问甚至一本正经地编造不存在的接口。后来我把这套实践方法试了几个月才想明白一个道理——Cursor 不是不聪明而是它默认没有读懂你的代码。想让 AI 真正辅助编码核心工作不是写提示词而是构建上下文。这篇文章就是把我在实际项目里总结出的一套可复用实践全部摊开讲。ChatGPT 这类对话模型很多人已经用熟了但把它用在真实代码库里是另一回事。我见过不少团队引入 Cursor 后效率反而下降原因几乎都一样模型不了解项目背景、不知道约束条件、不理解调用链于是产出大量看起来对但一运行就崩的代码。如果你也踩过这类坑或者正打算好好用 AI 辅助编码这篇文章会给出一个能直接照做的完整方案。1. Cursor 读不懂代码的真正原因它天然是个无状态新人1.1 上下文窗口有限但更关键的是无状态先说本质。Cursor 这类 AI 编程助手本质上是在你当前打开的文件和对话历史之上做概率生成。它并没有真正读过你的整个 Git 仓库也不是每次回答前都会把所有文件扫描一遍。默认情况下它能看到的上下文非常有限当前正在编辑的文件内容部分 IDE 插件会带上附近代码你在对话框里手动引用或打开过的文件整个会话中的历史消息项目根目录下的配置文件比如.cursorrules这就好比团队来了个新同事你直接丢给它一个修改用户鉴权逻辑的需求但它既没看过用户表结构也没看过现有鉴权代码更不知道你们技术栈里封装了哪些公共方法。它唯一能做的就是凭训练数据里的通用经验猜一套答案给你。这也是 Cursor 最常翻车的地方它不是在读代码而是在猜代码。1.2 三种最常见的翻车模式你肯定遇到过我在项目里总结过 Cursor 翻车的高频场景基本逃不出这三种翻车类型具体表现根因接口幻觉生成代码里调用了不存在的函数或字段模型基于训练数据里常见命名猜测上下文错位改 A 模块却引用了 B 模块的旧接口不知道项目实际目录结构风格漂移生成的代码风格和项目现有风格完全不一致不了解团队编码规范和约定举个真实例子。有一次我让 Cursor 在订单模块里加一个批量取消功能它直接在代码里调用了OrderService.cancel()方法。问题是我们项目里根本没有这个方法真正的名字是OrderDomainService.cancelByStatus()。更神奇的是它还贴心地在 Service 层写了一个Transactional但我们项目的事务控制其实是在应用服务层统一处理的——结果差点把事务边界切破。你说 Cursor 蠢吗不。它只是不知道这些约束。谁有这个信息你。所以核心问题变成了怎么把你脑子里那些隐性知识高效地塞给 AI。1.3 一个类比让你彻底想通我把 Cursor 理解成高智商但零记忆的外包工程师。外包工程师刚进项目时会花一两天读文档、问人要背景资料然后才敢动手。但 Cursor 没有主动提问的能力至少当前版本还没有它只会基于已有信息直接输出。所以你的工作不是告诉它答案而是帮它把入职培训补齐。这套培训材料就是上下文工程。理解了这一点后面所有方法论都顺理成章了。2. 上下文工程让 AI 在动手前先进入状态2.1 项目级画像写好你的 .cursorrules.cursorrules是 Cursor 最重要的文件没有之一。放在项目根目录它会在每次对话时自动加载相当于给 AI 立了一套入职手册。我见过很多人忽略这个文件或者只在里面写了一句你是资深工程师。这远远不够。真正有用的.cursorrules应该包含以下维度项目技术栈与版本明确语言、框架、关键库防止 AI 用错 API目录结构与模块职责告诉 AI 什么代码放在哪个层编码规范命名风格、错误处理方式、事务边界禁止事项哪些库不能用、哪些模式不要碰、哪些文件不该动一个我实际用的模板给你参考# 项目背景 这是一个基于 Spring Boot 3.2 MyBatis-Plus 的订单中台服务 核心业务域订单、支付、库存、售后。 # 目录约定 - controller/只做参数接收和响应封装禁止写业务逻辑 - service/应用服务负责事务边界和用例编排 - domain/领域服务与领域模型放置核心业务规则 - repository/数据访问层所有数据库操作必须走这里 # 编码规范 - 方法命名动词开头如 queryOrder、createOrder - 错误处理禁止直接捕获异常吞掉必须抛出统一 BizException - 事务控制只有 service 层可以使用 Transactional - 时间字段统一使用 LocalDateTime禁止使用 Date # 禁止事项 - 禁止在 controller 层调用 repository - 禁止修改数据库表结构相关的 DDL 文件 - 禁止引入新的第三方依赖除非我明确要求这个文件不是写一次就完事。项目结构调整、技术栈升级、规范变化时记得同步更新。它就是你给 AI 做的入职培训PPT。2.2 文件级上下文别让 AI 盲人摸象.cursorrules解决的是项目整体认知问题但具体到一次任务AI 还需要知道和任务相关的文件内容。我常用的手段有三个第一手动 关键文件。在 Cursor 对话框里用符号引用相关文件这是最直接的方式。改接口时把 Controller、Service、DTO 三个文件都 进去让 AI 看到完整的调用链。第二同时打开相关文件。Cursor 会优先参考当前打开的标签页内容。重构一个函数时把它的调用方和被调用方都打开能显著降低 AI猜错接口的概率。第三在关键目录放 README。这是个容易被忽略的技巧。在一个模块目录下放一个几百字的 README说明这个模块的职责、内部结构和常见改动方式。AI 阅读代码时如果发现 README理解准确率会高很多。后来我在项目里推广了这个做法Cursor 在这个模块里的表现明显更靠谱。2.3 会话级上下文一个任务一个会话很多人用 Cursor 喜欢在同一个会话里连续问十几个问题这是一个大坑。原因有两个一是上下文污染。你在会话前段让它写过文件解析逻辑后段问数据库查询优化时它可能还在莫名其妙地给你输出文件解析相关代码。二是长会话后指令衰减。研究发现模型对对话早期指令的遵循程度会随着上下文变长而下降。你在会话开头说的编码规范聊了 50 轮之后它基本忘光了。我的习惯是严格按任务切分会话修 bug 开一个写新功能开一个代码审查再单独开一个。每个会话里只放和当前任务相关的文件引用和规则说明。这样既省 token又保持每次对话都是从干净状态开始准确率高得多。3. 从会问到问对让 AI 真正理解你想要什么3.1 动手之前先让 AI 复述需求这是我在整个实践中回报率最高的一招。做法很简单输入任务后先不让 AI 写代码而是让它用自己的话复述一遍需求。比如我想让它优化一个查询接口我会这样说不要急着写代码。先告诉我你理解的这个任务是什么 你要修改哪些文件改动涉及哪些调用链你打算怎么做这一步的价值在于AI 一旦用语言描述自己的理解就能暴露出它没看明白的地方。如果它复述的需求和我实际想要的有偏差此时纠正的成本极低——改一句话就行。如果它直接写代码等写完了才发现理解错了那就是一堆返工。我做过一个粗略统计强制 AI 先复述需求之后一次通过的代码比例从大概三成提高到了七成。这个动作成本很低收益却非常稳定。3.2 用约束优先代替目标优先大多数人的提示词习惯是告诉 AI 要什么然后等结果。但 AI 在不知道边界的情况下会默认选择最常见的实现方式而这种方式往往不符合你项目的实际情况。我自己的提示词结构是先给约束再给目标【约束条件】 - 不要修改现有接口签名 - 不要改变已有的返回结构 - 保持现有命名风格 - 兼容老的支付渠道回调 【目标】 在现有订单查询逻辑中增加一个按商户维度过滤的可选参数。这样写的好处是AI 是在一个明确的边界内做选择而不是天马行空地自由发挥。它猜错的可能性被大幅压缩。3.3 把错误信息原文贴给它别自己转述遇到报错时很多人的习惯是自己看一眼报错然后用自己的话描述给 AI它说有个什么空指针。这个习惯非常不好。第一你的转述会丢失关键信息。堆栈里的类名、行号、异常类型都是定位问题的核心线索。第二你的描述本身可能带误导。AI 基于错误信息产生的猜测会被你的转述带偏。正确做法是把完整堆栈直接贴给 AI注意先确认里面没有密钥和敏感信息然后附上出错的代码片段让它分析。附带一句先告诉我导致这个异常的可能原因再给出修复方案。这能让 AI 先做推理再做修改比直接让它修复一下可靠得多。3.4 结构化提问模板把隐性知识显性化综合前面的经验我最终沉淀出一套通用的任务提问模板每条任务都用这个结构任务背景要处理哪个模块、和什么业务场景相关 具体目标预期达到什么效果 约束条件哪些不能做、必须遵守哪些规范 参考文件和本次改动相关的文件路径 验收标准怎么算改完了配合上.cursorrules里的项目级约束和文件引用这样一个结构化的输入AI 基本不会答非所问。它也保证了对话里每一次提问都携带足够上下文而不是让 AI 靠猜。4. 一套可复用的完整实践流程从需求到上线的标准动作4.1 第一步让 AI 先建地图再问路任何新任务开始前我都先让 AI 做一件事——读项目结构输出它理解的地图。先浏览项目根目录告诉我 1. 这是一个什么技术栈的项目 2. 主要模块有哪些各自职责是什么 3. 和当前任务相关的文件路径有哪些这一步配合.cursorrules能在开始前确认 AI 对项目的理解基线。有时候 AI 列出的目录结构和实际有出入此时纠正还来得及。等它真的开始改代码再发现目录搞错了返工成本就大了。4.2 第二步生成改动计划而不是直接生成代码在正式写代码前我会要求 AI 先给出改动计划基于以上需求列出你要做的改动清单 - 每个文件为什么要改 - 大概怎么改 - 会影响哪些调用方 - 有没有风险点这一步相当于让 AI 在动手前先过一遍设计方案评审。它的价值在于AI 的计划里如果有没有考虑到的调用方和影响面我可以在它动手前就指出来而不是等它写完了再来填坑。4.3 第三步分步生成及时验证计划确认没问题后才进入代码生成环节。但这里我坚持一个原则小步走分步生成不要让它一口气吐出几百行。比如要实现一个带缓存、带降级、带异步日志的完整链路我不会让 Cursor 一次性全写完。我会拆成几步先写核心查询逻辑再加缓存处理再加降级策略最后补日志每生成一步我都让 AI 自己解释一遍关键部分的思路我确认理解了再进入下一步。不是说必须每行都懂但核心业务逻辑和边界条件必须看懂否则就是在给项目埋雷。4.4 第四步生成不等于完成Review 是底线这是我最想强调的一点。Cursor 生成的代码本质上是初稿不是成品。有个读者问我AI 生成的代码可以直接上生产吗我的回答是如果你完全不 review那它不是 AI 的问题是你的流程问题。我的 review 清单是这样的有没有调用不存在的 API这是最高频问题有没有破坏现有函数签名和数据结构异常处理是否符合项目规范吞异常是最常见的有没有重复造轮子项目里已有的工具类它是不是又重新写了一遍边界条件有没有覆盖空值、超长、并发有没有引入安全风险SQL 拼接、敏感信息硬编码用这个清单过一遍AI 生成代码里的大部分坑都能拦在提交前。4.5 第五步把编译报错和测试结果反馈回去形成闭环评审完之后进入常规的编译、测试阶段。这个过程里报错反馈是 AI 修复代码最有效的驱动。我的固定操作是这段代码编译报错以下是完整错误信息 【粘贴完整报错堆栈】 请分析原因给出修复方案并说明你的修复思路。注意一个细节不要让 AI 直接改先让它说明原因。这能避免它瞎试——有时候 AI 会为了消除报错而用错误的方式绕过问题比如加个SuppressWarnings把警告压下去。让它先解释原因至少能保证它知道自己在改什么。4.6 实际案例一个真实的小重构说个我最近用这套流程的真实案例。需求是把订单列表查询接口从只支持单商户改成支持多商户同时不能影响原有调用方。描述不算复杂但如果直接丢给 AI 写它大概率会改接口签名——而调用方有七八个签名一改全都得跟着炸。我的操作是打开 Controller、Service、Mapper 文件和调用方的代码全部 进上下文在提示词里明确约束不修改对外接口签名通过新增参数对象的方式兼容让 AI 先复述需求确认它会保留旧方法重载让 AI 列出改动计划确认影响范围覆盖了全部调用方分步生成新方法再让 AI 补全原有逻辑跑单测和编译把报错反馈回去迭代整个过程花了不到二十分钟。改完代码审查下来只手动调整了两处细节一处是空集合处理一处是 SQL 里IN语句的超长风险。如果直接从第一个答案开始改保守估计要返工两三轮。5. 必须守住的红线AI 编码的边界与踩坑记录5.1 幻觉是常态不是 Bug有一件事你必须接受大模型生成看起来合理但其实不存在的代码是它的天然属性不是偶发缺陷。我踩过的例子包括它写了一个.ApplyAsync()方法但项目用的框架版本根本没有这个方法它引用了官方文档早已废弃的配置项它给 Python 代码加了一个 Java 风格的类型注释。你Review 的时候如果带着AI 应该不会错的心态这些坑就会悄悄溜进代码库。所以我的建议是AI 生成的每段代码默认都有幻觉的可能。这不代表不能用而是要用的时候多留个心眼。凡是它引用了某个工具类某个依赖而你没有在上下文里明确提到过就一定要去实际文件里查证。5.2 无限修 bug 的恶性循环要及时跳出AI 编程有个很折磨人的场景一个 bug 让它修它改完引入新 bug把新报错反馈给它它又改出一个新问题。如此循环几轮代码越来越难看但错误依旧。我经历过一次最离谱的让 Cursor 修一个并发问题连续五轮它加了三次锁、改了两处缓存逻辑最后并发问题没解决还把正常的查询功能弄坏了。后来我给自己定了一条规则同一问题让它修三轮还没通过立刻停手。停下来之后回到最近的 Git 提交重置代码重新分析根因再决定是换个思路问还是手动修。这条规则帮我省下了大量无效沟通。5.3 长对话里的指令衰减比你想的更严重前面提到过会话切分这里我再补充一个细节哪怕是单任务会话随着代码来回修改AI 回归你早期要求的情况也会变多。比如任务开头你说不要用Thread.sleep做限流等对话进行了几十轮它可能又在某个文件里写出Thread.sleep。这不是它记性差而是上下文过长后早期指令在注意力机制中的权重会自然下降。我的对策是把核心约束放在每个新提示词的末尾。之前你在一开始说过的要求后续每次提问都再强调一遍记得前面说的不要用Thread.sleep。看着啰嗦但确实管用。5.4 隐私与安全永远别把敏感信息贴在对话框里这是一个容易被忽略但非常严肃的问题。你发给 Cursor 的代码会经过第三方 API 处理这意味着把生产环境的数据库连接串、密钥、Token 贴在对话框里等于把钥匙交给陌生人涉及客户数据、未公开商业逻辑的代码不建议整段贴出企业内部如果有保密要求在使用前要先了解合规边界我的做法是涉及密钥的地方用环境变量和占位符替代涉及敏感数据结构的用假数据脱敏拿不准的不贴。这个习惯无论用哪个 AI 工具都应该养成。5.5 Git 是 AI 编码的保险绳最后也是最重要的一条任何 AI 生成的改动提交前必须 diff而且最好每个小步骤都留一个提交点。git diff # 查看当前改动 git add -A git commit -m refactor: AI辅助调整订单查询逻辑我在用 Cursor 的时候几乎把 CtrlZ 用出了肌肉记忆。AI 改崩了就回滚改对了就提交。没有 Git 兜底AI 编码就是裸奔。6. 实际用下来这套实践改变了我的工作方式最后分享一点个人使用习惯的转变也许比前面的技巧更值得参考。以前我打开 Cursor 的第一反应是让它赶紧写代码现在我的第一反应变成了先把项目背景喂给它。实际做下来我在上下文构建上花的时间和在代码生成上花的时间比例大概在 7:3。起初觉得这样很浪费时间但坚持一个月后发现反而是这个慢功夫让 AI 产出的代码质量有了质的提升。另一个变化是我开始让 AI 帮我做代码审查。写完一版代码后我会让 Cursor 站在资深 Reviewer的角度找问题——不是让它夸而是让它专门挑刺。它确实能发现一些我忽略的边界条件和代码风格问题虽然偶尔会误报但当成第二双眼睛用性价比很高。还有一个很有意思的转变因为我习惯了把需求写清楚、把约束列明确、把验收标准说具体我发现自己对需求的理解也变得更清晰了。以前接到需求就急着动手现在会先在脑子里过一遍这个任务要动哪些文件、有哪些边界、怎么验证结果。让 AI 读懂你的代码本质上也是逼你自己先读懂自己的代码。这套方法别人能不能复用我不敢打包票但对于想认真用 AI 辅助编码、又不想被它带进沟里的开发者至少值得一试。
返回列表