Cursor(AI IDE)はどのように動作するのか
(blog.sshh.io)- AIコーディングツールであるCursor、Windsurf、Copilotの内部動作を理解すると、複雑なコードベースで生産性を高め、一貫した性能を確保できる
- 多くの人はAI IDEの限界を理解しないまま従来のツールのように扱い、性能問題を経験している
- この記事では、Cursorの内部動作、システムプロンプト、そしてコーディングおよびCursorルールの最適化方法を説明する
LLMからコーディングエージェントへ
大規模言語モデル(LLM)
- LLMは基本的に次の単語を予測する方式で動作する
- プロンプトを与えると、LLMがオートコンプリートとして応答を生成する
- 初期のデコーダベースLLM(例: GPT-2)は、完成した結果を得るために特定のプロンプト作成が必要だった
- プロンプトエンジニアリングは、モデルを「誘導して」望む答えを引き出す技術である
- **命令チューニング(Instruction Tuning)**の導入後、使いやすさが向上した
- 「FooメソッドをリファクタリングするPRを書いて」のような命令がそのまま実行される
- 実際にはオートコンプリートプロセスの拡張版である
- **ツール呼び出し(Tool Calling)**が追加された
- モデルがファイルの読み取り、書き込み、コマンド実行のような作業を行える
- 例:
read_file('index.py')→ クライアントがファイル内容を提供 → モデルが作業を進める
エージェントベースのコーディング
CursorのようなAI IDEは、複雑なラッパー構造を使って構成されている:
- VSCodeフォーク → オープンソース基盤から開始
- チャットUIの追加と適切なLLMの選定(例: Sonnet 3.7)
- コーディングエージェント用ツールの実装
read_file(full_path: str)write_file(full_path: str, content: str)run_command(command: str)
- プロンプト最適化
- "あなたは専門家コーダーです"、"推測せずツールを使え" などの命令を追加
→ 単に上記の手順を実装するだけでも実際には動くが、構文エラー、ハルシネーション、一貫性不足の問題が発生する可能性がある
- "あなたは専門家コーダーです"、"推測せずツールを使え" などの命令を追加
エージェントベースのコーディング最適化戦略とヒント
- 良いAI IDEを作るには、LLMが得意な作業を把握し、LLMの限界に合わせてプロンプトとツールを慎重に設計する必要がある。
- 主作業を単純化し、サブタスクにより小さなモデルを使う方式が効果的である
- 複雑な作業を分散処理して性能と一貫性を改善できる
-
ユーザーコンテキストの追加(@fileの使用)
- ユーザーはすでに適切なファイルやコンテキストを知っている可能性が高い
@file構文を追加 → ファイル全体またはフォルダ内容を含めてコンテキストを提供- ヒント:
@folder/@fileの積極的な使用を推奨 → 明確なコンテキスト提供で応答速度と精度を改善
-
コード検索の最適化
- コード検索は複雑になりうる。特に意味ベース検索(例: "認証コードの場所")は難しい
- コードベースを**ベクターストア(Vectorstore)**にインデックス化 → 検索時にLLMが自動でフィルタリングと再ランキングを行う
- ヒント: コードコメントと文書は重要 → 埋め込みモデルの性能を強化する
- ファイル上部にそのファイルの目的、意味、修正時点の説明を追加する
-
ファイル作成の最適化
- 完璧なコード作成は難しく、コストも高い
- ファイル全体ではなく**意味的差分(Semantic Diff)**を生成 → 修正されたコード断片だけを提供
- 意味的差分を基に別の適用モデルが実際のファイル書き込みを行い → 構文エラーを修正
- ヒント: 適用モデルには直接プロンプト命令できない → ファイル全体を渡して制御を強める
- ヒント: 適用モデルは大きなファイル編集時に遅くなり、エラーが発生しうる → ファイルサイズを500 LoC以下に保つ
- ヒント: リンター(linter)のフィードバックは非常に重要なシグナル → 強力なリンターの導入が必須
- コンパイル言語や型付き言語が提供するフィードバックも活用できる
- ヒント: 固有のファイル名を使う →
page.jsの代わりにfoo-page.js、bar-page.jsのような具体的な名前を使う- 文書内で完全なファイルパスを提供 → 編集ツールの曖昧さを排除
-
エージェント特化モデルの使用
- 一般的なコード生成モデルではなく、エージェント特化モデルの使用を推奨
- AnthropicのモデルがCursorのようなIDEで優れた性能を示す理由である
- ヒント: 単なるコード生成ではなく、エージェントベースIDEに最適化されたモデルを選ぶ
- WebDev Arenaのリーダーボードでモデル性能を確認できる
-
自己修正ツールの使用(高度な戦略)
- "apply_and_check_tool" → 高コストなリンター実行 + ヘッドレスブラウザでコンソールログとスクリーンショットを収集
- MCP(Model Context Protocol)→ エージェントの自律性とコンテキスト提供を強化
Cursorシステムプロンプトの詳細分析
- Cursorの最新プロンプト(March 2025)は、MCPベースのプロンプト注入手法を通じて抽出された
- Cursorのプロンプトエンジニアは、他のAI IDEと比べても優れたプロンプト作成能力を持っている。
- プロンプト構造を分析すれば、コード生成性能とエージェントアーキテクチャ設計能力を改善できる
-
主要なプロンプト要素と意味
- "<communication>"、"<tool_calling>" などのタグを使用
- MarkdownとXMLタグを混在使用 → 人が読みやすく、LLMが処理しやすい
- "powered by Claude 3.5 Sonnet"
- モデルの一貫性を強化 → LLMが実行中モデルについて誤情報を出すのを防ぐ
- "the world's best IDE"
- LLMがエラー発生時に他製品を勧めるのを防ぐ
- "we may automatically attach some information…follow the USER's instructions…by the <user_query> tag."
- ユーザープロンプトを直接渡さず、特殊タグに含めて混乱を防ぐ
- "Refrain from apologizing"
- 不要な謝罪を防ぐ(Sonnetモデルの特性を補う)
- "NEVER refer to tool names when speaking"
- ツール名に言及しないという命令を追加 → ただし実際のモデルでは無視される場合がある
- "Before calling each tool, first explain"
- ツール呼び出し前に状態を説明 → ユーザー体験を改善
- "partially satiate the USER's query, but you're not confident, gather more information"
- 過度な自信による早期応答を防ぐ → 追加情報の収集を促す
- "NEVER output code to the USER"
- 直接コードを出力することを禁止 → ツール経由でのみコード生成を許可
- "If you're building a web app from scratch, give it a beautiful and modern UI"
- 単一プロンプトで魅力的なWebアプリ生成を誘導(デモ目的)
- "you MUST read the the contents or section of what you're editing before editing it"
- コード修正前にコンテキストを読むことを強制 → 文脈認識を強化
- "DO NOT loop more than 3 times on fixing linter errors"
- 修正ループを制限 → 無限ループを防ぐ
- "Address the root cause instead of the symptoms."
- 問題の症状ではなく根本原因の修正を促す
- "DO NOT hardcode an API key"
- セキュリティ強化のための命令 → ハードコーディングを防止
- "codebase_search"、"read_file"、"grep_search"、"file_search"、"web_search"
- コード作成前に正しいコンテキストを確保するための各種検索ツールを提供
- "One sentence explanation…why this command needs to be run…" の要求
- ツール引数処理時の論理性を強化 → プロンプト改善技術を適用
- "reapply"ツールは "Calls a smarter model to apply the last edit"
- 最後の修正内容をより高度なモデルで再適用 → 修正品質を改善
- "edit_file"ツールは "represent all unchanged code using the comment of the language you're editing"
- 変更されていないコードをコメントで表現 → 編集モデルの動作精度を強化
- "<communication>"、"<tool_calling>" などのタグを使用
- プロンプトキャッシングの活用
- システムプロンプトとツール説明は静的状態として維持
- コードベースやユーザーごとのカスタマイズはない → プロンプトキャッシングでコストと処理速度を改善できる
Cursorルールを効果的に書いて使う
- Cursorルール作成の正解は状況によって異なりうるが、プロンプト作成経験とCursor内部構造への理解を基に、いくつか有用なヒントを示す
- ルールは単純な命令ではなく、百科事典型のガイドとして書くことが重要である。
-
ルール作成の核心概念
- LLMはルール一覧の名前と説明を基に**fetch_rules(…)**を呼び出す
- ルールはシステムプロンプトに追加されず、必要なときに参照される
- したがって命令ではなく百科事典的な説明方式が効果的である
-
ルール作成時に避けるべきこと
- アイデンティティ(identity)の定義禁止
- "あなたはTypeScriptの専門家です" のような説明は禁止
- LLMはすでに内蔵プロンプトでアイデンティティを認識している → 衝突リスクがある
- システムプロンプトの上書きを試みない
- "コメントを追加するな"、"質問してからコードを書け" などの命令 → 内部ツール利用に混乱を招く
- 否定命令を避ける
- "するな" より "しろ" のような肯定命令の方がLLMに有効
- 肯定命令の例: "ファイル修正時は全体コンテキストを確認してから修正する"
- アイデンティティ(identity)の定義禁止
-
ルール作成時の推奨事項
- 明確で直感的なルール名と説明を書く
- コードベースに関する最小限の情報だけでもルール適用が可能であるべき
- 重複ルールの作成も可能 → 検索精度を向上
- ルールは百科事典的に書く
- 具体的命令より状況や目的の説明を提供
- 必要に応じてコードファイルを添えて文脈を強化できる
- Cursorを使ってルールのドラフトを作る
- LLMは他のLLMのためのコンテキスト作成に強い
- 例: "@folder/ よく修正されるコードパスと定義に関するMarkdownファイルを作成"
- ルールを過剰に作らない
- ルールが多すぎるのは非効率であり、直感的でないコードベースを意味する
- 理想的なコードベースでは、エージェントが最小限のルールで作業できるべきである
- 明確で直感的なルール名と説明を書く
-
効果的なルール作成例
- ✅ ルール命令:
- "ファイル修正前に全体コンテキストを読む"
- "サーバーコード修正時は認証コードロジックを確認する"
- "エラー発生時は原因を先に修正する"
- ❌ ルール命令(避けるべき):
- "コメントを削除するな"
- "修正前に私に質問しろ"
- "不要なコード修正をするな"
- ✅ ルール命令:
-
ルール作成の核心戦略
- ルールは命令ではなく状況説明として書く
- 直感的な名前と説明を使う → 最小限のルールで最大限の性能を確保
- 具体的な命令より状況説明とコード連携を強化
結論
- VSCodeのフォークから始まり、オープンソースベースのプロンプトと公開モデルAPIを使ったCursorが**100億ドル(約13兆ウォン)**に近い評価額を得たのは驚くべきことだ
- Cursorは現在、"wrapper multiple" 基準で6倍の評価を受けている
- Cursorは最適化されたプロンプトと強力なツール呼び出しシステムのおかげで高い性能を提供する
- Cursorが独自のエージェントモデルを開発する可能性は低い
- 代わりにAnthropicがClaude CodeとSonnetベースの競合製品を投入する可能性が高い
-
核心インサイト
- コードベース、ドキュメント化、ルールを正しく整備することは今後も重要な技術になる
- AIコーディングツールの最適化戦略を理解すれば、生産性と正確性を強化できる
- Cursorがうまく動作しないなら、使い方の問題である可能性が高い
"Cursorが動かないなら、使い方をもう一度見直すべきだ。"
4件のコメント
試してみないといけませんね
面白いですね。やはり同じ水を飲んでいるからでしょうか?
洞察が込められていますね。ありがとうございます。