Adithyan 关于我博客项目照片

用一个 Cursor Rule 编写 Cursor Rules

2025 年 4 月 10 日

我大部分的编码时间都在 Cursor 中度过。它是一款出色的 LLM 辅助编码工具。 但是使用 LLM 编码有一个特殊的怪癖:它们拥有强大的上下文记忆,但缺乏情景记忆。 简单来说,它们能记住单个对话中的信息,但一旦开始新的聊天会话,就会忘记一切。无法从之前的聊天中学习你喜欢的风格,也无法积累机构的怪癖和知识。 可以把它想象成和一个患有失忆症的出色助手一起工作。每天,你都要重复相同的指令:

如果你经常使用 Cursor,那么这听起来应该很熟悉。你总是不断地将 AI 引导回你项目的标准和个人偏好。如果你已经点头表示同意,并且(从标题中)明白了我想要表达的意思,那么你可能只是想要我使用的 meta cursor rule 模板。如果是这样,你可以直接跳转到 即插即用的 Meta-Cursor Rule。 如果你仍然不确定我在说什么,我将更详细地解释为什么这是必要的,我们如何使用 cursor rules 解决这个问题,以及如何使用 meta-rule 方法高效地创建 cursor rules。 cursor rules 的可视化表示,展示了它们如何在不同的聊天会话中为 AI 提供一致的指令

为什么、如何,然后是什么

我在这篇博客中撰写文章的方法是帮助其他人理解_为什么_我们需要做某事,以及_如何_着手创建解决方案。 在理解了_为什么_和_如何_之后,是什么(具体的实现或解决方案)就变得更加明显了。尤其是_为什么_! 我个人认为,你会想出一个比我提供的更适合你的项目和个人偏好的解决方案(是什么)。 所以让我们从_为什么_开始。

为什么你需要 AI 系统

想象一下,你正在管理几个项目,每个项目都分配了一个出色的开发人员。 问题是:每天早上,你的所有开发人员都会完全失忆。他们忘记了你的编码约定、项目架构、昨天的讨论,以及他们的工作如何与其他项目相关联。 每天,你都要重复同样的解释:

你会怎么做来阻止这种无休止的重复循环? 你会构建系统!

这些确保了你失忆的开发人员能够快速恢复上下文,并保持项目之间的一致性,让你能够专注于解决新问题,而不是重复旧的解释。 现在,将此应用于使用 AI 进行编码。 我们与智能 LLM 合作,它们功能强大,但在每次新的聊天中都会重新开始。它们没有记忆你的偏好,你如何构建项目,你喜欢如何完成工作,或者你积累的机构知识。 因此,你最终会重复自己。你如何解决这个问题? 完全相同的方式:你构建系统! 你需要一种方法来立即让你使用的每个 LLM 都达到最新状态。 ⚠️ 注意事项: 对于你不会重复使用的快速、一次性脚本,这可能并不重要,我实际上不建议你为它们创建规则。 但是,对于随着时间推移构建的严肃应用程序,经过数周和数月的逐步增长,这绝对重要。我可以根据个人经验告诉你这一点。你会浪费宝贵的时间来重新解释。 如果没有一个系统向 AI 提供这些信息,你将继续在重复的解释上浪费时间。幸运的是,Cursor 提供了内置的方法来创建这样的系统。让我们看看一个具体的解决方案。

我们该怎么做?Cursor Rules

Cursor Rules 是 AI 在你的项目中使用的永久指令文档。 对于每个 git 仓库,你都可以创建规则文件(存储在 .cursor/rules/ 中),告诉 LLM 如何使用你的特定代码库。不同的仓库可以有不同的规则,每个仓库通常有多个规则来解决项目的各个方面。 这些规则解决了 AI 的记忆空白。它们充当指令文档,教 AI 你的项目模式和偏好。当 Cursor 看到与规则模式 (glob) 匹配的文件时,它会自动加载该知识。这在你每次与 AI 聊天时都会创建一致性。 我在这里提供了我自己的总结,但你可以阅读官方文档了解更多详情。阅读时间不超过五分钟,我强烈推荐阅读。

创建规则,消除摩擦

这个概念听起来很简单:阅读文档并编写一些 .mdc 文件。 但说实话。许多开发人员理解这些好处,但犹豫不决,因为创建规则感觉像是额外的工作。它增加了摩擦。 这是我注意到的一些事情,无论是我自己还是向朋友解释时:我们都理解这个概念,我们都看到了长期的好处,但我们很少实施它。即使我知道 cursor rule 从长远来看会节省我的时间,但我通常也不会创建一个,因为编写它感觉像是一个障碍。 那么你如何克服这种阻力? 你构建一个系统来构建系统本身。 我知道这听起来很元,但这正是我们所需要的:使用 AI 为自身编写规则。 如何?通过创建一个 meta-cursor rule。 这意味着创建一个_一个_规则,作为编写_所有其他_规则的模板。它定义了你的所有规则应该遵循的结构和内容。 一旦你有了这个 meta-rule,这个过程就变得很简单:

  1. 注意到你想要编纂的模式
  2. 打开 Cursor 聊天
  3. 将 AI 指向你的 meta-rule(例如,“使用 cursor-rule-creation.mdc 指南……”)
  4. 要求它根据你的对话编写一个新规则(例如,“根据此聊天为我们的组件结构编写一个规则”)

在实践中,我个人在两种常见情况下使用它:

这种方法大大减少了构建规则库所需的工作量。AI 遵循你的模板来生成结构良好的草稿,你可以快速保存和使用。

是什么:一个即插即用的 Meta-Cursor Rule

所以最后,这是等式的“是什么”部分——我实际使用的 meta-cursor rule,它贯穿我的所有仓库。这是一个即插即用的解决方案,你可以直接复制到你自己的项目中。 只需将其另存为 .cursor/rules/cursor-rule-creation.mdc(或你喜欢的任何类似名称),它将立即用作你创建所有其他规则的基础:

---
title: 创建有效的 Cursor 项目规则
description: 创建结构良好的 Cursor 项目规则(.mdc 文件)的综合指南,以帮助 AI 理解你的代码库和编码风格。
glob: "**/*.{mdc}"
alwaysApply: true
---
# 创建有效的 Cursor 项目规则
此 meta-rule 提供了关于创建有效的 Cursor 项目规则的综合指南。这些规则是存储在你项目的 `.cursor/rules` 目录中的 `.mdc` 文件,可以帮助 AI 了解你的特定代码库、约定和偏好。遵循这些指南将帮助你创建易于人类和 AI 理解的规则,从而实现更一致和更有帮助的 AI 交互。
## 什么是 Cursor 项目规则?
项目规则是为 Cursor 的 AI 提供持久的、特定于项目的指令的推荐方法。它们与你的代码一起存在(在 `.cursor/rules/` 中),并且当在聊天或其他 AI 功能中引用与其定义的模式 (`glob`) 匹配的文件时,会自动激活。
将它们视为你项目的结构化知识库,用于教导 AI:
* 编码约定和风格指南
* 架构模式
* API 用法和接口
* 领域特定知识
* 你的个人或团队偏好
## 规则文件结构
虽然很灵活,但结构良好的规则文件可以提高人类和 AI 的清晰度。考虑包含以下组件:
### 1. YAML Frontmatter(至关重要)
**位置:** YAML frontmatter 块 (`--- ... ---`) **必须**是文件中的绝对第一个内容。任何前导空格、行或字符都可能阻止规则正确加载。
```yaml
---
title: 规则的简短标题(例如,React 组件指南)
description: [此规则涵盖的内容及其目的,例如,构建函数式 React 组件] 的指南
glob: "[pattern/to/match/files/**/*.{ext}]" # 参见下面的示例
alwaysApply: false # 可选:设置为 true 以始终包含此规则
---

2. 内容部分(推荐结构)

有逻辑地组织规则的内容。建议使用 markdown 标题 (##, ###)。

介绍 / 问题

模式描述

实施步骤(如果适用)

真实世界的例子(强烈推荐)

常见陷阱 / 反模式

高级功能

文件引用 (@file)

使用 @file 指令将关键的上下文文件直接包含在你的规则中。将这些文件放在 frontmatter 之后,但理想情况下放在主要内容_之前_。

@file ../tsconfig.json
@file ../package.json
@file ./docs/ARCHITECTURE.md

代码块

始终使用带有语言说明符的 fenced code blocks,以实现正确的渲染和 AI 的潜在语法突出显示:

```typescript
function greet(name: string): string {
 // 格式正确的 TypeScript
 return `Hello, ${name}!`;
}
```

规则激活和交互

最佳实践

团队协作

完整规则示例

---
title: React 函数式组件结构
description: 使用 TypeScript 构建函数式 React 组件的指南,包括属性定义、状态管理和 Hook 用法。
glob: "src/components/**/*.tsx"
alwaysApply: false
---
@file ../../tsconfig.json
@file ../../tailwind.config.js
# React 函数式组件结构
## 介绍
此规则定义了本项目中函数式 React 组件的标准结构,以确保一致性、可读性和可维护性。我们使用 TypeScript 来确保类型安全,并且首选使用 Hook 来处理状态和副作用。
## 模式描述
组件通常应遵循以下顺序:
1. `'use client'` 指令(如果需要)
2. 导入 (React, libs, internal, types, styles)
3. 属性接口定义 (`ComponentNameProps`)
4. 组件函数定义 (`function ComponentName(...)`)
5. 状态 Hook (`useState`)
6. 其他 Hook (`useMemo`, `useCallback`, `useEffect`, 自定义 Hook)
7. 辅助函数(定义在外部或内部记忆化)
8. `useEffect` 块
9. Return 语句 (JSX)
```typescript
'use client' // 仅当需要浏览器 API 或 useState/useEffect 等 Hook 时
import React, { useState, useEffect, useCallback } from 'react';
import { cn } from '@/lib/utils'; // 内部实用程序的示例
import { type VariantProps, cva } from 'class-variance-authority';
// 定义属性接口
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
 isLoading?: boolean;
}
// 定义组件
function Button({ className, variant, size, isLoading, children, ...props }: ButtonProps): React.ReactElement {
 // 状态 Hook
 const [isMounted, setIsMounted] = useState(false);
 // 其他 Hook
 const handleClick = useCallback((event: React.MouseEvent<HTMLButtonElement>) => {
 if (isLoading) {
 event.preventDefault();
 return;
 }
 props.onClick?.(event);
 }, [isLoading, props.onClick]);
 // Effects
 useEffect(() => {
 setIsMounted(true);
 }, []);
 // 条件渲染逻辑可以放在这里
 // 返回 JSX
 return (
 <button
 className={cn(buttonVariants({ variant, size, className }))}
 disabled={isLoading}
 onClick={handleClick}
 {...props}
 >
 {isLoading ? '加载中...' : children}
 </button>
 );
}
// 变体定义的示例(可以放在同一个文件中或导入)
const buttonVariants = cva(
 'inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background',
 {
 variants: {
 variant: {
 default: 'bg-primary text-primary-foreground hover:bg-primary/90',
 // ... 其他变体
 },
 size: {
 default: 'h-10 py-2 px-4',
 // ... 其他尺寸
 },
 },
 defaultVariants: {
 variant: 'default',
 size: 'default',
 },
 }
);
export { Button, buttonVariants }; // 首选命名导出

实施步骤

  1. 为属性定义清晰的 interface
  2. 使用标准的 React Hook 来处理状态和副作用。
  3. 使组件专注于单一职责。
  4. 为组件使用命名导出。

真实世界的例子

常见陷阱

## 最小规则模板
将此用作新规则的快速起点:
```markdown
---
title: [规则名称]
description: [目的] 指南
glob: "[pattern]"
alwaysApply: false
---
# [规则名称]
## 介绍 / 问题
[此规则存在的原因以及它解决了什么问题。]
## 模式描述
[用代码示例解释该模式。]
## 真实世界的例子
* [链接到代码](mdc:../path/to/example.ts)
## 常见陷阱
* [常见错误 1]
* [常见错误 2]
复制
## [](https://www.adithyan.io/blog/<#building-systems-pays-off>)构建系统会带来回报
使用像这样的 meta-rule 可以帮助你为你的 AI 交互构建系统。你教 AI 如何始终如一地创建自己的文档。
这会创建一个积极的反馈循环,提高你项目中的一致性,并为你节省大量时间。在定义一个好的 meta-rule 方面的少量前期投资会很快得到回报,因为你花费在重复指令上的时间更少,而花费在构建上的时间更多。
随着 AI 越来越融入我们的开发工作流程,那些创建有效系统的人将获得巨大的优势。
我鼓励你在你自己的项目中尝试这种方法。
整个博客文章是我自己对 Cursor rule 的理解,但实际的官方文档本身并不太长,所以我强烈建议你也阅读 Cursor 的原始文档。
从一两个关键模式开始,并观察你的 AI 协作的改进速度。如果你开发了自己的 meta-rule 变体,我很乐意听到它们!
© 2025 [Adithyan](https://www.adithyan.io/blog/<https:/x.com/adithyan_ai>)
[](https://www.adithyan.io/blog/<https:/x.com/adithyan_ai>)[](https://www.adithyan.io/blog/<https:/github.com/AdithyanI>)[](https://www.adithyan.io/blog/<https:/www.instagram.com/adithyan.ai/>)[](https://www.adithyan.io/blog/<https:/www.linkedin.com/in/adithyan-ai/>)[](https://www.adithyan.io/blog/</rss.xml>)