2025年12月、MetricShip リポで MetricShip構想 を実装した。AI が「実装できました」と言ったとき、それを人間じゃなくて基準で判定するためのツール。

構成(モノレポ)

  • packages/judge — YAML の判定基準を読んで PASS / BLOCK / HUMAN を出す
  • packages/collector — メトリクスを集める
  • examples/todo-app — React + Hono の例アプリ(判定を試す用)

最初は Next.js の UI(apps/ui)も付けていたけど、途中で「CLI だけでいい」と判断して UI を削除。判定結果は CLI でカラー表示(PASS=緑 / BLOCK=赤 / HUMAN=黄)に変えた。テストは Bun ネイティブに移して、judge / collector ともカバレッジ 100% まで持っていった。

判定基準を YAML で固定する

肝は、完了条件をコードじゃなくて YAML に固定すること。metricship.criteria.yaml に、項目ごとにコマンド・閾値・落ちたときの扱いを書く。

criteria:
  quality:
    type_errors:
      command: "bun x tsc --noEmit 2>&1 | grep -c 'error TS' || echo 0"
      parse: number
      lte: 0
      on_fail: BLOCK          # 1つでもあれば即マージ不可
      description: "TypeScript型エラー数(0必須)"
    test_coverage:
      command: "bun test --coverage | grep 'All files' | awk '{print $4}' | tr -d '%'"
      parse: number
      gte: 80
      warn: 90
      on_fail: HUMAN          # 通っても人間レビューに回す

項目は correctness(ビルド・ユニット・E2E)→ quality(型 / lint / カバレッジ / any 型 / console.log 残り)→ security(脆弱性 / ハードコードされた秘密)→ reliability(バンドルサイズ / P95 レイテンシ)→ maintainability(循環参照 / 巨大ファイル)の順で評価する。比較演算子は eq / lte / gte / lt / gt

判定は3段階。

  • BLOCK … 1つでもあれば即失敗(マージ不可)
  • HUMAN … 全部 PASS でも、HUMAN があれば人間レビューに回す
  • PASS … 全クリア

GitHub Actions で PR 作成時に走らせて、collector が集めた metrics.json を judge が評価し、結果を PR にコメントする。レイテンシは autocannon で計測。

学び

「作る AI」と「疑う AI」を分ける、という構想の入口は、結局 判定基準を YAML で外に出すところから始められた。基準がコードに埋まっていると毎回ブレるけど、YAML に固定すると「何をもって完了か」が常に同じになる。warn / HUMAN を挟めるので、白黒つけられない項目も握りつぶさずに残せるのが良かった。

おわり

PoC から本番への壁は、機能じゃなくて完了判定の自動化だ、というのがこのシリーズの結論。MetricShip はその回答の最初の形。判定項目はまだ増やせるし、プロジェクトごとの criteria を育てていく前提。