木曜日, 7月 31, 2025
木曜日, 7月 31, 2025
- Advertisment -
ホームニューステックニュースモジュールを外から見た振る舞いだけAIレビューさせる smoke-review

モジュールを外から見た振る舞いだけAIレビューさせる smoke-review



来週から Claude Code に 5 時間レートリミットではなく Week Limit が導入されるみたいです。辛いですね。

というわけで、元々考えてたコンテキスト消費を少なくするテクを実装してみました。

リポジトリはここで、主に .claude の下に色々おいてあります。

https://github.com/mizchi/subagents-smoke-review-poc

tl;dr

  • 動いている前提で公開 API とテストケース一覧を AI にレビューさせる
  • .claude/agents/*-reviewer.md を置いて、レビュータスクをここに書いていく
  • .claude/commands/smoke-review.md をオーケストレーターとして reviewer を並列で発火させる

    • *-reviewer の Agent を並列に起動して、コードをレビューしてください

最小ケース

$ git clone https://github.com/mizchi/ts-starter-with-smoke-review myproj
$ cd myproj
$ claude
> /smoke-review

動機: 実装バイアスを排除したい

モジュールやライブラリを実装してると必ず直面するのが実装者バイアスです。

実装者はついつい実装を知りすぎているために、中の都合を外に露出してしまいます。

人間だけではなく AI もこの傾向が強く、実装したものはすべて export してしまう傾向が強いです。

export * from "./core";
export * from "./utils";
export * from "./internal-methods";

ここで使えるのが、TDD の Red/Green/Refactor サイクルで、実装バイアスを排除するのに優れたワークフローです。

モジュールの振る舞いがこうあってほしい、というのを先に宣言して、実装をそれに寄せていきます。

function calc() {
  
}

it("calc() は 42 を返す", () => {
  const expected = 1;
  const output = calc();
  expect(output).toBe(expected);
});

Smoke Testing の概念

Smoke testing (software) – Wikipedia

動いているときのインターフェースとテスト一覧をレビューさせるというのは、多分 API Review とかそういう概念のが近そうなんですが、あんまり該当する概念がなくて 一旦 Smoke Review と命名します(もっといい概念があったら教えてください)

要はあえて詳細実装を渡さずにモジュール利用者視点でレビューさせつつ、トークンの節約とワークフローの高速化を目指してみます。

ライブラリユーザー視点で型定義だけレビューさせる

型定義だけ API に食わせたいです。例えば typescript で rolldown-plugin-dts を使うと、型定義ファイルを一つにバンドルすることができます。

(実装方法はこれ以外にも色々あります)

https://github.com/sxzz/rolldown-plugin-dts

import { dts } from "rolldown-plugin-dts";
export default {
  input: "./src/index.ts",
  plugins: [dts()],
  output: [{ dir: "dist", format: "es" }],
};

あなたは実装を知りませんが、これで生成された型定義ファイルがこれです。


type Rect = {
  x: number;
  y: number;
  width: number;
  height: number;
};
declare function calculateAreaDifference(a: Rect, b: Rect): number;
type SimilarityResult = {
  firstIndex: number;
  secondIndex: number;
  similarity: number;
};
declare function calculatePairwiseSimilarities(
  rects: Rect[]
): SimilarityResult[];

export {
  Rect,
  SimilarityResult,
  calculateAreaDifference,
  calculatePairwiseSimilarities,
};

座標計算を行うライブラリのように見えます。ライブラリユーザーは、結局この単位でライブラリの使い方を確認するはずです(よね?)

例えば zod の使い方を知ってる人は多くても、 zod の実装まで確認する人は少数のはずです。

外からみたモジュールとしての完成度は、内部実装とは別に、公開 API の完成度からレビューするほうが効率がいいと考えることができます。

検証 実装フェーズ SubAgent に必要なデータだけ渡してレビューさせる

やってみましょう。SubAgents を使います。

https://docs.anthropic.com/en/docs/claude-code/sub-agents

SubAgent は呼び出し元の環境を知らないので、ここから型定義のバンドル結果をレビューさせれば、実装バイアスを分離できるはずです。

とはいえコンテキストが何も無いのも辛いので、tests/のインテグレーションテストの状態も渡すことにします。

事前準備として、vitest のテスト結果だけ取り出してリスト化するスクリプトを作っておきます

.claude/scripts/get-vitest-specs.bash

#!/bin/bash


set -e


cd "$(dirname "$0")/../.."
PROJECT_ROOT=$(pwd)


TEMP_FILE=$(mktemp)
trap "rm -f $TEMP_FILE" EXIT


if [ -d "tests" ]; then
    
    npx vitest run tests --reporter=json > "$TEMP_FILE" 2>/dev/null || true
else
    
    npx vitest run --reporter=json > "$TEMP_FILE" 2>/dev/null || true
fi


if command -v jq &> /dev/null; then
    jq -r --arg root "$PROJECT_ROOT" '
      .testResults |
      group_by(.name) |
      .[] |
      .[0] as $suite |
      "\n\($suite.name | sub($root + "https://zenn.dev/"; ""))" +
      ($suite.assertionResults |
        group_by(.ancestorTitles[0] // "") |
        map(
          if .[0].ancestorTitles[0] then
            "\n  \(.[0].ancestorTitles[0])" +
            (map("\n    - \(.title) [\(.status)]") | join(""))
          else
            map("\n  - \(.title) [\(.status)]") | join("")
          end
        ) | join("")
      )
    ' "$TEMP_FILE" 2>/dev/null
else
    echo "Error: jq is required"
    exit 1
fi

こういうテスト結果を取り出せます。

tests/integration.test.ts
  Rectangle Library Integration
    - should calculate area difference for UI layout comparison [passed]
    - should handle game object collision detection preparation [passed]
    - should work with responsive design breakpoints [passed]
    - should handle floating point rectangles [passed]
    - should handle very large rectangles without overflow [passed]
    - should work with array of rectangles [passed]
    - should support functional programming patterns [passed]

というわけで、これを入力にする .claude/agents/smoke-reviewer.md のエージェント定義の例です。

---
name: smoke-reviewer
description: 公開型定義とインテグレーション命名と一覧を評価し、ユーザー視点でモジュールを評価します
color: yellow
---

このライブラリのユーザー視点でレビューします。提供されている API に対してどのようなテストケースが準備されているかを確認し、必要なテストケースの修正/追加/削除を提案します。

## 入力

1. バンドルされた公開 API(`dist/index.d.ts`)
2. インテグレーションテストの一覧: `bash .claude/scripts/get-vitest-specs.bash`

**重要**: 実装コードを参照せずに、型定義の公開 API と、インテグレーションテストのスペックのみでインターフェースを評価してください。

実行結果: どういう振る舞いになるか

という発想を元に smoke-review をするリポジトリを作ってみました。

https://github.com/mizchi/subagents-smoke-review-poc

/smoke-review というコマンドが実装してあります。

トークンを減らすという目的にはやや逆行しますが、自分の手元では三並列にします。

  • examples
  • tests
  • dist/index.d.ts

やってみましょう

/smoke-review
...

● 3つのサブエージェントを並行して実行し、ライブラリをレビュー
  します。

● smoke-public-api-reviewer(Review public API)
  ⎿  Done (2 tool uses · 17.8k tokens · 37.5s)

● smoke-examples-reviewer(Review examples)
  ⎿  Done (12 tool uses · 25.8k tokens · 2m 3.1s)

● smoke-integration-reviewer(Review integration tests)
  ⎿  Done (6 tool uses · 22.4k tokens · 55.5s)

● スモークレビュー結果サマリー

  1. 公開APIレビュー 🔴 要改善

  - APIリネームは完了したが、基本的な矩形操作機能が不足
  - calculateAreaDifference の名前は改善されたが、まだ不明確
  - 矩形計算ライブラリとして期待される基本機能(面積計算、交
  差判定など)がない

  2. サンプルコードレビュー 🟢 良好

  - calculatePairwiseSimilarities のサンプルが追加されて改善
  - 実用的なユースケースが豊富
  - ただし、類似度の計算アルゴリズムの説明が不足

  3. 統合テストレビュー 🟢 良好

  - 実用的なシナリオが適切にテストされている
  - エッジケースの基本的なカバレッジがある
  - calculatePairwiseSimilarities のより詳細なテストが必要

  総合評価: 部分的改善 🟡

  前回のレビューから以下の改善が確認されました:
  - ✅ API名の改善(calculateSurface →
  calculateAreaDifference)
  - ✅ 類似度計算のサンプルコード追加
  - ✅ SimilarityResult のプロパティ名改善(rect1/rect2 →
  firstIndex/secondIndex)

  ただし、まだ以下の課題が残っています:
  - ❌ 基本的な矩形操作関数の不足
  - ❌ 類似度計算アルゴリズムの説明不足
  - ❌ JSDocコメントによる関数の動作説明がない

  次のステップの提案:
  1. 基本的な矩形操作関数(area, intersects, contains
  など)を追加
  2. 各関数にJSDocコメントを追加して動作を明確化
  3. 類似度の計算方法についてドキュメントを追加

プロンプトキャッシュは効かないんですが、オーケストレーターに負荷を抑えて並列にプロセス分離ができました。

で、使えるの?

レビュー用エージェントを分割した感想ですが、並列化しないと遅すぎて使い物にならなかったです。

とはいえ、少なくともこれを開発してる間は一度も Opus Limit の警告を見なかったので、多少減ってるかもしれません。型定義が増えすぎたり、テスト出力結果を渡しすぎると逆に増える予感はあります。

(こういうのを作り込むとモデル更新時に大変になるので、基本作り捨ての気持ちでやっています)



Source link

Views: 0

RELATED ARTICLES

返事を書く

あなたのコメントを入力してください。
ここにあなたの名前を入力してください

- Advertisment -