🏬

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.mdcsample2.mdcを読み込むように誘導する
  • sample2.mdcで「Sample2だよ」と応答させる
  • sample2.mdcで現在時刻を応答させる
    という流れのプロンプトを書いています。

上記*.mdcがある状態で、Cursorに対して様々なプロンプトで指示し、その応答を調べます。
期待する動作としては

Sample1だよ。〜〜〜
〜〜〜〜〜〜〜〜〜〜
〜〜〜〜〜〜〜〜〜〜
〜〜〜〜〜〜〜〜〜〜です。
Sample2だよ。2025-4-15:12:00:00です。

のような応答がCursorから返ってくることです。このように返ってくれば、分割した規則の橋渡しができるということを意味します。

結果

しかしながら、冒頭で述べた結果の通り、これではうまくいきません。

  • 「Sample1だよ」✅ これはほぼ常に返してくれる
  • 「Sample2だよ」❌ これは全く返してくれない
  • 時刻      ❌ これは全く返してくれない

また留意点なのですが、このときCursor Setting>Rulesを確認すると


という表記になっていました。英文には'may'とあるので、実際どうなっているか曖昧です。
現状の不明点かつ懸念点になっています。

https://www.reddit.com/r/CursorAI/comments/1jr5mvi/this_rule_may_never_be_used_since_it_has_no/
(私と同じ現象の人がいます😇)

結論

  • 2つの*.mdcファイルの規則を依存させるような書き方は効果がありません。先に読み込まれるほうが優先されます。
  • *.mdcに書く対象は1つの対象に絞るべきです。
    e.g., リポジトリにサービスA、サービスBがある場合、サービスA用のA.mdc、サービスB用のB.mdcのように、互いが疎結合なプロンプトになるようにすべきだと考えます。

参考文献/外部リンク

[1] https://sdrmike.medium.com/cursor-rules-why-your-ai-agent-is-ignoring-you-and-how-to-fix-it-5b4d2ac0b1b0

[2] https://github.com/justdoinc/justdo/blob/master/.cursor/rules/999-mdc-format.mdc

脚注
  1. mdcとはMarkdown Configurationの略です。 ↩︎

  2. 実機で試しているのは別の名前ですが、未公開プロジェクトのため名前を伏せています ↩︎

Discussion