この記事は Claude on SonicGarden の記事です。ソニックガーデンのプログラマが、Claude Codeの活用について書いています。#claude_on_sonicgarden
きっかけ
Claude Code、もはやない人生は考えられないくらいお世話になっているのですが、ここはこう書いてほしいんだよなーみたいなのはどうしてもちょいちょい発生します。
なので.claude/rules/を整備していかないとなーと思うのですが、ルールファイルをコードを眺めながら自分で一から書いていくのはなかなかモチベーションが上がりません。
そこでコードベースやClaude Codeとのやり取りから自動的にルールを抽出するスキルを作りました。
設計思想
「Claudeが知らないことだけを抽出する」がこのスキルの方針です。
Claude Codeは const を使え、DRYを守れ、といった一般的なベストプラクティスはすでに知っています。わざわざルールに書く必要がないし、書くとコンテキストを圧迫するだけです。
| 抽出する | 抽出しない |
|---|---|
| チーム固有のスタイル選択(FPのみ、classは使わない) | 一般的なベストプラクティス(const, DRY) |
プロジェクト定義のシンボル(useAuth(), RefOrNull<T>) |
言語の標準的な使い方 |
| フレームワークのレイヤー別規約 | フレームワーク公式ドキュメントに書いてあること |
「このルールがなかったら、Claude Codeは違うコードを書くだろう」というものだけに絞っています。
作ったもの
コードベース・会話履歴・PRレビューの3つのソースからルールを抽出できるAgent Skillです。
使い方
| モード | コマンド | 用途 |
|---|---|---|
| 初回抽出 | /extract-rules |
コードベースからルールを一括抽出 |
| 更新 | /extract-rules --update |
新しいパターンを追加(既存は保持) |
| 再構成 | /extract-rules --restructure |
ファイル構造を最適化 |
| 会話から抽出 | /extract-rules --from-conversation |
会話履歴からルールを抽出 |
| PRから抽出 | /extract-rules --from-pr 123 |
PRレビューコメントから抽出 |
初回は /extract-rules でコードベースから一括抽出し、その後は --from-conversation や --from-pr で日常的にルールを積み上げていく運用です。
--from-conversation
一番よく使っているモードです。
Claude Codeとペアプロしていると、「いや、うちではそうじゃなくて...」と修正するシーンがあります。こういったやり取りこそが、ルールの宝庫です。
/extract-rules --from-conversation
ポイントは、compact後でもセッションの全会話履歴を読めること。
Claude Codeは各セッションの全メッセージを ~/.claude/projects/ 配下に .jsonl ファイルとして保存しています。--from-conversation はコンテキストではなくこのファイルを直接読むので、compactされていても関係ありません。
内部では専用スクリプトが .jsonl をパースして、最新のメッセージを優先しつつテキストを抽出します。AskUserQuestion などへのユーザー回答も拾います。これらは明示的な好みの表明なので、ルール抽出の良いシグナルになります。
デフォルトでは最新の .jsonl を自動選択しますが、同一プロジェクトでClaude Codeを複数同時に動かしている場合は /extract-rules --from-conversation <session-id> でセッションを明示指定したほうが確実です。
修正や好みの議論が発生したタイミングでこまめに実行するのがおすすめです。
--from-pr
チームのコードレビューにはルールの種が詰まっています。
/extract-rules --from-pr 123
/extract-rules --from-pr owner/repo#123
/extract-rules --from-pr 100..110
PR番号、owner/repo#番号 形式、範囲指定のいずれでも指定できます。botのコメントは自動で除外されます。
複数PRを指定すると横断分析が行われます。一般的なベストプラクティスであっても、チーム内で繰り返し指摘されているなら「このチームが特に重視している原則」として具体的な適用文脈付きで抽出されます。
出力構造
.claude/rules/
├── languages/
│ ├── typescript.md # Principles(ポータブル)
│ ├── typescript.local.md # Project-specific patterns(ローカル)
│ └── typescript.examples.md # コード例(参照用)
├── frameworks/
│ ├── react.md
│ ├── react.local.md
│ └── react.examples.md
├── project.md
└── project.examples.md
ルールは2種類に分離されます。
Principles(.md) — プロジェクトをまたいで通用する原則。複数プロジェクトで共通ルールとして共有できます。
- FP only (no classes, pure functions, composition over inheritance)
- Strict null handling (no non-null assertions, explicit narrowing required)
Project-specific patterns(.local.md) — そのプロジェクトでしか使わないパターン。
- `useAuth() → { user, login, logout }` - auth hook interface
- `RefOrNull<T extends { id: string }> = T | { id: null }` - nullable relationships
この分離は、中編で紹介する merge-rules / apply-rules で組織ルールを共有するための設計です。
.examples.md の工夫 — Good/Badのコード例は .examples.md に分離しています。.examples.md には paths: フロントマターを設定していないので、Claude Codeのコンテキストに自動読み込みされません。代わりに .md / .local.md の末尾にリンクを書いておくことで、Claude Codeが判断に迷ったときだけ参照しに行く設計にしています。コード例はサイズが大きくなりがちなので、常時読み込まれるとコンテキストを圧迫してしまいます。
Railsのようなレイヤー構造を持つフレームワークでは、rails-controllers.md、rails-models.md のようにレイヤーごとにファイルが分割され、paths: フロントマターでスコープが設定されます。
使ってみて
- コードベースから抽出したルールはそれなりにプロジェクトの特徴を捉えているので今のところいい感じに抽出できていそう
- 日々のタスクの最後に
--from-conversationを実行することでいい感じにルールが追加されていっている - 昔からのしがらみで現状のコードはこうなってるんだけど今後はこうしていきたいんだよなみたいなところもルール抽出されるので抽出したルールの取捨選択は人間がしたほうがよさそう
ただ、ルールを書いただけではClaude Codeに無視されることも多いです。この問題は後編で紹介する rules-review で対策しています。
おわりに
プロジェクトの流儀をコードベース・会話履歴・PRレビューから自動抽出するスキルを紹介しました。
次回の中編では、抽出したルールを組織内の複数プロジェクトで共有する merge-rules と apply-rules について紹介します。
今回紹介したスキルは以下のリポジトリで公開しています。
hiroro-work/claude-plugins
この記事はZenn/Qiitaにクロスポストしています