AIと人間が使うDartメトリクスツール dartrics
はじめに
GWに思い立ったので、AIによる・AIの・AIのためのツールを作ってみました。
https://pub.dev/packages/dartrics
日に日に、AIエージェントが記述するコードの量が増えつつあります。便利だなと思う反面、検討しなければならない話題も増えてきた印象です。特にAIエージェントには周囲のコードを参照モデルとして取り込む癖があるようで、良い結果になる時もあれば、その逆になる時もあります。
そのほか、レビュープロセスなどを考えると、AIが「終わりました」とコードを提出した時のコードの質が重要です。現時点では、ここから複数回の往復を行うのですが、初手が悪いとまるっと書き直しを依頼することもあります。書き直しを依頼するとなんとかなることから、AIが各コードの質を保つ工夫があれば、AIエージェントが自身のコードを評価してチェックした上で、より良いものが出されるのでは? と考えていました。
GW中にあれこれ試していて思いついたのが、AIに周囲のコードではなく外部の固定された基準を渡すという発想です。基準を外部に置ければ、過適合の方向を一段抑えられるはずです。
dartricsは、この枠組みを学術的なメトリクスに置くことで、2026年現在でも簡単かつ実践的に運用できるツールを作る試みになります。
この記事では、なぜ作ったのか、どのような設計にしたのか、そしてどう使うのかを紹介します。
dartrics
dartricsはDartやFlutterプロジェクト向けのコード解析CLIです。analyzer パッケージを土台に、複数のメトリクス計算と未使用public APIの検出を提供します。具体的な設計の柱は次のセクションで掘り下げます。
Claude Codeをはじめ、AIエージェントが自律して動作するのが当たり前になってきました。このとき、AIエージェントがコード分析やセルフレビューにおいて、コードに対する評価を複数の観点から得られれば、適切に組み合わせて判断がなされるはずです。
この仮説に基づき、CLIとして完結するように設計し、またAIエージェントに追加のガイドなしで利用できるようにしました。
dart pub global activate dartrics
これでインストールできます。続けて「
dartricsを使って不要コードの候補を検出し、削除が妥当な箇所を対応して」のように指示を出すと、そのまま実行される、というのが想定する利用シーンです。人間が直接叩いても、AIエージェントに渡しても同じように動くCLI、それが
dartricsの立ち位置です。
特徴の紹介
dartricsは全く新しいツールではありません。メトリクスを測るというカテゴリ自体には、何十年もの蓄積があります。ただし、既存のツール群が人間を一次読者として設計されてきたのに対し、
dartricsはAIエージェントを一次読者として作り直した点が違います。以下、三つの柱に分けて説明します。
柱1: AI-firstで設計する
dartricsの主たる利用者はAIエージェントです。もちろんCLIとして人間が直接使っても便利なのですが、設計判断はAIに渡したときに筋が良いかどうかを判断の軸にしています。
mobile-firstや
API-firstと同じ意味での、AI-firstなメトリクスツールです。
この方針には、もう一つの含意があります。CLIを賢く作る方向には進まない、という選択です。
メトリクスツールの世界には「ツール側がもっと賢ければ違反を自動で直せるはず」という発想があります。
dartricsはその方向を取りません。代わりに、結果を解釈可能な形で出すことに振り切ります。コードの判断は、CLIよりも"知性"に近いAIエージェントに委ねるべき、という立場をとっています。
これは、AIエージェントの性能と性能の伸びに重きを置く判断です。そして、
dartricsは出力フォーマットを利用者別に分けて用意しています(後述の
--reporter)。AI向けには
ai(トークン効率重視のYAML系)、人間向けには
mdや
console。利用する主体ごとに最適なフォーマットを渡すことが、自律したAIエージェントの動作と噛み合う、という狙いです。
柱2: 「正しいAST」を土台にする
もう一つの柱が、コンパイル時と同等のASTでメトリクスを測ることです。具体的には、Dart公式の
analyzerパッケージを使い、
dart analyzeやIDEと同じASTを参照しました。
メトリクスを「それっぽく」測るだけなら、正規表現や簡易パーサで切り抜けることもできます。が、これだと、
- ジェネリクスやnamed parameter、
switch
式といったDartの新しい構文に追従できない - メソッド境界の判定が曖昧で、メソッド長や複雑度が実態とズレる
- 未使用コードの検出が信用できない
という問題に当たります。逆に、コンパイル時と同等のASTを使えば、これらは原理的にズレません。
特に効くのは、未使用検出への影響です。
analyzerは名前解決まで含めた完全なASTを提供してくれます。これは「ある関数/クラスがどこから呼ばれているか」を、コンパイラと同じレベルで判定します。未使用コードを取り除いた上で各種メトリクスを測れるので、結合度や複雑度の数字が「生きているコードに対する数字」として信頼できます。[1]
dartricsが出力する情報の正しさは、この正しいASTという土台に支えられています。
柱3: メトリクスを学術文献にアンカーする
最後の柱が、各メトリクスを必ず原典となる学術文献に紐付けることです。Cyclomatic ComplexityならMcCabe (1976)、Cognitive ComplexityならSonarSource (2017)、LCOM4ならHitz & Montazeri (1995)、結合度ならCK (1994)、不安定度ならMartin (1994)、Halstead VolumeならHalstead (1977)、といった具合です。
手元でドッグフーディングすることで確かめたのですが、現時点のAIは、適切な指示を与えないとメトリクスの定義や閾値の根拠をトレーニングデータからハルシネーションしてしまうというケースがあります。
dartricsは各違反のrationale・refactor hints・出典を出力に同梱することで、AIが「Cyclomatic Complexityとは何か」「なぜ閾値10なのか」を改めて検索する必要をなくしています。出典を引用することで、AIのハルシネーションを防ぐ。同時に、人間側が「AIエージェントの判断がどの文献に基づくか」を後から検証できる。この二つの効果を狙っています。
ただし、文献上のメトリクスをすべてDartに適用するのが妥当とは限らないため、採用するメトリクスや閾値については個別に調整しています。経緯はリポジトリの
doc/calibration.mdにまとめているので、運用時に気になったらご確認ください。
この学術文献の整理を含め、
dartricsの設計と実装の多くにAIエージェントを使っています。各メトリクスの原典追跡、出典監査、削除判断、コードの大部分の記述まで、人間が「何を達成したいか」を提示し、AIエージェントが実作業を回す体制で進めました。[2]
dartrics
の工夫
三つの柱は、AIエージェントとCLIの出力の反復の中で噛み合うように設計されています。AIがCLIを叩いた結果は、AIが読める形式で(柱1)、正しいASTに基づく違反として(柱2)、学術文献の根拠付きで(柱3)返ってきます。AIはこの返り値だけで判断し、次のCLI呼び出しに繋げる。柱は単独でも機能しますが、このループの中ではじめて全部の意味が立ち上がります。
以下、その反復ループを成立させるために工夫した実装上のポイントを紹介します。
IDによる問題箇所の特定
違反には、実行をまたいで安定したIDが振られます。これにより「前回の実行で出た違反のうち、どれが直って、どれが残ったか」を機械的に追跡できます。
AIエージェントを利用した開発は、単発では終わらなくなっています。日々のサイクルで、コードが追加され、また削除されていきます。このループを回すうえで、メトリクス結果のうち「どの指摘がどこを指していたか」を特定する必要が生じます。安定したIDは要となる設計です。[3]
出力フォーマット
柱1で触れた通り、出力は読み手別に最適化したものを用意しています。入口は
--reporterで切り替えます。
| reporter | 想定読者 | 用途 |
|---|---|---|
ai |
AIエージェント | LLMへのパイプ。トークン効率を意識したYAML系 |
console |
人間 | ターミナルでの対話的な利用 |
md |
人間 | PRコメントやドキュメントへの貼り付け |
sarif |
機械 / レビューUI | GitHub ActionsのCode Scanning連携 |
json |
機械 | 自前のダッシュボードへの流し込み |
AI向けフォーマット(
--reporter ai)は、JSONより冗長性が低く、トークン効率を最優先したYAML系の出力になります。LLMの文脈窓に多くの違反を詰め込めるよう、装飾は最小限にしました。実際にClaude Code(Opus 4.7)などに渡してみると、整形スクリプトを挟むことなく、違反のID・rationale・refactor hintsをそのまま解釈してくれます。
なお、人間向けやgit管理向けの出力フォーマットについては、まだまだ改善の余地を感じています。もしも「こういう形で、出力を利用したい」というものがあれば、Issueにてご意見をお寄せください。
未使用public APIの検出
dartrics unusedサブコマンドとして、未使用public APIの検出も提供しています。公開APIとして定義されているが、内部からも外部からも参照されていない、というコードを拾う機能です。
dart fixや
unnecessary_*系のlintでは拾えない領域で、特にライブラリ開発時に重宝するはずです。
人間が直接使ったときに一番「便利」と感じやすいのは、おそらくこの機能でしょう。というのも、未使用コードを地道に探すのはそれなりに骨です。CLIで未使用コード(の候補)をリストし、個別にチェックすることで、その手間を大きく省けます。
filterオプションなども用意してあるので、気になる方はオプションを確認してみてください。
使い方
インストールと解析
dart pub global activate dartrics dartrics analyze lib/
Claude Codeなどに渡したい場合は、AI向けフォーマットでパイプもできます。
dartrics analyze lib/ --reporter ai | claude -p "Refactor violations"
出力はそのままLLMが理解できる形式なので、整形スクリプトを挟む必要がありません。
リグレッション解析でループを閉じる
リファクタリング後に改善を確認するには、
regressionサブコマンドを使います。
dartrics regression --before HEAD~1 --after HEAD --reporter ai
analyze→ AIに修正させる →
regressionで差分を確認、というループがコマンド一つで回せます。作成されたコミットが本当に改善になっているのか? より改善したほうが良いものではないのか? こうしたチェックは人間が手で叩いて確認するのにも使えますし、
regression実行をルール化してコード生成プロセスに組み込むこともできます。
設定
analysis_options.yamlで閾値や対象の調整ができます。
dartrics:
metrics:
cyclomatic-complexity:
warning: 10 # デフォルト10
method-length:
enabled: true # デフォルトoff、明示的に有効化
exclude:
- "lib/generated/**"
設定可能なキーの完全な一覧は、リポジトリの schemas/dartrics-config.schema.json に定義してあります。
IDE / dart analyze
への統合
CLIだけでなく、analyzer pluginとしても提供しています。
analysis_options.yamlに以下を書いてanalysis serverを再起動すると、IDEや
dart analyze上で軽量な3ルール(Cyclomatic Complexity、Cognitive Complexity、Number Of Parameters)がインラインの警告として表示されます。
plugins: dartrics:
重いメトリクス(LCOM4、CBO、RFC、Martin系の結合度)と未使用public APIの検出は、プロジェクト横断のインデックスが必要なため、CLIに限定しています。コードを書きながらIDE側で軽い違反を拾い、深い分析や未使用検出はCLIで行う、という二段構えの使い分けをサポートします。
同梱ドキュメント
メトリクスの定義やAIループの組み方は、CLI内に同梱しています。
dartrics manual # メトリクスの定義と解釈 dartrics ai-loop # AIエージェントとの組み合わせ方 dartrics rules # 有効なルール一覧と閾値
CLIに同梱することで、AIエージェントが自動的にドキュメントを読み、CLIを実行するようになります。
作ってみて一番感動したのが、ドキュメントを同梱できたことでした。AIエージェントがGitHub検索もせず、ただCLIにある公式ドキュメントを読んでそのまま処理に入る――この導線をツール側から提供できることに、AI時代のCLIならではの価値があると考えています。
その他のサブコマンド
ここまで触れたもの以外に、次のサブコマンドが用意されています。
dartrics unused # 未使用public APIの検出 dartrics report # 解析結果のJSONから別フォーマットへの変換 dartrics doctor # 環境チェック
dartrics --helpで一覧を確認できるので、気になった方はぜひご確認ください。
そのほかの研究
Dartでうまくいったので、ほかの言語でも試してみたくなりました。Opusに頼んで作ったRust版を触ってみた結果、なんか動くものは出来つつあります。AI-firstなCLIデザインとASTベースの解析という設計はDart固有ではない――これが現時点での結論です。
https://github.com/koji-1009/cargo-rustics
Rust側の実装で気付いたことをDart側に反映する局面も多く、共通のアイデアを複数言語で試すのは有意義でした。ドッグフーディングの対象も2つになりますしね。
筆者はRustに不慣れなため、
cargo-rusticsのリリースはしていません。あくまでコンセプトの輸出可能性をチェックする実験です。処理時間はDart版より遅くなっているのですが、それでも動いている、という事実そのものを成果と捉えています。Rustの利用シーンも広がりそうなので、こちらも今後深めていく予定です。言語的な特徴をあれこれ調べるきっかけにもなり、大変面白いです。
おわりに
dartricsは判断をAIエージェントに委ねることを前提に設計した道具です。
2026年5月現在のAIエージェントには、Dart/Flutter領域でのブレと、周囲のコードを参照モデルとして取り込む癖が残ります。
dartricsは、そこにツール側から文脈の質を補強する道具です。AIのパフォーマンスが上がれば、この補強もより効くようになるのではないか。今後のAIエージェントの性能向上に賭けている、そう表現しても良いはずです。
まだまだ活発に更新中のツールです。フィードバックやIssueはいつでも歓迎です。ぜひ試してみてください。
https://pub.dev/packages/dartrics