autoFixable: 900ルールで前段一掃
コードレビューでいちばん苛立つのは、AIレビュアーから10件のコメントが来て、そのうち4件が「import順が違う」「セミコロン抜け」「型がany」の類だった時です。読む前から答えが分かっているものにトークンを払っている。私はこれを「AIが悪い」問題だと思っていません。
「並べる順番が悪い」問題です。
linterが2秒で片付けられるものを、AIより先に走らせていないだけです。
3層モデル: linter → AI → 人間
レビューには少なくとも3つの層があります。
層ごとに1コメントあたりのコストが違うのに、日本のチームは全部を2層目 (AI) か3層目 (人間) に流し込む癖があります。
| 層 | 1コメントの原価 | 得意なこと |
|---|---|---|
| Linter autofix (Biome/ESLint/Ruff) | ほぼ0円、2秒 | フォーマット、未使用import、any混入、順番 |
| AI (CodeRabbit / 自作エージェント) | tokenと待ち時間 | コンテキスト依存のバグ、命名、局所パターン |
| 人間 | 給与とアテンション | 設計、trade-off、プロダクト判断 |
AIに全部投げるのは、5年前まで「セミコロンの抜けを人間レビュアーが指摘する」問題を笑っていたのと同じ構図です。
ドルに変わっただけ。
autoFixableパターンとは「linterが直せるものにラベルを付けて、AIレビューの前に強制的に処理する」型です。
ch12の中心概念で、3層モデルの土台になります。
2026年時点の「autoFixable」の広さ
「linterで直せる範囲」は2年前と別物になっています。
私が普段触る3つを並べると、収録ルール数がざっと900+/300+/200+の帯にあり、そのうち機械修正が効く割合も無視できない大きさです。
- Ruff 0.11+ (Python): 900+のルール が入っていて、公式ドキュメントに「autofix可能」を示す🛠️マークが付いています。おおよそ半分がautoFixable。flake8 + isort + black + pylintが1バイナリに畳まれ、単体テストより速い
- Biome 2.x (JS/TS/JSX): 200+のネイティブルール で、大半がautoFixable。ESLint + PrettierをRust製の1バイナリに置き換える設計
- ESLint (legacy JS/TS): 300+のコアルール + プラグインで生態系は最大だが、autoFix率はプラグイン依存。Biomeが後発として整理し直したのは、この「自動修正の一貫性のなさ」が理由の1つ
Ruffの900という規則総数と、そのうちおおよそ半分が「機械修正で人間の判断を挟まず片付けられる」側にあるという事実が、2026年時点のautoFixable領域の広さを表しています。
ここを人間やAIが目視で拾っている現場は、そのぶんレビュー予算を溶かしている。
分類: autoFixable と non-autoFixable
autoFixableパターンを実装する前に、「機械が直せるか / 人間の判断が要るか」の分類を明文化します。
ch12ではこう並べました。
autoFixable (機械が最終判断できる)
| 問題 | ツール | 判定根拠 |
|---|---|---|
| フォーマット | Prettier / Black / Biome | 出力が一意 |
| import順 / 未使用import | eslint-plugin-import / Ruff I001 / TS organizeImports | 決定論的な並べ替え |
| 単純な型キャスト | TypeScript strict + --fix | 推論可能 |
any の指摘 | Biome noExplicitAny / ESLint no-explicit-any | 場所は機械が指せる (修正は人間) |
| 命名規則の整形 | @typescript-eslint/naming-convention | 決められた表記に寄せるだけ |
non-autoFixable (人間の判断が要る)
| 問題 | 理由 |
|---|---|
| 設計の問題 | 正解が一意でない |
| N+1問題 | ビジネスロジックへの副作用がある |
| 命名の「良さ」 | コンテキスト依存 |
| ロジックのバグ | 仕様理解が要る |
ここで大事なのは、「any の指摘」がautoFixable側にあることです。指摘する場所は機械が指せるが、そこにどんな型を入れるかは人間が判断する——という切り分けを崩さない。
CodeRabbitがanyの場所を指し、私はどう直すかを決めるだけになります。
実装: PR時にlinter先行の2ゲート
私の運用は「linterを人間の目に触れる前に2回走らせる」です。
Gate 1: pre-commitフック (ローカル、2秒)
ruff check --fix か biome check --write をpre-commitに入れる。開発者が忘れてもフックが走る。ここで機械修正の90%は消えます。
commitする時点でPRから外れているので、AIも人間も見ることがない。
Gate 2: GitHub Actionsの autofix.yml (CI、〜30秒)
PRが開いた時点でCIが --fix を走らせ、差分があれば自動commitして返す。
ローカルフックを回避した場合の受け皿。
# .github/workflows/autofix.yml
name: Auto Fix
on:
pull_request:
types: [opened, synchronize]
jobs:
autofix:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}
token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
- run: npm ci
- run: npx biome check --write .
- name: Commit if changed
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git diff --quiet || (
git add -A &&
git commit -m "chore: autoFixable" &&
git push
)
commitメッセージを chore: autoFixable に固定しておくと、後から「機械修正だけの差分」を絞り込めます。
ここのラベル一貫性がフィードバックループの起点になります。
Gate 3: AIレビュー (CodeRabbit / Claude) Gate 1, 2を通過したdiffだけがAIに届く。
AIは形式の指摘に時間を使わなくてよくなり、コンテキスト依存の指摘に集中できます。
「AI Slop」がレビューコメントに現れる問題
autoFixableパターンを入れる副次的な理由が、AIレビュー特有のノイズを減らすことです。
AIレビュアーは、フォーマットやimport順の指摘を 丁寧な文章で長文化する 癖があります。「このimportの順序について、以下の点を検討してください: 1. …」という体の指摘が10件並ぶと、本命のバグ指摘が埋もれる。Gate 1で消してあれば、AIに「これは書かないで」を教えなくても、そもそも見せていないので何も書きません。
これは ChatGPT Codex vs Claude Code で私が測ったコスト差の話とも接続していて、47PRの中に「AIが形式コメントを吐いた」ぶんが混ざっていました。autoFixableをGate 0側に持ってくると、そのぶんの token 消費が最初から発生しない。
non-autoFixableをAGENTS.mdに還元する
3層モデルの残り半分は「AI/人間が拾ったnon-autoFixable指摘を、次回に活きる形に戻す」です。ch13の「フィードバックループ」の話ですが、ここでは要点だけ:
- レビューで同じ指摘が2回続いたら、AGENTS.md か CodeRabbit の設定に書く
- 書けたら次回からAIが同じ指摘を「先手で」拾う
- 3ヶ月続けると、autoFixable側に押し上がる項目が出てくる (例: 「controllerに認証チェックを直書きしない」→ ESLint custom rule として書ける形になる)
autoFixableは「今、機械が直せるもの」の集合ですが、この境界は動きます。
1回目は人間の指摘、2回目はAGENTS.mdの記述、3回目はlinter ruleに落ちる——という降格ループを回すのが、autoFixableパターンを型として活かす道筋です。
まとめ
autoFixableパターンは3つの分離で成立します。
- 層の分離: linter (原価0) / AI (token) / 人間 (給与) を混ぜない
- 判断の分離: 「場所を指す」と「どう直すか」を切って、機械側は場所だけ担当
- 時間の分離: pre-commit → CI → AIレビュー → 人間レビュー の順に走らせ、上位ほど原価の低い層に押し下げる
Ruffの900ルールもBiomeの200ルールも、この分離のためにあります。
分離せずにAIレビュアーに全部投げると、AIが「機械の仕事」を「言葉で説明する仕事」に変えてしまい、レビューが往復するばかりになる。
Claude Codeで実装するAIコードレビュー — 3層モデルとautoFixable では、この3層モデルの全体像とGitHub Actions/CodeRabbit/AGENTS.mdの具体実装を、Next.js + TypeScriptのリファレンスプロジェクトで通しで解説しています。
ch12がautoFixableの型定義、ch13がAGENTS.mdへの還元ループの実装です。
関連書籍 AIコードレビューを仕組み化する技術 AIコードレビュー 自動化 | hooks 設計・CodeRabbit 導入・Conventional Comments・GitHub Actions パイプライン 書籍ページを見る → この記事は役に立ちましたか?