Claude Codeを使い始めた最初の1ヶ月、自分は「どれだけ書かせられるか」を試していました。大きめの機能もひとことで指示すればそれっぽく実装が出てくるので、最初は単純に速いツールだと思っていました。
3ヶ月回してみて印象が変わりました。速さそのものより効いてくるのは「何を毎回説明せずに済ませるか」「何を人が握ったままにするか」という任せ方の設計です。この記事は、Next.js(App Router)+TypeScriptの個人開発でClaude Codeを日常的に使ってきた中で、CLAUDE.md・サブエージェント・フック・スラッシュコマンドという実在する機能をどう使い分けたか、そして各所でやった失敗を含めて共有する運用ノートです。
1. CLAUDE.mdは仕様書でなく「毎回の説明を消す」ために書く
最初、CLAUDE.mdに機能仕様や設計の背景をそのまま書いていました。結果として、依頼のたびに参照される情報量が増え、肝心の「毎回言うのが面倒なルール」が埋もれてしまいました。
いまは仕様の置き場ではなく、セッションが変わるたびに自分が口頭で繰り返している指示を消すための場所として使っています。ディレクトリ構成、命名規則、lintとtestをいつ実行するか、くらいに絞ると効きます。
<!-- CLAUDE.md(概念例、抜粋) -->
## 構成
- UIは `app/`、共有ロジックは `lib/` に置く。コンポーネントはPascalCase、関数はcamelCase。
## 実行条件
- ロジックを変更したら `npm run typecheck` と該当テストを実行してから完了報告する。
- 新規ファイルを追加したときはimportパスの解決だけ先に確認する。
失敗談としては、過去の設計判断の経緯まで書き足していった時期があり、CLAUDE.mdが数百行に肥大化しました。情報量が増えるほど参照される優先度が下がる感覚があり、結局古い経緯は別ドキュメントに追い出し、CLAUDE.md自体は「いま守るべきルールだけ」に削り直しました。仕様書ではなく、繰り返し説明を省くためのファイルだと割り切ってからのほうが扱いやすいです。
2. サブエージェントは実装より調査・レビュー担当に分ける
Claude Codeのサブエージェント(.claude/agents/*.mdにfrontmatterでname・description・tools・modelを定義する仕組み)は、最初「実装を並列で進めるための機能」だと捉えて使っていました。これは失敗でした。複数のサブエージェントに近い範囲のファイルを同時に実装させたところ、片方の変更をもう片方が知らないまま進み、マージ時に差分が衝突しました。実装は基本的に1本の流れで進めたほうが安全だと感じています。
いま効いているのは、実装ではなく調査・レビュー専任のサブエージェントです。「既存のDB操作パターンを探す」「変更がどのテーブル・APIに影響するか洗い出す」「差分をレビューして既存の命名規則から外れていないか指摘する」といった役割に絞ると、実装用のセッションとは別の視点で並行して情報を集めてくれます。
---
name: db-impact-scout
description: 変更対象のテーブル・APIへの影響範囲だけを調査する。実装は行わない。
tools: Read, Grep, Glob
model: sonnet
---
あなたは実装を行わない調査担当です。指定された変更が影響するテーブル・関数・APIルートを列挙し、
実装方針の提案はせず事実だけを報告してください。
toolsをRead/Grep/Globだけに絞っているのがポイントで、書き込み権限を持たせないことで「調査のつもりが実装まで進んでしまう」事故を防いでいます。
3. フックは自動化しすぎず「壊れやすい作業だけ」に絞る
Claude Codeのフック(ファイル編集などのイベントに合わせてコマンドを自動実行する仕組み)は、最初「使えるものは全部自動化しよう」と考えて、編集のたびにフォーマッタ・型検査に加えて関連テストまで走らせる設定にしていました。結果、1つの小さな修正のたびに数十秒待つことになり、テンポが落ちて逆に手を止めたくなりました。壊れていない検証まで毎回走らせるのは、自動化というより足かせでした。
いまは「人が忘れがちで、かつ壊れると気づきにくい作業」だけに絞っています。具体的には、編集後の整形(フォーマッタ)のような軽い処理だけです。
// settings.json(概念例、抜粋)
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | xargs -r npm run format:fix --"
}
]
}
]
}
}
ここで一点、実際にやって気づいたことがあります。PostToolUse フックは編集イベントの情報を標準入力にJSONで受け取り、対象ファイルのパスは .tool_input.file_path に入っています(環境変数で渡ってくるわけではありません)。上の例は jq でそのパスを取り出してフォーマッタに渡しています。ここを勘違いして環境変数のつもりで書くと、対象が渡らず何も整形されない、という空振りになります。
型検査やテストのような重い検証は、毎回のフックから外してスラッシュコマンドや依頼の中で明示的に呼ぶ形に戻しました。「壊れやすい・忘れやすい・軽い」ものだけをフックに残すと決めてから、テンポを落とさずに事故だけ防げるようになった感覚があります。
4. カスタムスラッシュコマンドで「よくある依頼」を定型化
同じような依頼(差分レビュー、リファクタ前の計画立案など)を毎回一から文章で書いていると、日によって調査範囲や出力形式がぶれます。ある日は「ここも見て」と言い忘れ、別の日は検証手順を書かずに走らせてしまい、あとで型エラーに気づく、ということがありました。
これに対しては.claude/commands/にスラッシュコマンドとして依頼のテンプレートを定型化しています。調査範囲・出力形式・検証手順まで先に埋めておくのがポイントです。
<!-- .claude/commands/review.md(概念例) -->
差分を次の順でレビューしてください。
1. 既存の命名規則・ディレクトリ構成から外れていないか
2. 型定義とAPIの入出力が一致しているか
3. 追加/変更したロジックに対応するテストがあるか
最後に「要修正」「軽微な指摘」「問題なし」の3段階でまとめてください。
毎回書き直さずに/reviewと打つだけで済むようになり、依頼の質が日によってぶれることが減りました。定型化した分だけ、依頼者側(自分)の判断コストも下がっています。
5. 大きめリファクタは一発でなく3段階に分ける
範囲の広いリファクタを「まとめて任せる」と、差分が一気に膨らんで自分でもレビューしきれなくなる、という失敗を何度かしました。特に、命名規則の統一のような「触るファイル数は多いが1件ごとの変更は単純」なタスクを一括で依頼すると、想定していなかったファイルまで巻き込まれて差分が読めなくなります。
いまは次の3段階に分けています。
- 影響範囲の列挙 — 変更対象になるファイル・関数を先に洗い出してもらう(実装はしない)
- 計画 — 洗い出した範囲を、どの順番で・どの単位で変更するか計画してもらう
- 小単位の実装 — 計画の1単位ずつ実装してもらい、都度差分を見る
一発で任せていた頃と比べると依頼の回数は増えますが、各回の差分が小さいのでレビューの負荷が下がり、途中で方針を変えたいときも被害が小さく済みます。速く終わらせることより、途中で止められる形にしておくことのほうが結果的に早く着地する印象です。
6. AIに任せない判断を先に決める
最後は技術というより運用の話です。方針の選定(どのアーキテクチャで進めるか)、データ設計のトレードオフ(正規化するか・冗長に持つか)、最終的な差分の承認は、いまは最初から人が持つと決めています。
これを決める前は、設計判断を含む依頼を投げてそのまま採用することがありました。セッションが変わるとその場の文脈だけで別のトレードオフを選ぶことがあり、同じような判断が実装のあちこちで一貫していない、ということが起きました。判断そのものをAIに委ねると、セッションをまたいだ一貫性が保たれにくいというのが実感です。
なので、方針やデータ設計は自分で決めてから「この方針で実装して」と渡す、実装後の差分は毎回自分で読む、という順序にしています。任せるのは「決めたことを形にする」部分までで、「何を決めるか」は渡さない、という線引きです。
まとめ
3ヶ月を振り返ると、行き着いた型はシンプルでした。調べる → 計画する → 小さく実装する → 差分をレビューする。この4段階のうち、調べる・計画する・小さく実装するはサブエージェントやスラッシュコマンドで定型化できますが、差分のレビューと最終判断だけは毎回人が持つようにしています。
Claude Codeは「たくさん書かせる道具」というより、判断を残しながら反復作業を減らす道具として使うほうが、自分には合っていました。
個人開発でWebサービス(Kapsel)を作っています。
https://getkapsel.com?utm_source=qiita&utm_medium=social&utm_campaign=claude-code-solo-ops