エージェントのハーネス早見表:構成要素、ファイル、よくある問題、起動チェックリスト
エージェントのハーネスは5つのサブシステムからなります。指示、ツール、環境、状態、フィードバックです。最小限のファイルセットは、短いルーターとしての AGENTS.md、検証スクリプト(make check、verify.sh)、進捗ファイル、ステータス付きの機能リストです。「passing」の判定はエージェントではなくスクリプトが行います。
ハーネスの5つのサブシステム
| サブシステム | 意味 | 成果物 | 壊れたときの症状 |
|---|---|---|---|
| 指示 | エージェントがプロジェクトについて知るべきこと | AGENTS.md / CLAUDE.md、skills、docs/、ADR | 既知の規約を破る |
| ツール | エージェントができること | shell、テスト、リンター、ブラウザ、MCPサーバー | 「やりたいができない」 |
| 環境 | エージェントが働く場所 | ロックファイル、Docker/devcontainer、git worktree、サンドボックス、init.sh | 毎回のセッションが環境の修復から始まる |
| 状態 | 再起動後も残るもの | PROGRESS.md、DECISIONS.md、feature_list.json、コミット履歴 | 新しいセッションが前回どこで止まったか分からない |
| フィードバック | エージェントが自分のミスをどう知るか | make check、E2E、フック、アーキテクチャチェック、評価者 | 「完了」と言うが、動いていない |
ゼロから作る場合の順序は、フィードバック → 指示 → 状態 → 環境 → ツールです。
ハーネスのファイル
| ファイル | 用途 | ルール |
|---|---|---|
| AGENTS.md / CLAUDE.md | 入口:プロジェクトの概要、起動方法、検証方法 | 短いルーター(約80行)、「いつ読むか」の条件付きでドキュメントにリンク |
| docs/*.md | テーマごとの詳細 | 必要なときに読む。まとめて読み込まない |
| .claude/skills/*/SKILL.md | 繰り返し行う手順(デプロイ、レビュー) | タスクが説明と合致したときに読み込まれる |
| PROGRESS.md | 状態、完了した作業、ブロッカー、次のステップ | セッションの終わりごとに更新 |
| DECISIONS.md | 決定、理由、却下した選択肢 | 結論だけでなく経路も記録する |
| feature_list.json | 機能ごとの behavior、verification、state | active はちょうど一つ(WIP=1) |
| scripts/verify.sh | 機能を検証し、passing に設定する | passing を設定できる唯一のスクリプトで、コミットの SHA を付ける |
| scripts/arch-check.sh | アーキテクチャの境界を検査する | 終了コード1、出力に WHY と FIX を含める |
| scripts/init.sh | 作業前に環境を確認する | 環境が正常、git の作業ツリーがクリーン、make check が緑、アクティブな機能がある |
| sprint contract | コーディングの前に機能について合意する文書 | スコープ内 / スコープ外 / 未解決の質問 |
| .claude/settings.json | Claude Code の権限とフック | エージェントの記憶ではなく、イベントで検査する |
AGENTS.md の骨組み
# プロジェクト:決済バックエンド(FastAPI、PostgreSQL)
## 起動
docker compose up -d && ./scripts/init.sh
## 検証
make check # リンター、型、単体テスト、arch-check
make e2e # エンドツーエンドのシナリオ
## 完了の定義
- make check と make e2e が終了コード0
- 機能は scripts/verify.sh で passing に設定されている
- PROGRESS.md が更新されている
## MUST
- DBアクセスはリポジトリ経由のみ
- シークレットは環境変数からのみ読む
## ドキュメント
- docs/payments.md——決済と返金に関わるタスク
- docs/migrations.md——DBスキーマを変更するタスク
機能の状態
| 状態 | 意味 | 誰が変更するか |
|---|---|---|
| pending | 待機中 | 計画者 |
| active | 作業中(同時に一つだけ) | エージェントが作業を開始するとき |
| passing | 検証に合格 | verify.sh のみ |
| blocked | 人間の判断が必要、理由を記載 | エージェント |
検証の層
| 層 | 内容 | 実行タイミング |
|---|---|---|
| 1 | リンター、型チェック | 常に |
| 2 | 単体テストと統合テスト | 常に |
| 3 | E2Eテスト | 複数の層にまたがる変更のとき。「完了」と言う前 |
| 4 | arch-check | 層をまたぐ新しいインポートが現れたとき |
一番上の層を通過して初めて「完了」と言えます。緑の単体テストは完了ではありません。
ルールの機械化
| 層 | ツール | コスト |
|---|---|---|
| grep ガード | パターン検索と WHY/FIX のメッセージを出すスクリプト | 数分 |
| リンターのルール | import-linter(Python)、dependency-cruiser、eslint-plugin-boundaries(JS/TS) | 約1時間 |
| アーキテクチャテスト | 層の違反で失敗する CI のテスト | 手間は増えるが、make check で見える |
#!/usr/bin/env bash
fail=0
if grep -rn "from app.db" app/services/; then
echo "WHY: サービス層は DB に直接アクセスしない"
echo "FIX: app/repositories/ のリポジトリを使う"
fail=1
fi
exit $fail
よくある問題と対処法
| 問題 | サブシステム | 対処法 |
|---|---|---|
| CLAUDE.md のルールが守られない | 指示 | ファイルを縮め、ルールを検査またはフックに変える |
| エージェントがテストを実行できない | ツール | そのコマンドを許可し、依存関係をイメージに入れる |
| マシンによって動作が違う | 環境 | ロックファイル、Docker/devcontainer、ランタイムのバージョン固定 |
| セッション間の健忘症 | 状態 | PROGRESS.md、セッションの引き継ぎメモ、開始時に読む |
| 三つの機能を始めて、どれも完了しない | 状態 | feature_list.json で WIP=1 |
| 「完了」なのに動かない | フィードバック | 完了の定義、E2E、verify.sh、独立した評価者 |
| テストは緑なのに機能が壊れている | フィードバック | 実際のDBと設定を使った E2E |
| エージェントが悪いパターンをコピーする | フィードバック | 初日から arch-check を入れる |
| エージェントが何をしたか分からない | 状態 | 小さなコミット、PROGRESS.md での報告、DECISIONS.md の記録 |
| 一晩で環境が壊れた | 環境 | サンドボックス、git worktree、チェックポイント、init.sh によるロールバック |
| 同じレビューコメントが二度出た | ハーネス全体 | make check の検査に変え、指示文からは削除する |
長いタスクにおける役割
| 役割 | 担当 | 担当しないこと |
|---|---|---|
| 計画者 | 受け入れ基準付きの機能 | コードは書かない |
| 生成者 | 一つの機能を実装し、テストを実行 | 完了かどうかは決めない |
| 評価者 | 評価基準に沿って、ファイル、行番号、ログを参照して判定 | 生成者の推論は見ない |
| マージ | review == pass のときにコミット | コードであって、エージェントではない |
自律作業の予算
- 目標は一文で書く(例:すべての機能を passing にする)。
- WIP=1。機能ごとに時間と試行回数の上限を設ける。
- 指標は単調に増え、回帰が起きたら即座にロールバックする。
- マイグレーション、インフラ、お金は人に引き継ぐ。
- レビューが何度も失敗したら、その機能はクリーンなコンテキストで最初からやり直す。
エージェント起動のチェックリスト
- AGENTS.md がある:技術スタック、起動方法、検証コマンド、完了の定義。
- クリーンなクローンで make check が通る。
- 環境が再現可能:ロックファイル、Docker または devcontainer。
- エージェントに必要なコマンドの権限があり、危険なコマンドは禁止されているかサンドボックス内にある。
- 主要なシナリオを一つ以上カバーする E2E テストがある。
- PROGRESS.md があり、セッションの開始時に読むよう定められている。
- 機能リストにステータスがあり、アクティブなのは一つだけ。
- passing の設定はスクリプトが行う。
- 検査のメッセージに WHY と FIX が含まれる。
- タスクに受け入れ基準があり、スコープの境界が明確。
- 人間の判断が必要な事項が明確になっている。
- 変更の前に verification gap を計算し、後で比較できるようにしている。
ハーネスの指標
| 指標 | 計算方法 |
|---|---|
| Verification gap | 10タスクのうち、「完了」と言ったが検証で確認されなかった割合 |
| MTTR | 障害の発生から作業可能な状態への復旧までの時間 |
| コールドスタート | 新しいセッションが、推測せずに「今どこにいて、次は何か」に答えられるか |
| アブレーション | 固定したタスク集合で、一つのサブシステムを切ったときの性能低下 |
まとめ
ハーネスはファイル一つではなく、指示、ツール、環境、状態、フィードバックからなる一つのループです。検証から始め、AGENTS.md は短く保ち、「完了」の判定はスクリプトに任せ、ハーネスを定期的に見直してください。これらはすべて、ハーネスエンジニアリングの講座で、実際のプロジェクトを通した完全なハーネスとしてまとめています。
よくある質問
AGENTS.md と CLAUDE.md の違いは何ですか?
役割は同じで、どちらもエージェントの指示ファイルです。CLAUDE.md は Claude Code が読み、AGENTS.md は複数のエージェントに通じる共通の形式です。CLAUDE.md から AGENTS.md を参照することもできます。
AGENTS.md は何行にすべきですか?
厳密な上限はありませんが、入口のファイルは目次のように短く、100行程度が目安です。詳細は別のドキュメントに置いてください。
小さなプロジェクトにも feature_list.json は必要ですか?
単発の小さな修正なら不要です。エージェントが複数の機能を連続して、あるいは複数のセッションにまたがって扱うようになると、その価値が出てきます。
エージェントがアクセスするシークレットはどこに置けばよいですか?
環境変数やシークレットマネージャーに置き、指示ファイルやコードには書かないでください。エージェントに渡すのは環境へのアクセス権であり、テキストに書かれた値ではありません。
このテーマはコース「Harness Engineering: инженерия надёжности AI-агентов」で実践とともに詳しく解説しています。
- Из чего состоит harness AI-агента: инструкции, инструменты, среда, состояние, обратная связь
- Харнес AI-агента с нуля: AGENTS.md, feature_list.json, verify.sh и автономный цикл