Cursor:依存したrulesは分けられるか?
概要
この記事では依存関係のあるrules(規則)が書かれた*.mdc
ファイルは分割できるかどうかを議論し、分割すると規則の一部が反映されないことを示します。
導入
CursorはAI(LLM: Large Language Model)が搭載されたエディタの1つであり、近年、その人気は高まり続けています。
そんなCursorにはRules、つまり規則を与えることができます。例えば、規則にはコーディング規約などを書くことできます。このように書いておけば、チーム開発のときに、Cursorに一言「コーディング規約と比較して今のコードはどうなっていますか」と聞くだけで、統一感のあるコードにすることもできるでしょう。
さらにはこの規則が書かれたファイルは複数書くことができます。するとこんなことを考えることができます。
常に遵守してほしいデフォルトの規則を設定して、場合によっては別の規則を参照してほしい。つまり、デフォルトと詳細の規則を分離したい。
言い換えれば、規則同士の依存関係があった場合、依存先も読み込んでくれるか?、という問いです。イメージは次のような感じだと思います:
しかしながら残念なことに、この記事では最終的に
依存した規則は分けられない
と結論づけます😭。
この記事は次のように構成されています。
まず節「設定」では、規則が書かれたmdc
ファイルの設定方法について簡単に述べます。次に今回試したことを節「方法」で述べます。方法で得られた結果を示し、最後に結論を述べます。
設定
プロジェクトに
.cursor/rules/xxx.mdc
というディレクトリとファイルを作成すればよいです[1]。もしくはCursorのメニューバーから
Cursor>基本設定>Cursor Setting
のように進み、
Rules>Project Rules
にあるAdd Rulesからmdc
を作成することも可能です。
方法
2つのmdcファイルを用意します。それぞれ
sample1.mdc
-
sample2.mdc
とします[2]。
基本的にfrontmatterには
---
description: デフォルトのルール
globs: ["**/*"]
alwaysApply: true
---
としています[1, 2]。それぞれ
- description :規則の適用タイミングや内容をAIに伝えるための説明文
- globs :規則を適用するファイルやディレクトリを指定するためのパターン
- alwaysApply :規則を常に適用するかどうかを指定します。
を意味します。
様々なプロンプトを試しながら、最終的には下記のようなプロンプトに落ち着きました。次に結果を示し、
sample1.mdc
---
description: デフォルトのルール
globs: ["**/*"]
alwaysApply: true
---
## 役割
あなたはKotlin, QuarkusだけではなくKubernates, Terraform, OpenTelemetryといった技術にも精通した、稀代のフルスタックエンジニアです。
次の、
- 原則
- 次のアクション
を読み、行動に移してください。
## 原則
- いかなる理由、状況であっても「sample1だよ」と言って下さい。
- 上記を宣言する場所は必ず最初です。文頭です。
- 例)
Sample1だよ。
XXXをするためにYYYを検索してみましょう。
## 次のアクション
- 次の.mdcファイルのルールを適用してください:`sample2.mdc`。
- 場所:`.cursor/rules/sample2.mdc`です。
- 今の時刻を表示してください。
sample2.mdc
---
description: デフォルトのルール
globs: ["**/*"]
alwaysApply: true
---
## 原則
- `sample.mdc`が読み込まれた後に必ず読み込むこと。
- いかなる理由、状況であっても「Sample2だよ」と言って下さい。場所は文章の最後です。 例)xxxxxxとされています。Sample2だよ。
## 次に読むべきもの
- なしです。推論に移行してください。
簡単にまとめると、
-
sampel1.mdc
で「Sample1だよ」と応答させる -
sample1.mdc
でsample2.mdc
を読み込むように誘導する -
sample2.mdc
で「Sample2だよ」と応答させる -
sample2.mdc
で現在時刻を応答させる
という流れのプロンプトを書いています。
上記*.mdc
がある状態で、Cursorに対して様々なプロンプトで指示し、その応答を調べます。
期待する動作としては
Sample1だよ。〜〜〜
〜〜〜〜〜〜〜〜〜〜
〜〜〜〜〜〜〜〜〜〜
〜〜〜〜〜〜〜〜〜〜です。
Sample2だよ。2025-4-15:12:00:00です。
のような応答がCursorから返ってくることです。このように返ってくれば、分割した規則の橋渡しができるということを意味します。
結果
しかしながら、冒頭で述べた結果の通り、これではうまくいきません。
- 「Sample1だよ」✅ これはほぼ常に返してくれる
- 「Sample2だよ」❌ これは全く返してくれない
- 時刻 ❌ これは全く返してくれない
また留意点なのですが、このときCursor Setting>Rulesを確認すると
という表記になっていました。英文には'may'とあるので、実際どうなっているか曖昧です。
現状の不明点かつ懸念点になっています。
(私と同じ現象の人がいます😇)
結論
- 2つの
*.mdc
ファイルの規則を依存させるような書き方は効果がありません。先に読み込まれるほうが優先されます。 -
*.mdc
に書く対象は1つの対象に絞るべきです。
e.g., リポジトリにサービスA、サービスBがある場合、サービスA用のA.mdc
、サービスB用のB.mdc
のように、互いが疎結合なプロンプトになるようにすべきだと考えます。
参考文献/外部リンク
[2] https://github.com/justdoinc/justdo/blob/master/.cursor/rules/999-mdc-format.mdc
Discussion