本稿では、AIエージェントの出力品質は「構造」で大きく変わるという前提のもと、CLAUDE.mdの次のパラダイムとして注目される「ハーネスエンジニアリング」の概念・構成要素・導入方法を、実運用の経験を交えて解説します。
なぜハーネスが必要になったのか
半年ほど前、筆者はCLAUDE.mdだけでプロジェクトを回していました。
コーディング規約、ディレクトリ構成、技術スタックを書いておけば、AIは概ね期待通りに動きます。
最初のうちは。
問題はプロジェクトが大きくなってから出ました。
- 品質のばらつき: 同じ「APIエンドポイントを追加して」という指示でも、セッションによってファイル配置やエラーハンドリングの粒度が違う
- セッション切れの断絶: 昨日の作業の続きを頼むと、前回の設計判断を無視した実装が返ってくる
-
スキル追加の破綻:
/deploy/write-testのようなスキルを20個以上追加した結果、実行順序や前提条件の管理が手に負えなくなった - ルール違反の見落とし: CLAUDE.mdに「ドメイン層は外部ライブラリをimportしない」と書いても、守られているかは人間がレビューするしかない
つまり、CLAUDE.mdは「お願い」でしかなかったのです。
守らせる仕組みがない。
違反を検知する仕組みもない。
ルールが古くなったことに気づく仕組みもない。
GMOインターネットの平野氏も、ConoHa VPS開発で同様の課題に直面しています。AIの出力品質にばらつきが生じる問題に対し、人の注意力ではなく構造で品質を守るアプローチを採用しました。
これが「ハーネスエンジニアリング」という考え方の出発点です。
馬具のハーネスとAIのハーネス
「ハーネス(harness)」の原義は馬具です。
馬の体に装着し、騎手の意図した方向に力を伝える道具です。
ここで重要なのは、馬具は馬の脚力を削ぐものではないということです。
むしろ逆です。
馬具があるからこそ、馬は全力で走れます。
方向の制御を馬具に任せることで、馬は「走る」ことに集中できるからです。
馬具なしの馬は、どこに走るかわからない。
馬具ありの馬は、全力で正しい方向に走れる。
AIエージェントも同じです。
ハーネスなしのAIは、どんな設計判断をするか予測できない。
ハーネスありのAIは、制約の範囲内で最大限の創造性を発揮できます。
ソフトウェア開発における「テストハーネス」も同じ語源です。テスト対象の実行環境を構造的に制御し、結果を検証可能にする仕組み。ハーネスエンジニアリングは、この考え方をAIエージェントの行動制御に拡張したものです。
CLAUDE.md → AGENTS.md → ハーネス:進化の実体験
AIエージェント制御は3段階で進化してきました。
各段階で何ができるようになり、何が足りなかったのかを振り返ります。
第1段階: CLAUDE.mdの時代(2025年前半)
プロジェクトルートにCLAUDE.mdを置き、技術スタックとコーディング規約を書く。
これだけで、AIの出力は劇的に改善されました。
# CLAUDE.md
## 技術スタック
- Next.js 15 (App Router)
- TypeScript 5.x
- Prisma + PostgreSQL
## 規約
- コンポーネントは src/components/ に配置
- APIルートは src/app/api/ に配置
- 型定義は src/types/ に集約
できるようになったこと: AIが技術スタックを把握し、規約に沿ったコードを生成する。
足りなかったこと: ルールは「お願い」止まり。セッションが切れると前回の文脈が消える。複数人で開発すると、CLAUDE.mdの解釈がエージェントによって微妙にずれる。
第2段階: AGENTS.md + ルール分離の時代(2025年中盤)
CLAUDE.mdが肥大化し、1ファイルでは管理しきれなくなりました。
.claude/rules/ にルールを分離する構成が登場します。また、AGENTS.mdはクロスツールのオープン標準として策定され、エージェントに向けた指示(どのファイルを読むべきか、どのツールを使うべきか等)を宣言的に記述する仕組みです。特定ツールに依存しない点が特徴で、Claude Code以外のエージェントツールからも参照できます。
project/
├── CLAUDE.md # プロジェクト全体の方針(簡潔に)
├── AGENTS.md # エージェント向けの指示書(クロスツール標準)
└── .claude/
└── rules/
├── architecture.md # アーキテクチャ制約
├── testing.md # テスト方針
└── security.md # セキュリティ要件
できるようになったこと: ルールの関心分離。エージェントが参照するコンテキスト量を必要最小限に制御できる。AGENTS.mdにより、ツールを問わずエージェントへの指示を標準化できる。
足りなかったこと: ルールを書いても、守らせる強制力がない。セッション間の記憶が途切れる問題は未解決。スキルの実行手順がエージェント任せで、品質がばらつく。
第3段階: ハーネスエンジニアリング(2025年後半〜)
ルール定義だけでは不十分だと気づき、実行・検証・記憶の仕組みを統合します。
これがハーネスです。
| 段階 | 対象 | 制御方法 | 持続性 | 違反検知 |
|---|---|---|---|---|
| プロンプト | 単一の応答 | テキスト指示 | なし | なし |
| コンテキスト | 単一セッション | ファイル配置 | セッション内 | なし |
| ハーネス | 複数セッション | 構造的制約 | 永続的 | 自動 |
ハーネスはコンテキストエンジニアリングを置き換えるのではなく、包含します。
CLAUDE.mdもAGENTS.mdもハーネスの一部です。
それに加えて、スキル・フック・メモリ・検証ループという層を重ねたのがハーネスです。
ハーネスなし vs ハーネスあり: Before/After
同じタスク「ユーザー認証APIを追加する」を、ハーネスなし/ありで実行した場合の違いを示します。
Before: CLAUDE.mdのみ
指示: 「ユーザー認証APIを実装して」
結果:
- src/app/api/auth/route.ts にJWT認証を実装 ← OK
- パスワードを平文でログに出力 ← セキュリティ違反
- エラーレスポンスの形式が既存APIと不一致 ← 規約違反
- テストなし ← 基準未達
- 前回のセッションで決めた「認証はNextAuth.js」の方針を無視 ← 文脈断絶
5つの成果物のうち、問題なしは1つだけです。
しかも問題に気づくのは、人間がレビューしたときです。
After: ハーネスあり
指示: 「ユーザー認証APIを実装して」
実行される制御:
1. [メモリ] progress.mdから前回の決定事項を読み込み → NextAuth.js採用を認識
2. [スキル] /add-feature の手順に従い、型定義→ロジック→API→テストの順で実装
3. [フック] ファイル保存時にBiomeで自動フォーマット
4. [フック] console.logやセキュリティ違反パターンを即時検出
5. [フィードバック] タスク完了前にtypecheck + テスト実行 → 型エラー0件、テスト全パス
6. [メモリ] progress.mdを更新、次のセッションに引き継ぎ
結果:
- NextAuth.jsで実装(前回の方針を反映) ← OK
- セキュリティ要件準拠 ← OK
- エラーレスポンス形式が統一 ← OK
- テストカバレッジ基準達成 ← OK
- 進捗ファイル更新済み ← OK
違いは明白です。
ハーネスなしでは「良い出力が出ることを祈る」運用です。
ハーネスありでは「悪い出力が出にくい構造」になっています。
ハーネスの5つの構成要素
ハーネスは以下の5要素で構成されます。
1. ルール(Rules)
CLAUDE.md や .claude/rules/ に配置する行動規範です。
エージェントが従うべき制約を宣言的に記述します。
# .claude/rules/architecture.md
- src/domain/ 配下のファイルは外部ライブラリを直接importしない
- APIレスポンスの型は src/types/ に定義する
- コンポーネントは1ファイル200行以内に収める
ルールはハーネスの土台ですが、ルールだけでは「守られているか」を検証できません。
GMOの事例では、12カテゴリ48ルールを管理しています。
この規模になると、人間のレビューだけでは限界があります。
2. スキル(Skills)
再利用可能な手順書です。
/deploy /write-test のようなコマンドとして定義し、エージェントに特定の手順を実行させます。
# .claude/skills/write-test/SKILL.md
1. 対象ファイルのexportされた関数を列挙する
2. 各関数に対してVitestのテストケースを作成する
3. 正常系・異常系・境界値の3パターンを含める
4. `npm run test` で全テストが通ることを確認する
Claude Codeの最新版では、スキルの定義場所が .claude/commands/*.md から .claude/skills/<name>/SKILL.md に移行しています。新規作成の場合は .claude/skills/ を使用してください。
スキルの本質は「手順の標準化」です。
エージェントが毎回異なるアプローチを取る問題を、構造的に解消します。
「テストを書いて」という曖昧な指示が、常に同じ品質基準で実行されるようになります。
3. フック(Hooks)
イベント駆動の自動実行トリガーです。
Claude Codeでは hooks 設定で、特定のタイミングに処理を差し込めます。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/format.sh"
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "npm run test"
}
]
}
]
}
}
公式ドキュメントに基づく補足です。matcherの内側に hooks 配列を持ち、各ハンドラには type フィールドが必要です。matcherにはClaude Codeのツール名(Edit, Write, Bash 等)を指定します。Stop イベントはmatcherをサポートしません。また、hookコマンドにはstdin経由でJSON(tool_input にファイルパス等を含む)が渡されるため、フォーマッタ等の実行はシェルスクリプトでJSONをパースして処理するのが定石です。
フックの価値は、ルール違反の検知タイミングを「事後レビュー」から「即時」に変えることです。
ファイルを編集した瞬間にフォーマッタが走り、タスク完了時にテストが実行される。
人間が気づく前に、構造が違反を捕まえます。
4. メモリ(Memory)
セッション間で持続するコンテキストです。
進捗ファイル、意思決定ログ、学習記録などが該当します。
# progress.md
## 2026-03-22
- [x] ユーザー認証API実装(NextAuth.js)
- [x] JWTトークン発行・検証
- [ ] パスワードリセット機能
## 意思決定ログ
- 2026-03-20: ORMはPrismaを採用(理由: 型安全性とマイグレーション管理)
- 2026-03-21: 認証はNextAuth.jsを使用(理由: App Router対応、OAuth統合の容易さ)
## 次のセッションで対応すること
- パスワードリセットのメール送信処理
- rate limiting の追加
メモリがなければ、セッションが切れるたびに文脈がリセットされます。
前回決めた設計方針を無視した実装が返ってくる原因は、ほとんどがこれです。
メモリの形式には注意が必要です。Markdownは人間にとって読みやすい反面、エージェントが勝手にタスクを完了にする、意思決定ログを改変するといった問題が起きやすくなります。構造的な整合性を重視する場合は、JSON形式での管理も検討してください。
5. フィードバックループ(Feedback Loop)
エージェントの出力を自動検証する多層構造です。
| 層 | 検出対象 | 応答速度 | 例 |
|---|---|---|---|
| 型チェック | 構文エラー、型不整合 | 数秒 | tsc --noEmit |
| リンター | コード品質、パターン違反 | 数秒 | Biome, ESLint |
| ユニットテスト | ロジックの誤り | 数十秒 | Vitest, Jest |
| 構造テスト | アーキテクチャ違反 | 数十秒 | dependency-cruiser |
| E2Eテスト | 統合・UI不整合 | 数分 | Playwright |
フィードバックが速いほど、エージェントの軌道修正も速くなります。
TypeScriptの型チェックは最速のフィードバック層です。
型エラーが出れば、エージェントは数秒で問題を認識して修正に入ります。
GMOの事例では、architecture.test.ts に23条件の構造テストを実装し、アーキテクチャ違反をCI以前に自動検出しています。
everything-claude-code の設計を読み解く
everything-claude-code(GitHub 100K+ stars)は、ハーネス設計の集大成ともいえるリポジトリです。
自らを「agent harness performance optimization system」と説明しています。
なぜ10万スターを超えたのか。
単なるCLAUDE.mdのテンプレート集ではなく、ハーネスの5要素すべてを網羅した実行可能なシステムだからです。
ディレクトリ構成と各要素の対応
everything-claude-code/
├── CLAUDE.md # [ルール] プロジェクト概要・基本方針
├── AGENTS.md # [ルール] 28エージェントの役割定義
├── rules/ # [ルール] 言語別の詳細制約
│ ├── typescript/ # TypeScript固有のルール
│ ├── python/ # Python固有のルール
│ ├── rust/ # Rust固有のルール
│ └── common/ # 全言語共通ルール
├── skills/ # [スキル] 125個以上のワークフロー定義(2026年3月23日時点)
│ ├── tdd-workflow/ # TDD手順
│ ├── deep-research/ # リサーチ手順
│ ├── security-review/ # セキュリティレビュー手順
│ └── continuous-learning/ # 学習パターン自動抽出
├── agents/ # [スキル] 28個の専門エージェント定義
│ ├── planner.md # 設計・計画担当
│ ├── code-reviewer.md # コードレビュー担当
│ ├── tdd-guide.md # TDD実行担当
│ └── harness-optimizer.md # ハーネス自体の最適化担当
├── hooks/hooks.json # [フック] 25以上のイベントトリガー
├── contexts/ # [メモリ] セッション永続コンテキスト
│ ├── dev.md # 開発用コンテキスト
│ ├── research.md # リサーチ用コンテキスト
│ └── review.md # レビュー用コンテキスト
└── tests/ # [フィードバック] 自動検証スイート
注目すべき設計パターン
1. フックの多層防御
hooks.jsonには25以上のフックが定義されています。
特に注目すべきは、その多層構造です。
PreToolUse(ツール実行前):
- git hook bypass の阻止(--no-verify を許さない)
- linter設定ファイルの改変を阻止(ルール弱体化の防止)
- セキュリティモニタリング
- MCP サーバーのヘルスチェック
PostToolUse(ツール実行後):
- 自動フォーマット
- TypeScript型チェック
- console.log残留の警告
- 品質ゲートチェック
Stop(タスク完了時):
- セッション状態の永続化
- 学習パターンの自動抽出
- コスト(トークン使用量)の記録
「ファイル編集後に自動フォーマット」程度のフックは多くの人が設定しています。
ECCが突出しているのは、エージェントがルールを迂回する行動自体を阻止するフックを持っている点です。
--no-verify でgit hookを飛ばそうとする行動や、ESLintの設定を緩めてエラーを消そうとする行動を、構造的にブロックします。
2. 自己最適化の仕組み
harness-optimizer というエージェントが存在します。
これはハーネス自体の設定を分析し、改善提案を行う専門エージェントです。
さらに continuous-learning スキルが、セッションごとにパターンを自動抽出し、ハーネスの知識ベースを継続的に更新します。
ハーネスが自分自身を改善する。
これは静的なCLAUDE.mdテンプレートとの根本的な違いです。
3. 段階的な強度設定
ECCのフックには minimal standard strict の3段階のモードがあります。
すべてのフックが常時有効ではなく、プロジェクトの成熟度に応じて強度を調整できる設計です。
導入の段階的アプローチ
いきなり全部入りは失敗します。ECCのような完成形を初日から導入すると、フックの嵐でエージェントの応答が遅くなり、設定の管理に追われ、本来の開発が進みません。痛みを感じたところから順に追加するのが正解です。
ステップ1: CLAUDE.mdを書く(Day 1)
まだ持っていないなら、ここからです。
プロジェクトの技術スタック、コーディング規約、ディレクトリ構造を記述します。
# CLAUDE.md
## 技術スタック
- Next.js 15 (App Router)
- TypeScript 5.x
- Prisma + PostgreSQL
## 規約
- コンポーネントは src/components/ に配置
- APIルートは src/app/api/ に配置
- 型定義は src/types/ に集約
筆者の経験では、所要時間は30分程度です。
これだけでAIの出力品質は筆者の体感で大幅に改善しました。
ステップ2: 最初の痛みが出たらスキルを追加(Week 1〜2)
「テストの書き方が毎回違う」「デプロイ手順を毎回説明している」と感じたら、その作業をスキル化します。
# .claude/skills/add-feature/SKILL.md
1. src/types/ に型定義を追加する
2. src/domain/ にビジネスロジックを実装する
3. src/app/api/ にAPIルートを作成する
4. テストを書いて実行する
5. 進捗ファイルを更新する
最初は2〜3個で十分です。
「何度も同じ説明をしている」作業から優先的にスキル化します。
ステップ3: ルール違反が気になったらフックを設定(Week 2〜4)
「フォーマットが崩れたまま出力される」「テストを書き忘れる」と感じたら、フックの出番です。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/format.sh"
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "npm run typecheck && npm run test"
}
]
}
]
}
}
まずはこの2つだけ設定します。
- ファイル編集後の自動フォーマット(
Edit|Writeにマッチ) - タスク完了前の型チェック+テスト実行(
Stopはmatcher不要)
これだけで「テストを書き忘れた」「型エラーが残っている」が構造的に防がれます。
ステップ4: セッション切れで困ったらメモリを構築(Week 2〜4)
「昨日の続きを頼んだのに、前回の決定を無視された」と感じたら、メモリを導入します。
# progress.md
## 現在の状態
- 実装済み: [機能A, 機能B]
- 作業中: [機能C]
- 未着手: [機能D, 機能E]
## 意思決定ログ
- 2026-03-20: ORMはPrismaを採用(理由: 型安全性)
- 2026-03-21: 認証はNextAuth.jsを使用(理由: App Router対応)
CLAUDE.mdに「セッション開始時にprogress.mdを読むこと」と追記します。
ステップ5: 同じ違反が繰り返されたらルールを昇格(継続的)
GMOの事例で紹介されている「エスカレーションラダー」の考え方です。
| レベル | 方式 | 例 | いつ昇格するか |
|---|---|---|---|
| L1 | ドキュメント | CLAUDE.mdにパターンを記載 | 初回の違反 |
| L2 | AI検証 | CLAUDE.mdでルール参照、AIレビュー | 同じ違反が3回発生 |
| L3 | ツール検証 | Biome, dependency-cruiserで機械的に検査 | AI検証をすり抜ける |
| L4 | 構造テスト | architecture.test.tsで不変条件をテスト | ビジネスクリティカルな制約 |
最初からL4を目指す必要はありません。
同じ違反が3回発生したら、1段階上のレベルに昇格させる。
この「3回ルール」でルールの強度を段階的に上げていきます。
GMOの事例では、この昇格を「エスカレーショントラッカー」で管理しています。週次で違反を集計し、繰り返し発生するパターンを自動的にCI検証に昇格させる仕組みです。
ハーネスの限界と今後
ハーネスエンジニアリングは万能ではありません。
現時点の限界
初期コストと保守コスト: ルール体系・スキル・フックの設計には時間が必要です。さらに厄介なのは保守です。設定したルールは放置すると実態と乖離していきます。GMOの事例では90日間隔のパターン鮮度チェックを推奨しています。
過剰なハーネスは逆効果: フックを増やしすぎると、ファイルを1つ編集するたびに5つの検証が走り、エージェントの応答が極端に遅くなります。ハーネスの設計自体に、コスト意識が求められます。
エージェントの能力限界は超えられない: ハーネスはエージェントの出力方向を制御しますが、エージェント自体ができないことを可能にはしません。複雑な設計判断や、ドメイン知識が必要な意思決定は、依然として人間の役割です。
「ハーネス = 信頼しないこと」ではない
よくある誤解に触れておきます。
ハーネスはAIを信頼しないための仕組みではありません。
優秀な人間エンジニアも、git戦略・CI/CD・コードレビューという「構造」の中で最高のパフォーマンスを発揮します。
lint設定やテスト自動化は、エンジニアを信頼していないから導入するのではありません。
むしろ、構造的な支援があるからこそ、人は本質的な問題解決に集中できます。
AIエージェントも同じです。
今後の展望
ツール側の組み込み対応: Claude CodeのHooks機能、Kiro CLIのステアリングファイルのように、エージェントツール自体がハーネスの概念を取り込み始めています。ECCのような外部プラグインで実現していた機能が、ツール本体に吸収されていくでしょう。
ハーネスの共有と標準化: ECCの10万スターが示すように、良いハーネス設計はコミュニティの共有知になりつつあります。言語別・フレームワーク別のハーネステンプレートが整備されていく流れは加速するでしょう。
自己進化するハーネス: ECCの continuous-learning スキルのように、セッションからパターンを自動抽出し、ハーネス自体を継続的に改善する仕組みが一般化していくと考えます。静的な設定ファイルから、学習する制御システムへの進化です。
まとめ
ハーネスエンジニアリングの要点を整理します。
- AIエージェントの品質は「賢さ」ではなく「構造」で守る
- CLAUDE.mdは出発点だが、それだけでは「お願い」にすぎない
- ルール・スキル・フック・メモリ・フィードバックループの5要素で制御する
- いきなり全部入りにせず、痛みを感じたところから段階的に追加する
- 同じ違反が3回起きたら、ルールの強度を1段階上げる
- ハーネス自体の保守(鮮度管理・過剰検証の排除)も忘れない
馬具が馬の全力疾走を可能にするように、ハーネスはAIエージェントの能力を最大限に引き出す構造です。
「どう指示するか」から「どう制約するか」へ。
この発想の転換が、AIとの協働開発を次の段階に進めます。