AIコードレビューを導入して品質が上がった3つの理由

個人開発では自分のコードを自分でレビューするしかない。見慣れすぎてミスを見落とす「自分レビューの限界」をずっと感じていた。LLMによるコードレビューを開発フローに組み込んでから、この問題がかなり改善された。

導入前の問題

前職のプロジェクトでは複数人のエンジニアがいたのでコードレビューができていた。個人開発に移ってからは:

  • 自分のコードは慣れすぎて客観的に見られない
  • バグを本番に出してから気づく
  • セキュリティ面の確認漏れが怖い
  • という状況だった。

    導入したフロー

    実装が完了したら、変更差分をClaudeに渡してレビューしてもらう。

    # git diffの内容をClaudeにレビューさせるスクリプト
    git diff HEAD~1 | python review.py
    # review.py
    import sys
    import anthropic
    
    def review_diff(diff_content: str) -> str:
        client = anthropic.Anthropic()
    
        prompt = f"""
    以下のコード変更をレビューしてください。
    
    確認してほしい観点:
    1. バグ・潜在的なエラー(最優先)
    2. セキュリティの問題
    3. パフォーマンスの問題
    4. 可読性の問題(変数名、コメントの適切さ)
    
    各問題は以下の形式で報告してください:
    - [severity: critical/major/minor] ファイル名:行番号 - 問題の説明
    
    問題がなければ「問題なし」と返してください。
    
    コード変更:

    {diff_content}

    """
    
        message = client.messages.create(
            model="claude-3-7-sonnet-20250219",
            max_tokens=2048,
            messages=[{"role": "user", "content": prompt}]
        )
    
        return message.content[0].text
    
    
    diff = sys.stdin.read()
    result = review_diff(diff)
    print(result)

    品質が上がった理由1: 自分では見逃すバグを指摘される

    一番助かっているのが、「自分ではロジックが正しいと思い込んでいるバグ」の発見だ。

    先日やらかしたのがこれ:

    # NG: i += 1 が while ループの外にある
    def find_index(items, target):
        i = 0
        while i < len(items):
            if items[i] == target:
                return i
        i += 1  # ← これが while の外にある(無限ループ)
        return -1

    自分で何度読んでも「正しく見える」んだが、Claudeは「i += 1 がwhile文のスコープ外にあるため無限ループになります」と即座に指摘してくれた。

    品質が上がった理由2: セキュリティの確認がルーティン化できる

    セキュリティの観点は知識がないと見落としやすい。AIレビューを使うことで、自動的にセキュリティチェックが入るようになった。

    # こういうコードを書いたとき
    def get_user(user_id: str):
        query = f"SELECT * FROM users WHERE id = {user_id}"  # SQLインジェクション
        return db.execute(query)

    「SQLインジェクションの可能性があります。パラメータ化されたクエリを使ってください」と指摘が来る。知識として知っていても、実装時に忘れることはある。自動でチェックが入るのが重要。

    品質が上がった理由3: 命名とコメントの客観的なフィードバック

    自分が書いた変数名や関数名は「自分には」意味が通じる。でも他の人(や未来の自分)には通じないことがある。

    # Claudeレビュー例
    def proc(d):  # ← "proc" と "d" は意味不明
        temp = []
        for x in d:
            if x > 0:
                temp.append(x)
        return temp

    「関数名procと引数名dが何を処理するのか不明です。filter_positive_numbers(numbers)のような名前が良いでしょう」という指摘。自分では慣れていて気づかないが、言われてみれば確かにそのとおり。

    レビューの限界と対処法

    AIレビューは万能ではない。気をつけていること:

    ビジネスロジックの正しさは確認できない: 「この計算式でいいのか」という判断はAIには難しい。ドメイン知識が必要な部分は自分で確認する必要がある。

    動的な問題は見つけにくい: スレッドセーフティやメモリリークなど、実行時に初めて現れる問題は静的なコードレビューでは見つかりにくい。

    レビュー精度はコンテキストによる: 変更差分だけを渡してもコードの全体像が分からないと、誤った指摘が来ることがある。重要なレビューのときは関連ファイルも一緒に渡す。

    # 重要なレビュー時はコンテキストを追加
    def review_with_context(diff: str, related_files: dict[str, str]) -> str:
        context = "\n\n".join(
            f"### {filename}\n```python\n{content}\n```"
            for filename, content in related_files.items()
        )
    
        prompt = f"""
    関連ファイル:
    {context}
    
    上記を踏まえて、以下の変更をレビューしてください:
    {diff}
    """
        # ... APIを呼ぶ

    費用感

    Claude 3.7 Sonnetで1回のレビューにかかるAPIコストは平均$0.01〜0.05程度。月100回レビューしても$1〜5。人間のコードレビューをお願いするコストと比べれば無視できるレベル。

    まとめ

    AIコードレビューを開発フローに組み込んで品質が上がった3つの理由:

    1. 客観的な視点でバグを発見: 思い込みによる見落としを防ぐ

    2. セキュリティチェックの自動化: 知識があっても忘れる、だから自動化する

    3. 命名・可読性の客観的フィードバック: 自分には見えない問題を可視化

    完全に代替はできないが、「第二の目」として使うには十分なクオリティ。個人開発者やチームが小さいプロジェクトでは特に有効だと感じている。