AI

コードベースの定期グルーミングをAIに任せる

  • AI
  • Claude Code
  • サブエージェント
  • リファクタリング
  • コードレビュー
  • Vigilare

コードベースを週次で走査するだけのサブエージェントを立てて、1か月ほど回しています。役割は検知と報告だけで、修正はさせず、見つかったものはチケットにして直すかどうかを別で判断します。

name: code-groomer
description: 定期グルーミング担当。潜在バグ・規約違反・デッドコード・古いコメントを検知して報告する。修正はしない
tools: Read, Grep, Glob, Bash

トラッカーの週次タスクが発火し、修正権限を持たないエージェントがコードベースを走査して報告を書く。報告はそのままチケットにはならず、レビュー側が報告に書かれたgrepを打ち直して裏取りをし、そこで初めてチケットになる。次の週の走査は、そのチケットが解消されたかの確認から始まるので、ここで一巡する

PRまでに担保しきれないものが残る

変更を出すときは、その変更について説明できる状態にしてから出します。テストを足し、規約に合わせ、レビューを通す。それでも漏れるものがあります。

漏れるものには共通点があって、どれもその変更の中では正しい、ということです。イベントを購読して解除を書き忘れても、その機能は動きます。撤廃した仕様の説明がコメントに残っていても、コードは正しく動きます。参照されなくなったファイルは、消し忘れても誰も困りません。変更単位のレビューは変更の妥当性を見るので、こういうものは原理的に視野の外にあります。

人間だけで書いていた頃も同じで、だから定期的にリファクタの時間を取っていました。同じことをAIにやらせているだけ、というのが今回の話です。

修正させない

最初に決めたのは、このエージェントに修正させないことでした。ツールの一覧から書き込み系を外し、残した Bash も grep や件数の集計に限る、とプロンプトで縛っています。

理由は2つあります。1つは、検知の質と修正の質が別物だからです。「ここが怪しい」と言うのに必要な確度と、実際にコードを書き換えるのに必要な確度は違います。同じ実行の中で両方やらせると、直せる範囲のものだけを報告するほうへ寄ります。

もう1つは、走査の結果が数十件になることがあるからです。全部直させると、レビューする側は「機械的な変更が数十件入った1つの差分」を受け取ることになります。中に1件だけ判断の要るものが混ざっていても、埋もれます。

検知と修正を分けると、報告からチケットを起票する工程が挟まります。そこで初めて「これは直す」「これは仕様なので意図をコメントに書く」「これは判断が要るので保留」の振り分けが起きます。実際、報告から起票されたものには「参照ゼロのコードをどう扱うか決める」のように、直すかどうかそのものが論点のものが混ざります。

「0件」と「未走査」を分けさせる

報告の形式でいちばん効いているのは、走査したうえでの0件と、走査していないので分からないものを、必ず書き分けさせることです。

これを書かせないと、報告書の空欄が「問題なし」と「見ていない」のどちらなのか読めません。読む側は前者に受け取るので、見ていない領域が安全だと誤解します。

実際に効いた回があります。時間の制約でエージェントが2つの観点を走査しきれず、「未走査(0件ではない)」と明記して返してきました。レビュー側でその2つを引き取って走査したところ、参照ゼロのファイルが1件見つかり、チケットになっています。空欄で返ってきていたら、その週は「異常なし」で終わっていました。

確度も同じ理由で書かせています。断定と、誤検知の可能性がある指摘を、記号で区別させる。後者には誤検知しうる根拠まで書かせます。

報告を鵜呑みにしない

運用してみて分かったのは、エージェントの報告そのものが検証対象だということです。

ある回では、報告の3件が実際には6件でした。内訳はこうです。

  • 「解消済み」と報告された項目が、実際には別の2ファイルに残っていた
  • 「意図をコメントに明記すべき」という指摘が誤検知だった。指摘された箇所には既に意図コメントが書かれていて、エージェントがそれを読み落としていた
  • 修正作業中に自分でgrepを打ったら、同じ種類の劣化があと3箇所見つかった

以来、報告に載っているgrepはレビュー側で打ち直しています。手間に見えますが、打ち直すのは報告に根拠として書かれたコマンドだけなので、数分です。

裏取りのついでに見つかることもあります。ある回は「参照ゼロのファイルを削除してよいか」を確認する過程で、ビルド設定側にそのファイルへのリンク参照が残っていることに気づきました。走査は .cs に絞ってgrepしていたので、プロジェクトファイルの参照が視野の外にありました。そのまま削除していればビルドが通らなくなっています。

偽陽性の判定にも同じ用心が要ります。動的に組み立てられる文字列キーは、リテラル検索では必ず未参照に見えます。これを偽陽性と断じるには、接尾辞の値域が定数と一致するかまで確認する必要があります。「使われているはず」で流すと、本当に余っているキーを見逃します。

増減を追えるようにしておく

走査は繰り返しタスクとして Vigilare に置いてあり、実行するたびに検知件数のサマリをそのタスクのコメントに残しています。

VigilareFloating Reminders for macOSKeep your Apple Reminders always on top with a floating window for macOS. Works in fullscreen apps, with quick actions, list filtering, and a built-in Markdown editor.

1回ごとの報告だけだと、その週に何件見つかったかしか分かりません。同じタスクにコメントを積むと、前回の指摘がどうなったかを追えます。持ち越した項目が次の回で解消を確認されたのか、それとも3週間放置されているのかが、1つの場所で読めます。

1回の走査では「参照ゼロのファイルが1件」としか出ません。履歴があると「入ってから一度も呼ばれないまま残っている」という別の情報になり、起票するときの優先度が変わります。

外部の実践との違い

AIエージェントにリファクタさせる話自体は、2026年の時点でありふれています。DevToolLab の記事が挙げているのは、コードベースをインデックスしてから重複を提案するツール群で、AIが既存のユーティリティを知らないまま似た関数を書いてしまう問題への対処です。Awesome Skillsも、エージェントが速くコードを書けるようになった以上、それが正しいか・保守できるか・十分小さいかを判断する技能のほうが重要になる、という整理をしています。

どちらも「エージェントに直させる」前提で、起動は人間が必要になったときです。今回の運用が違うのは3点あります。

一般的な運用この運用
起動必要になったとき週次の繰り返しタスク
権限修正まで検知と報告のみ
出力差分チケット

定期にしているのは、劣化が「気になったとき」に均等に溜まらないからです。気になるのは大きな変更の直後だけで、その時期はたいてい他のことで手がふさがっています。

まだ解けていないところ

走査に時間がかかる観点があり、毎回すべてを完走できていません。全キーの横断走査は手順さえ渡せば数十秒で終わることが分かったので、次はその手順をエージェント側に先に渡します。走査の速い書き方をエージェントに探させると、そこで時間を使ってしまいます。

もう1つ、報告の裏取りをレビュー側の手作業でやっているのが残っています。検知の一部は機械的に判定できるはずで、そこを削ればレビューは判断の要るものだけに集中できます。ただし「機械で落とせるものを先に落とす」という方針そのものは、検知エージェントを1つ足すのとは別の話になります。走査を増やすほど、その走査自体を誰が検証するのかという問題が同じ形で戻ってきます。