Claude Codeが生成するコードの品質を上げる5つの方法【実践ガイド】
Claude Codeを半年使ってきて、ようやく「AIとの付き合い方」が分かってきました。
最初の頃は「動くコードを出してくれるなら何でもいい」と思っていたんですが、実際にプロダクションで使うとなると話が違う。
動くけど、保守できないコードが量産されていく。
useEffectが10個並んでいるコンポーネント。急にインラインCSSが混ざるスタイル。フロントとバックエンドで微妙に違う型定義。
「AIが悪い」と思っていた時期もありましたが、結論から言うと指示の出し方の問題でした。
この記事では、僕が試行錯誤して見つけた「コード品質を上げる5つの方法」を紹介します。
この記事で分かること
- Claude Codeが「やりがち」な品質問題
- CLAUDE.mdに何を書けばいいか
- 「指示を忘れる」問題への対処法
- チーム開発で揉めないための型管理
目次
- Claude Codeがやりがちな品質問題
- CLAUDE.mdの書き方(これが9割)
- 「NG例」を見せると効果絶大
- 型定義は一箇所で管理する
- コンテキスト管理(長時間作業のコツ)
1. Claude Codeがやりがちな品質問題
まず、僕が実際に遭遇した問題を4つ紹介します。
1-1. useEffectの乱用(React)
Reactのコンポーネントを作らせると、とにかくuseEffectを使いたがる。
// AIが生成しがちなコード
useEffect(() => {
setProcessedData(process(rawData));
}, [rawData]);
いや、これuseMemoでよくない?
// 本来はこう
const processedData = useMemo(() => process(rawData), [rawData]);
動くんですよ、動くんだけど、後から見ると「なんでuseEffect?」ってなる。レビューで毎回指摘するのも面倒。
1-2. 急にインラインCSSを書き出す
プロジェクトでCSS Modulesを使っていても、お構いなしにインラインで書いてくることがある。
// 既存コード
<button className={styles.primary}>Click</button>
// AIが追加したコード
<button style={{ backgroundColor: 'blue', padding: '10px' }}>New Button</button>
なんで急にインライン?既存コード見てないの?
1-3. 型定義がフロントとバックエンドで違う
これが一番厄介だった。バックエンドのAPIを作らせて、その後フロントエンドを作らせると、型定義が微妙にずれる。
// バックエンド
interface User { userId: number; createdAt: Date; }
// フロントエンド(別のタスクで生成)
interface User { user_id: number; created_at: string; }
camelCaseとsnake_caseが混在。型も違う。「画面に何も表示されない」デバッグに1時間かかった。
1-4. 長時間作業すると指示を忘れる
CLAUDE.mdに「console.logは残さない」と書いてあるのに、30分もすると普通に残してる。
最初は「AIの限界か」と思ったけど、これはコンテキストの圧縮が原因だった。
2. CLAUDE.mdの書き方(これが9割)
結局、CLAUDE.mdにどれだけ具体的に書くかで品質が決まる。
僕が使っているテンプレート
# プロジェクト概要
React + TypeScriptのWebアプリケーション
## 絶対に守るルール
- CSSはCSS Modulesのみ(インラインCSS禁止)
- console.logを本番コードに残さない
- any型の使用禁止
## Reactのルール
- 状態の派生はuseMemo、副作用はuseEffect
- useEffectは最小限に
## 禁止事項(具体例)
以下のようなコードは書かない:
- useEffect内でsetState(useMemoで代替可能な場合)
- style={{ }} のインラインCSS
- any型、as any
ポイント: 「禁止」だけじゃなく「何を使うか」も書く。
CLAUDE.mdが無視される問題
「書いてあるのに守らない」問題、僕もめちゃくちゃ経験した。
解決策は三重化。
- CLAUDE.mdに書く
- プロンプトでも言う
- 具体的に指定する
新しいボタンコンポーネントを作ってください。
CLAUDE.mdの規約を守ってください。
CSSはCSS Modulesで書いてください。
「CLAUDE.md見て」だけだと、本当に見てるのか怪しい。具体的に言うと守る確率が上がる。
CLAUDE.mdが大きすぎると逆効果
調子に乗って仕様書を全部書き込んだら、「Large CLAUDE.md will impact performance」って怒られた。
40k文字以下に抑えるのがベスト。詳細な仕様は別ファイルにして、必要なときだけ参照させる。
## 詳細仕様
- API仕様: @docs/api-spec.md
- コンポーネント設計: @docs/components.md
3. 「NG例」を見せると効果絶大
抽象的なルールより、具体的なNG例を見せるほうが効く。
## NG例(これは書かない)
// ❌ 副作用のためだけのuseEffect
useEffect(() => {
setProcessedData(process(data));
}, [data]);
// ❌ インラインスタイル
<div style={{ margin: '10px' }}>
## OK例(こう書く)
// ✅ useMemoを使う
const processedData = useMemo(() => process(data), [data]);
// ✅ CSS Modulesを使う
<div className={styles.container}>
これをCLAUDE.mdに入れてから、useEffect乱用がかなり減った。
4. 型定義は一箇所で管理する
フロントとバックエンドで型がずれる問題、根本解決はOpenAPIから自動生成。
やり方
- まずOpenAPIスペックを作らせる
- そこから型定義を生成
- フロント・バックエンド両方で使う
からTypeScriptの型定義を生成してください。
フロントエンドはこの型定義を絶対に使用してください。
独自に型を定義しないでください。
「独自に型を定義しないで」がポイント。言わないと、勝手に作る。
5. コンテキスト管理(長時間作業のコツ)
30分以上の作業で指示が忘れられる問題、これはコンテキストの仕組みを理解すると対処できる。
「/clear」 と 「/compact」 を使い分ける
「/clear」
使いどころ: 新しいタスクを始めるとき
「/compact」
使いどころ: コンテキストが80%くらいになったとき
僕はタスクごとに 「/clear」 するようにしてる。前のタスクの文脈が混ざると、変な動きをすることがあるから。
大きなタスクは分割する
「API作って、フロントも作って、テストも書いて」みたいな指示は危険。
このタスクは3つに分けて進めます:
1. APIエンドポイントの実装
2. フロントエンドコンポーネントの作成
3. テストの追加
まず1から始めてください。
分割すると、各タスクで 「/clear」 できるから品質が安定する。
まとめ
半年使って分かったことをまとめると:
| 方法 | 効果 |
|---|---|
| CLAUDE.mdを具体的に書く | 基本ルールの定着 |
| 三重化で指示する | 忘却防止 |
| NG例を見せる | 品質基準の明確化 |
| 型定義を一元管理 | 不整合の根本解決 |
| タスクごとに/clear | 長時間作業の安定化 |
正直、最初は「AIに任せれば楽」と思ってたけど、AIにうまく指示を出すスキルが必要だった。
でも、このスキルを身につけると、本当に開発が速くなる。
Discussion