ハーネスで縛れ、AIに任せろ ーAIエージェントの出力品質は“構造”で守る

AIコーディングエージェントによって、実装のスピードは確かに上がりました。設計し、試し、修正する。その試行回数を増やせることは、AI駆動開発の大きな価値です。
一方で、コード品質のばらつきや設計の揺れといった課題も見えてきました。そこで私たちは、AIの出力品質を人の注意力ではなく、構造で支える仕組みとして「ハーネスエンジニアリング」を導入しました。本記事では、その実践内容を紹介します。

はじめに

こんにちは。GMOインターネットの平野です。

ConoHa VPSではMCP(Model Context Protocol)サーバーを、Claude Codeを活用したAI駆動開発で構築しています。この開発スタイルをしばらく続けてきて、AI コーディングエージェントに実装の多くを任せ、開発スピードはたしかに上がったと実感しています。

これは単に人間がコードを書く量が減る、という話ではなく、設計して、試して、修正する。その往復が速くなり、試行回数を増やせるのが大きいと感じています。

一方で、運用を続けるうちに、見過ごせない課題もはっきりしてきました。AIが出力するコードの品質に、どうしてもばらつきが出でしまいます。ファイルごとに実装パターンが少しずつずれたり、命名規約に揺れが出たり、アーキテクチャ境界を越えたimportが紛れ込んだりする。しかも、そのズレを最後に拾うのは、PRレビューをする人間の注意力でした。この状態だと、AIに任せるほど開発は速くなる一方で、品質保証のしわ寄せが人間に集中してしまいます。

そこで、AIの出力品質を人の頑張りではなく、構造で担保する仕組みを整えました。そのベースに置いたのが、ハーネスエンジニアリングという考え方です。この記事では、その実践内容を紹介します。

ハーネスエンジニアリングとは

ハーネスエンジニアリングは、AI コーディングエージェントを“自由に走らせる”のではなく、守るべき制約を明示し、逸脱したら検知・修正・停止できるようにする考え方です。名前のとおり、「手綱(harness)」のメタファーに近いものです。

中心になるのは、次の 3 つです。

  • コンテキストエンジニアリング: AIに「何を守るべきか」を正しく伝える
  • アーキテクチャ制約: 不変条件を機械的に検証し、違反をブロックする
  • ガベージコレクション: ルール体系そのものの劣化を検知し、鮮度を保つ

この考え方を、「ドキュメント → AI セマンティック → CI → 構造テスト」という 4 段階のエスカレーションラダーとして実装しました。現在は、12 カテゴリ・48 ルールをこの体系で管理しています。

カテゴリー内容ルール数
Aファイル構造3
Bクライアントモジュール6
Cスキーマ4
Dレスポンスフォーマッター5
Eテストファイル6
FJSDoc3
Gインポートルール4
H命名規則4
Iアーキテクチャ境界5
Jコード衛生2
Kセキュリティ・品質3
Lドキュメント整合性3

4段階エスカレーションラダー

このフレームワークの核になるのは、ルールの執行レベルを段階的に引き上げることです。すべてのルールは、まずL1のドキュメントから始めます。そのうえで、違反の頻度や、自動検出のしやすさに応じて、より強いレベルへ昇格させていきます。

最初からすべてをCIやテストに押し込むわけではありません。まずは言語化し、繰り返し問題になるものだけを、より強い執行手段へ移していく。この段階設計が、実際に回る仕組みをつくるうえで重要でした。

L1: ドキュメント: すべてのルールの出発点

最初の段階では、ルールを15個のパターンファイル(harness/patterns/*.md)に分けて定義しています。各ファイルには YAML フロントマターを持たせ、enforcement-levelrelated-rulesといったメタ情報も一緒に管理しています。つまり、ルールを単なる読み物として書くのではなく、あとから機械的に扱える前提で整理している、ということです。

ここで大事なのは、「何を守るべきか」を曖昧にしないことです。AIに品質を求める前に、人間側が品質基準を明文化しておく必要があります。地味に見える作業ですが、ここが曖昧だと、その先の自動化はどこかで破綻します。

L2: AI セマンティック: AIの判断力を執行に使う

機械的に判定しづらいルールは、AI のセマンティックな理解を使って執行します。

  • 開発時(予防): CLAUDE.mdにルールを記述し、Claude Codeが開発中に参照する
  • PR時(検知): Claude Code Review CIが差分をレビューし、違反を指摘する

このレベルの強みは定量化しにくい品質基準まで扱えることです。

たとえば、「APIレスポンスは、利用者が次のアクションを判断するのに必要な情報だけを返す」「エラーメッセージには、何が起きたかだけでなく、次にどうすればよいかも含める」といった基準です。こうしたものはlintや単体テストでは扱いづらい一方で、実際の使い勝手には大きく影響します。

だからこそ、これらを単なる“書き方の好み”で片づけず、品質基準として AI に共有しておくことが重要になります。

L3: CI ツール: 機械的に検出できるものは止める

違反が繰り返し発生し、しかも機械的に検出できるルールは、CI に移して自動でブロックします。

ツール検出対象CI種別
Biomeフォーマット・リンティングblocking
dependency-cruiser循環依存・アーキテクチャ境界blocking
knip未使用ファイル・未使用エクスポートblocking
npm audit高リスク脆弱性blocking
jscpdコード重複advisory
strykerミューテーションスコアadvisory

ここでは、違反時にマージを止めるblockingと、改善の参考情報として扱うadvisoryを分けています。
この線引きは、現場で運用するうえで意外と重要です。今すぐ直さないといけないものと、継続的に改善していくものが混ざると、だんだん全部がノイズになってしまうからです。

L4: 構造テスト: アーキテクチャの不変条件を固定する

最上位のL4では、architecture.test.tsに23個のアーキテクチャ不変条件をVitestで実装しています。npm testを実行するだけで、たとえば次のようなプロジェクト固有ルールを検証できます。

  • ファイル名が命名規約に従っているか
  • スキーマ定義に.strict()が付いているか
  • エクスポート関数がcamelCaseに従っているか

ここまで来ると、ルールは「読めばわかるもの」ではなく、破ったらテストが落ちるものになります。レビュー担当者の気づきに頼るのではなく、構造として守られる状態をつくれるのが、このレベルの大きな価値です。

開発フローの中で効かせる: Claude Code Hooks

4 段階のラダーは、主に CI やテストで効く仕組みです。ただ、実際に運用してみると、それ以上に効果を感じたのは、CIに届く前のローカル開発段階でもルールが作用することでした。そこでClaude Codeの Hooksを使い、3つのガードを設定しています。

Hookタイミング役割
harness-guardファイル編集前ハーネスファイル編集時に「Architecure Decision Record(ADR)の作成が必要かもしれない」と警告
biome-autofixファイル編集後Biomeの自動修正を即時適用
Stop promptAI作業完了時typecheck/testの実行漏れやKDR検討漏れを確認

これによって、AIがコードを書いた直後にフォーマットが整い、作業を終えようとした時点でテスト実行漏れも指摘されます。CIで落ちてから気づくのではなく、開発ループの中でその場で修正される。この即効性は、実際に回してみるとかなり効きました。

昇格の判断と実例

ルールを上位レベルへ昇格させる最終判断は人間が行います。ただし、その判断材料の収集は自動化できると考えています。

現在実装を進めているのが、Claude Code Review CIが付与するpattern-violation:*ラベルを週次で集計し、3回以上検出されたL2ルールについてGitHub Issueを自動作成するエスカレーショントラッカーescalation-tracker.yaml)です。これが稼働すれば、「このルールはL3に上げるべきか」「構造テストにすべきか」を、開発者がデータに基づいて判断しやすくなります。判断の経緯は、Architecure Decision Record(ADR)として残す運用を想定しています。

実例をひとつ挙げると、プロジェクト初期にはCODING_PATTERN.mdという 681 行の単一ファイルでルールを管理していました。しかし、この形だと AI がコンテキストとして読み込むコストが高く、メンテナンスもしづらい。そこで16個の独立したパターンファイルに分割し、それぞれにメタデータを付ける設計へ移行しました。

これは単なるファイル整理ではありません。AIが参照しやすく、人間も保守しやすいルール体系へ作り直した、という意味で大きな転換でした。

エントロピー管理: ルールは書いて終わりではない

ルールは、一度作れば終わりではありません。むしろ時間がたつほど、現場に合わなくなったり、形骸化したり、守る意味が薄れたりします。放っておくと、品質を守るための仕組みそのものが、現場の負債になっていきます。

そこで現在、週次のエントロピースキャンを GitHub Actions で定期実行する仕組みの導入を検討しています。具体的には、次のようなチェックを計画しています。

  • パターン鮮度チェック: 各パターンファイルの最終レビュー日を90日の閾値で確認する
  • 依存関係ドリフトの検出: npm auditknipdependency-cruiserを PR 時以外にも定期実行する
  • 違反検出時の自動起票: 問題をGitHub Issueに起票し、対応漏れを防ぐ

また、このフレームワークがどう変化してきたかは、Architecure Decision Record(ADR)として残しています。エスカレーションラダーを導入した理由、L3ツール群の選定基準、どのルールをどのタイミングで昇格させたのか。そうした判断の背景まで残しておくことで、運用が属人化しにくくなります。

仕組みを続けるうえで大事なのは、「良いルールを作ること」だけではありません。そのルールが今も有効かを見直し続けることだと考えています。

まとめ

AI 駆動開発で品質を担保するうえで大切なのは、AI を過度に信用することでも、逆に必要以上に疑うことでもありません。AIが守るべき制約を人間側が設計し、その制約を段階的に執行できるようにすることです。今回紹介したハーネスエンジニアリングの要点は、次の3つに整理できます。

1. ルールは段階的に強くする

最初はドキュメントとして言語化し、必要に応じてAIレビュー、CI、構造テストへと昇格させる。こうすることで、運用コストと実効性のバランスを取りながら、ルールを育てていけます。

2. 定量化しにくい品質も扱う

Taste Invariantsのような基準を言語化して共有しておくことで、機械的な検証だけでは拾いにくい品質も扱えるようになります。使いやすさやわかりやすさのような価値は、こうした層で効いてきます。

3. ルールそのものも保守対象にする

週次スキャンやArchitecure Decision Record(ADR)を通じて、ルールの鮮度と判断の背景を継続的に管理する。これをやらないと、どんなに立派な仕組みも、時間とともに形だけのものになってしまいます。

今後は、Claude Code Review CIで検出された違反ラベルを集計し、昇格候補のルールを自動で見つける仕組みや、エントロピースキャンで見つかった問題を自動修正につなげるワークフローも整えていく予定です。

AIコーディングエージェントは、これからさらに進化していくはずです。だからこそ、それを支える“手綱”の側も、固定されたルールとして置いておくのではなく、実際に使いながら育てていく必要と考えています。

ConoHa VPS MCPサーバー はこちらからご利用できます。

ConoHa VPS MCPは、ConoHa VPSの公開API日本語で簡単に操作できるオープンソースのModel Context Protocol (MCP) サーバーです。Claude Code、GitHub Copilot、ClineなどのAIエージェントと連携することで、自然言語によるVPS・オブジェクトストレージの操作が可能になります。ぜひ使ってみてください!

ブログの著者欄

平野 空暉

システム本部

入社以来、ConoHa・お名前.comにおけるAI関連の企画・開発に従事。生成AI関連のサービスを複数手がけるほか、社内開発におけるAIネイティブな開発スタイルを提案・実践中。プロトタイプ開発やフロントエンドの UX 改善、パフォーマンスチューニングに特に関心を持つ。

採用情報

関連記事

KEYWORD

TAG

もっとタグを見る

採用情報

SNS FOLLOW

GMOインターネットグループのSNSをフォローして最新情報をチェック