🛠️

Claude Codeが生成するコードの品質を上げる5つの方法【実践ガイド】

に公開

Claude Codeを半年使ってきて、ようやく「AIとの付き合い方」が分かってきました。

最初の頃は「動くコードを出してくれるなら何でもいい」と思っていたんですが、実際にプロダクションで使うとなると話が違う。

動くけど、保守できないコードが量産されていく。

useEffectが10個並んでいるコンポーネント。急にインラインCSSが混ざるスタイル。フロントとバックエンドで微妙に違う型定義。

「AIが悪い」と思っていた時期もありましたが、結論から言うと指示の出し方の問題でした。

この記事では、僕が試行錯誤して見つけた「コード品質を上げる5つの方法」を紹介します。

この記事で分かること

  • Claude Codeが「やりがち」な品質問題
  • CLAUDE.mdに何を書けばいいか
  • 「指示を忘れる」問題への対処法
  • チーム開発で揉めないための型管理

目次

  1. Claude Codeがやりがちな品質問題
  2. CLAUDE.mdの書き方(これが9割)
  3. 「NG例」を見せると効果絶大
  4. 型定義は一箇所で管理する
  5. コンテキスト管理(長時間作業のコツ)

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が無視される問題

「書いてあるのに守らない」問題、僕もめちゃくちゃ経験した。

解決策は三重化

  1. CLAUDE.mdに書く
  2. プロンプトでも言う
  3. 具体的に指定する
新しいボタンコンポーネントを作ってください。
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から自動生成

やり方

  1. まずOpenAPIスペックを作らせる
  2. そこから型定義を生成
  3. フロント・バックエンド両方で使う
からTypeScriptの型定義を生成してください。
フロントエンドはこの型定義を絶対に使用してください。
独自に型を定義しないでください。

「独自に型を定義しないで」がポイント。言わないと、勝手に作る。

5. コンテキスト管理(長時間作業のコツ)

30分以上の作業で指示が忘れられる問題、これはコンテキストの仕組みを理解すると対処できる。

「/clear」 と 「/compact」 を使い分ける

「/clear」
 使いどころ: 新しいタスクを始めるとき

「/compact」
 使いどころ: コンテキストが80%くらいになったとき

僕はタスクごとに 「/clear」 するようにしてる。前のタスクの文脈が混ざると、変な動きをすることがあるから。

大きなタスクは分割する

「API作って、フロントも作って、テストも書いて」みたいな指示は危険。

このタスクは3つに分けて進めます:
1. APIエンドポイントの実装
2. フロントエンドコンポーネントの作成
3. テストの追加

まず1から始めてください。

分割すると、各タスクで 「/clear」 できるから品質が安定する。

まとめ

半年使って分かったことをまとめると:

方法 効果
CLAUDE.mdを具体的に書く 基本ルールの定着
三重化で指示する 忘却防止
NG例を見せる 品質基準の明確化
型定義を一元管理 不整合の根本解決
タスクごとに/clear 長時間作業の安定化

正直、最初は「AIに任せれば楽」と思ってたけど、AIにうまく指示を出すスキルが必要だった。

でも、このスキルを身につけると、本当に開発が速くなる。

Discussion