这是专栏「AI编程实战:Cursor与Claude Code」的第 1 篇。读完你会得到一套可以照抄进真实项目的 AI 编程工作流:Cursor 与 Claude Code 各自的定位与协作分工、项目级提示词(rules)的写法、一个真实小项目从 0 到跑通的多文件改造、以及 8 个我在生产中真实踩过的报错的「原文 + 根因 + 解法」。不是"怎么装个插件试试看",而是"明天上班就能用上、还能少踩坑"。
一、先把定位说清楚:Cursor 和 Claude Code 不是二选一
很多人把 Cursor 和 Claude Code 当成同类产品对比,然后纠结"到底用哪个"。实际工程里,它们解决的是两个不同维度的问题,配合使用效率最高。
- Cursor :一个 AI 原生的 IDE(基于 VS Code 内核),强项是编辑器内的高频小循环 ------你光标在哪、它就懂哪,Tab 补全、
Cmd/Ctrl+K行内改写、Cmd/Ctrl+L侧栏对话,适合"我正在写这个函数,帮我顺手改一下"。 - Claude Code :Anthropic 出的命令行 Agent ,强项是跨文件的大循环------给它一个目标("把这个模块的回调改成 async/await 并补测试"),它会自己读多个文件、规划、改动、跑命令、再自我验证,适合"我要做一件涉及七八个文件的事"。
一句话记忆:Cursor 管"我手里这一段",Claude Code 管"这一整件事"。真实工作流里我通常是:用 Claude Code 完成跨文件的结构性改造,再回到 Cursor 里做收尾的精修和联调。
二、环境配置:30 分钟搭好两件套
2.1 Cursor 安装与关键设置
官网下载安装后,有三个设置直接决定体验,务必先调:
- 模型选择 :在
Settings → Models里,复杂任务优先用最新的 Claude 系列模型(推理强、长上下文稳),日常补全可以用更快的轻量模型省额度。 - Codebase 索引 :
Settings → Features → Codebase Indexing打开,让 Cursor 对整个仓库建立语义索引,@Codebase提问时才能跨文件检索,而不是只看当前文件。 - 隐私模式 :团队代码敏感的话,开
Privacy Mode,代码不被留存训练。
2.2 Claude Code 安装与登录
Claude Code 是一个 npm 包,需要 Node 18+:
bash
# 安装(全局)
npm install -g @anthropic-ai/claude-code
# 在你的项目根目录启动
cd /path/to/your/project
claude
首次启动会引导你登录(浏览器授权或 API Key 两种方式)。登录成功后,你就在项目根目录获得了一个能读写文件、能跑命令的终端 Agent。
2.3 一个常被忽略的关键:让两者共享同一份"项目规则"
Cursor 读 .cursor/rules/(或老版本的 .cursorrules),Claude Code 读项目根目录的 CLAUDE.md。两者内容应当保持一致,否则同一个项目里两个 AI 的"价值观"会打架。我的做法是写一份规则,两边都指过去:
markdown
<!-- CLAUDE.md(Claude Code 读) -->
# 项目约定
- 语言:TypeScript,严格模式;禁止 any。
- 风格:函数式优先,副作用集中在 service 层。
- 测试:每个 service 函数必须有 vitest 单测,覆盖率门槛 80%。
- 提交:commit message 用英文,遵循 Conventional Commits。
- 重要:不要新增依赖,除非我明确同意。
.cursor/rules/project.mdc 里写同样的约束即可。把"不要做什么"写清楚,比写"要做什么"更能止损------AI 最容易出问题的地方就是自作主张引入依赖、改无关文件、降测试覆盖。
三、提示词工程:让 AI 少返工的 4 条铁律
写给 AI 的提示词,本质是"把一个资深同事 onboard 到任务里"。下面 4 条是我返工率从高到低排出来的:
- 先给上下文,再给指令 。错误示范:"帮我写个登录接口"。正确示范:"我们用 Express + Prisma,
src/services/auth.ts已有hashPassword,请在src/routes/auth.ts新增POST /login,复用hashPassword,校验失败返回 401,成功返回 JWT。" - 把验收标准写进提示词 。"完成后请运行
npm test,确保新增的 3 个用例通过再停。"------Agent 会真的去跑,而不是写完就说"应该可以了"。 - 限定改动范围 。"只改
auth.ts和它的测试,不要动其他文件。"------这一句能挡掉大半"AI 顺手重构了我没让它动的代码"的事故。 - 让它先说计划再动手。复杂任务先问:"先别写代码,列一个改动计划给我看。"------计划阶段纠偏的成本,远低于代码写完再推翻。
四、实战:把一个回调地狱的模块改成 async/await + 补测试
下面是一个真实的小改造。原始代码(src/order.js)是典型的回调嵌套:
javascript
// 改造前:回调地狱
function placeOrder(userId, items, cb) {
getUser(userId, (err, user) => {
if (err) return cb(err);
checkStock(items, (err, ok) => {
if (err) return cb(err);
if (!ok) return cb(new Error('out of stock'));
createOrder(user, items, (err, order) => {
if (err) return cb(err);
cb(null, order);
});
});
});
}
在 Claude Code 里,我给的提示词是:
把
src/order.js的placeOrder从回调风格改成 async/await,三个依赖函数getUser/checkStock/createOrder也一并改成返回 Promise 的版本。改完后为placeOrder写 vitest 单测,覆盖正常下单、库存不足、用户不存在三种情况。只改src/order.js和新增src/order.test.js。
Claude Code 先返回了改动计划,确认后产出:
javascript
// 改造后:async/await
async function getUser(userId) { /* ...returns Promise<User> */ }
async function checkStock(items) { /* ...returns Promise<boolean> */ }
async function createOrder(user, items) { /* ...returns Promise<Order> */ }
export async function placeOrder(userId, items) {
const user = await getUser(userId);
const ok = await checkStock(items);
if (!ok) throw new Error('out of stock');
return createOrder(user, items);
}
以及配套测试:
javascript
import { describe, it, expect, vi } from 'vitest';
import * as deps from './order.js';
describe('placeOrder', () => {
it('下单成功返回 order', async () => {
vi.spyOn(deps, 'getUser').mockResolvedValue({ id: 1 });
vi.spyOn(deps, 'checkStock').mockResolvedValue(true);
vi.spyOn(deps, 'createOrder').mockResolvedValue({ id: 99 });
await expect(deps.placeOrder(1, [{ sku: 'a' }])).resolves.toEqual({ id: 99 });
});
it('库存不足抛错', async () => {
vi.spyOn(deps, 'checkStock').mockResolvedValue(false);
await expect(deps.placeOrder(1, [])).rejects.toThrow('out of stock');
});
});
这一步的价值不在"写出 async 代码"------那谁都会。价值在于:它同时把三个依赖函数的签名改了、把调用处对齐了、还补齐了测试,全程一致。这是 Cursor 的行内改写做不到的"跨文件一致性改造",正是 Claude Code 的主场。
五、生产级工作流:把 AI 嵌进 Git 循环
单点用 AI 是"尝鲜",把 AI 嵌进日常的 Git 循环才是"生产力"。我固定的循环是:
- 开分支 :
git checkout -b feat/async-order。 - Claude Code 做主体改造:给目标 + 验收标准,让它改完并自测。
- Cursor 精修 :回到编辑器逐文件 review,行内
Cmd/Ctrl+K修细节。 - 让 AI 写 commit message :
claude里直接说"看一下暂存区的改动,写一条 Conventional Commits 规范的提交信息"。 - PR 自查:合并前让 Claude Code "扮演 reviewer,找出这次改动里可能的 bug 和边界问题"。
第 5 步是性价比最高的:AI 审 AI 写的代码,能在你提 PR 前抓出一批低级问题,把 review 同事的时间留给真正的架构判断。
六、高频报错全解(生产中真实踩过的 8 个坑)
这一节是付费内容里最值钱的部分------替你把我踩过的坑填了。
坑 1:Claude Code 说"找不到文件"但文件明明存在。
根因:你不是在项目根目录启动的,Agent 的工作目录错了。
解法:先 cd 到项目根再 claude;或启动后用 /cwd 确认工作目录。
坑 2:改动跑飞,AI 动了一堆你没让它动的文件。
根因:提示词没限定范围,且 CLAUDE.md 没有"最小改动"约束。
解法:提示词显式写"只改 X 和 Y";CLAUDE.md 加一条"Make the smallest change that satisfies the request; do not refactor unrelated code."
坑 3:Cursor 的 @Codebase 检索不到明明存在的代码。
根因:Codebase Indexing 没开,或刚加的文件还没索引完。
解法:开启索引并等待右下角索引进度跑完;新文件可手动触发 re-index。
坑 4:AI 生成的代码引用了不存在的 API(幻觉)。
根因:模型对小众库 / 新版本 API 不熟,凭印象编。
解法:把真实的 API 文档片段贴进上下文(Cursor 用 @Docs,Claude Code 直接粘贴),并要求"只用我贴的 API,不要凭记忆"。
坑 5:长对话后 AI 开始"失忆"、前后矛盾。
根因:上下文窗口被历史塞满,早期约定被挤出。
解法:阶段性 /clear(Claude Code)或新开会话,把关键约定固化进 CLAUDE.md 而不是靠对话记忆。
坑 6:npm install -g @anthropic-ai/claude-code 报权限错误(EACCES)。
根因:全局目录权限问题(常见于用系统自带 Node)。
解法:用 nvm 管理 Node,或配置 npm 全局前缀到用户目录,别用 sudo 强装(后患更多)。
坑 7:改完测试一直挂,AI 反复"修"但越修越乱。
根因:让 AI 在没有跑测试反馈的情况下盲改。
解法:明确要求"每次改完都运行 npm test 并把失败输出贴回来再决定下一步",让它在真实反馈里收敛。
坑 8:团队协作时 Cursor / Claude 行为不一致。
根因:.cursor/rules 和 CLAUDE.md 内容漂移。
解法:把规则收敛成一份真源,CI 里加一个校验脚本检查两者关键约束一致。
七、小结与下一篇
这一篇把"骨架"搭好了:Cursor 管小循环、Claude Code 管大循环、用一致的项目规则约束两者、嵌进 Git 循环、并备好了踩坑清单。下一篇我们进入真实项目深水区:用这套工作流从 0 搭一个带数据库和测试的后端服务,重点拆"AI 在架构取舍上靠不靠谱、哪些决策必须人来拍板"。
如果这篇帮你少走了弯路,点个收藏 方便随时回查,关注作者追更本专栏后续章节。专栏会持续沉淀可复现的 AI 编程实战与踩坑解法,评论区也欢迎贴出你遇到的报错,我会挑高频的补进"报错全解"。