YouMind
ログイン

ハーネスエンジニアリング:実際に機能する AI エージェントの構築方法

@0xjmori
英語2026年9月27日
328K
196
24
17
638

TL;DR

本記事では「ハーネスエンジニアリング」を紹介し、AI エージェントの信頼性はモデルやプロンプトだけでなく、契約、ツール、状態、検証などの周辺システムに依存することを論じます。堅牢なエージェント基盤を構築するための包括的なガイドを提供します。

多くの人は、AI エージェントを間違ったレイヤーで修正しようとしている。

エージェントが失敗すると、プロンプトを書き直す。それでも失敗すると、指示を追加し、モデルを切り替え、コンテキストウィンドウを広げ、別のツールを接続する。

そして同じ問題がぶり返す。

エージェントは重要な判断を忘れ、間違ったツールを使い、3 ステップ前に何が起きたかを見失い、結果を確認せずにタスク完了だと主張し、予算が尽きるまで同じ失敗したアクションをリトライし続ける。

問題は常にモデルにあるわけではない。

問題は、その周囲の環境にある。

その環境こそが harness(ハーネス) である。

Harness Engineering とは、モデルの周囲にシステムを構築する実践のことだ。何が見えるか、何ができるか、何を記憶するか、何が成功とみなされるか、失敗時にどう振る舞うかを決定するシステムである。

より良いプロンプトは、1 つの応答を改善できる。

より良い harness は、すべての実行を改善する。

AI エージェント、自動化、本番システムのより実践的な解説については、私の Substack をフォローしてください:

substack.com/@lunarresearcher

1. モデルはエージェントではない

モデルは推論し、生成し、比較し、選択できる。

しかし、それだけでは信頼できるエージェントにはならない。

真のエージェントには、適切なコンテキストを見つけ、ツールを使い、状態を保持し、権限を尊重し、自身の作業を検証し、環境が想定通りに動かないときに復旧する能力も必要だ。

モデルはあくまで推論エンジンにすぎない。

その推論を実際の「実行」に変換するすべてが harness である。

text
1ユーザーのリクエスト
2 |
3 v
4+-----------------------------+
5| HARNESS |
6| |
7| contract context |
8| tools state |
9| policy verification |
10| traces recovery |
11+-----------------------------+
12 |
13 v
14 MODEL
15 |
16 v
17現実の環境

同じモデルをチャットボックスに入れれば、質問に答えるだけになる。

Mori - inline image

ターミナルアクセス、テスト、ブラウザツール、プロジェクトメモリ、制御された権限、レビューループを持つリポジトリの中に入れれば、実際の仕事を完了できるようになる。

モデルは変わっていない。

変わったのは harness だ。

2. すべてのリクエストをコントラクトに変換する

自然言語は柔軟だ。

しかし、自律的な実行は柔軟であってはならない。

次のようなリクエストは:

オンボーディングフローを改善して。

人間がモデルの隣にいるなら問題ない。

だが、本番環境の指示としては最悪だ。

エージェントが行動する前に、リクエストを境界の定まったタスクコントラクトに変換する。

Mori - inline image
yaml
1objective: オンボーディングの離脱率を下げる
2
3inputs:
4 - プロダクト概要資料
5 - アナリティクスデータ
6 - リポジトリ
7
8constraints:
9 - 認証機能は維持する
10 - データベーススキーマは変更しない
11 - 現在のモバイルでの挙動は維持する
12
13deliverable:
14 - レビュー可能なプルリクエスト
15
16done_when:
17 - テストが通過する
18 - アナリティクスイベントが正しく発火する
19 - デスクトップ版フローがレビューを通過する
20 - モバイル版フローがレビューを通過する
21
22approval_required:
23 - 本番環境へのデプロイ

重要なのは done_when(完了条件)だ。

これがないと、エージェントは少し簡単なバージョンの問題を解いただけで、「タスクは完了しました」と自信満々に宣言してしまう。

これがあれば、完了が測定可能になる。

エージェントはこう尋ねるべきではない:

次に何をすればいいですか?

こう尋ねるべきだ:

どのアクションが、現在の環境をコントラクトで定められた成果に近づけるか?

こちらの方がはるかに強力なループになる。

3. 巨大なコンテキストウィンドウではなく「地図」を与える

エージェントのミスに対するよくある反応は、モデルにより多くのコンテキストを与えることだ。

もっとドキュメントを。

もっと会話履歴を。

もっとファイルを。

もっとツールの出力を。

そのうちエージェントはすべてを受け取り、何も理解しなくなる。

コンテキストはストレージではない。

注意(アテンション)の予算だ。

Mori - inline image

プロジェクト全体を毎回の実行に放り込むのではなく、有用な情報がどこにあるかを示す小さな地図をエージェントに渡す。

text
1プロジェクトマップ
2
3product rules -> docs/product/
4architecture -> docs/architecture.md
5frontend -> apps/web/
6backend -> services/api/
7tests -> tests/
8commands -> docs/commands.md
9security -> docs/security.md

そして必要なときだけ展開する。

text
1タスク
2 |
3 v
4プロジェクトマップ
5 |
6 v
7関連するシステム
8 |
9 v
10対象ファイル
11 |
12 v
13ローカルな指示

元記事ではこれを progressive disclosure(段階的開示)と呼んでいる。harness が情報を読み込むべきなのは、タスクがそれを必要とするからであり、単に情報が存在するからではない。

目的はコンテキストの最大化ではない。

有用なシグナルの最大化だ。

4. モデルとツールの間にゲートウェイを置く

20 個のツールを持つモデルが、自動的に 20 倍有能になるわけではない。

単に失敗する方法が 20 個増えただけかもしれない。

すべてのツールにはコントラクトが必要だ。

text
1TOOL: edit_file
2
3INPUTS
4path
5patch
6
7PRECONDITIONS
8path が存在すること
9path がワークスペース内であること
10
11SUCCESS
12patch が適用されたこと
13diff が返されたこと
14
15FAILURE
16構造化されたエラー
17部分的な上書きは発生しないこと
18
19RISK
20可逆的

すると実行パスはこうなる:

text
1モデルが提案する
2 |
3 v
4ゲートウェイが検証する
5 |
6 v
7ポリシーが認可する
8 |
9 v
10ツールが実行する
11 |
12 v
13harness が結果を記録する

どのアクションを取りたいかを決めるのはモデルだ。

そのアクションが妥当で、許可されており、安全かどうかを決めるのは harness である。

Mori - inline image

この区別は、ツールがメッセージ送信、本番環境の変更、支払い、データ削除を行える場合に決定的に重要になる。

優れたツールゲートウェイは、タイムアウトの追加、引数の検証、ファイルパスの制限、エラーの正規化、リトライの安全化も担える。

良いツールは、モデルが推測しなければならないことを減らす。

5. メモリを会話の外へ移す

会話をシステムの記録源にしてはいけない。

長時間稼働するエージェントは、いずれコンテキスト上限に達し、クラッシュし、再起動するか、別のセッションへ作業を引き継ぐ。

重要な判断がすべてログの中にしか存在しなければ、ワークフローは脆い。

永続的な状態は別に保存する。

Mori - inline image
json
1{
2 "task_id": "feature_042",
3 "status": "verifying",
4 "current_step": "mobile_check",
5
6 "completed": [
7 "implementation",
8 "unit_tests",
9 "desktop_check"
10 ],
11
12 "decisions": [
13 "既存のエクスポートエンドポイントを再利用する",
14 "現在の日付フォーマットを維持する"
15 ],
16
17 "artifacts": [
18 "export.csv",
19 "desktop-after.png"
20 ],
21
22 "open_risks": [
23 "モバイルのツールバーがはみ出す可能性がある"
24 ],
25
26 "next_action": "モバイルビューポートを描画する"
27}

実用的なシステムは、メモリを 4 つのカテゴリに分ける:

text
1FACTS(事実)
2不変の知識
3
4DECISIONS(判断)
5何を選び、なぜ選んだか
6
7STATE(状態)
8現在の実行がどこまで進んでいるか
9
10LESSONS(教訓)
11今後の実行に影響すべき失敗

次のエージェントセッションが引き継ぐべきは、前回の会話を圧縮した物語ではなく、作業の状態そのものだ。

6. 完了のゲートを「証拠」にする

エージェントが「完了しました」と言うことは、仕事が終わった証明にはならない。

Mori - inline image

それはもう一つのモデル出力にすぎない。

harness には観察可能な証拠が必要だ。

text
1主張 証拠
2
3「バグは修正済み」 失敗していたテストが通過する
4
5「ページは正常に動く」 ブラウザでのフローが完了する
6
7「データは正しい」 値がソースと一致する
8
9「マイグレーションは安全」 ドライラン+ロールバックが成功する
10
11「タスクは完了」 すべての受け入れチェックが通過する

まずは決定論的なチェックを使う。

text
1構文チェック
2 |
3 v
4型チェック
5 |
6 v
7フォーカステスト
8 |
9 v
10統合テスト
11 |
12 v
13視覚的/意味的レビュー
14 |
15 v
16人間の承認

コンパイラ、テスト、スキーマ、データベースクエリで証明できることを、別のモデルに答えさせてはいけない。

判断にはモデルを使う。

事実には決定論的なシステムを使う。

成果物を作るのはモデルだ。

その成果物に関する証拠を作るのは環境だ。

証拠が十分かどうかを判断するのは harness である。

7. 作る人と検証する人を分ける

自己レビューにはもう一つ問題がある。

ミスを作り出したエージェントは、レビュー時にも同じ前提を持ち込んでしまうことが多い。

Mori - inline image

より堅牢なアーキテクチャは、ワーカーと検証者を分離する。

text
1BUILDER
2 |
3 v
4候補を作成する
5 |
6 v
7VERIFIER
8 |
9 +-- コントラクトを確認する
10 +-- 欠落しているケースを探す
11 +-- 根拠のない主張をテストする
12 +-- 結果を壊そうとする
13 |
14 +------ PASS ------> ACCEPT
15 |
16 +------ FAIL ------> RETURN EVIDENCE

検証者はこう問うべきではない:

これは良さそうに見えるか?

こう問うべきだ:

何が起これば、これは受け入れ不可になるか?

これにより、レビューは「確認作業」から「反証の試み」へと変わる。

元記事では、検証専用の却下基準を与え、最初の結果を生んだ前提に異議を唱えられるだけの独立性を持たせることを明確に推奨している。

8. 権限管理をモデルの外に出す

一部のルールは、モデルが覚えてくれることに依存してはならない。

text
1承認なしで公開しない
2シークレットを露出させない
3支出上限を超えない
4ワークスペース外に書き込まない
5実行していないテストを「通過した」と主張しない

これらはプロンプトへのお願いではない。

Mori - inline image

ポリシーだ。

シンプルな権限の階層:

text
1低リスク
2
3read
4search
5inspect
6
7-> 自動許可
8
9可逆的操作
10
11edit workspace
12run tests
13create draft
14
15-> 自動許可+トレース記録
16
17外部に影響する操作
18
19send
20deploy
21purchase
22
23-> 承認が必要
24
25不可逆/機密操作
26
27delete data
28rotate credentials
29publish globally
30
31-> 厳格なゲートまたは禁止

影響が大きいほど、制御も強くする。

アクションを推奨できるのはモデルだ。

認可するのは harness である。

実行するのはツールだ。

自律性とは、制御がないことではない。

強制力のある境界の内側での自由だ。

9. 盲目的なリトライをやめる

最悪のリカバリー方針の一つはこれだ:

失敗した。もう一度やれ。

何も変わらないなら、システムは同じ失敗を再現するためにお金を払っているだけだ。

まず失敗を分類すべきだ。

Mori - inline image
text
1ツールのタイムアウト
2-> バックオフ付きでリトライ
3
4無効な引数
5-> ツール呼び出しを修正
6
7コンテキスト不足
8-> 不足しているソースを取得
9
10テスト失敗
11-> 失敗した挙動を検査
12
13権限拒否
14-> 承認を要求
15
16要件の矛盾
17-> エスカレーション
18
19変化のない繰り返しの失敗
20-> 停止

実用的なエージェントループはこうなる:

text
1OBSERVE(観察)
2 |
3 v
4DECIDE(判断)
5 |
6 v
7ACT(実行)
8 |
9 v
10MEASURE(計測)
11 |
12 +---- ACCEPT(受容)
13 |
14 +---- REPAIR(修復)
15 |
16 +---- ESCALATE(報告)
17 |
18 +---- STOP(停止)

すべてのループには、試行回数、時間、コスト、破壊的範囲の上限が必要だ。

信頼できるエージェントは、どう続けるかを知る必要がある。

同時に、いつ次の試みが無駄になるのかも知る必要がある。

10. 繰り返される指示をインフラに変える

プロンプトにこう書かれているとしよう:

必ずフォーマッターを実行すること。

フォーマッターが自動で走るようになれば、このルールはより強固になる。

指示にこう書かれていたとしよう:

UI コードはデータベースに直接アクセスしてはならない。

ルール違反時に失敗するアーキテクチャテストとして実装した方が、はるかに強力だ。

進化の過程はこうなる:

text
1説明
2 |
3 v
4チェックリスト
5 |
6 v
7テンプレート
8 |
9 v
10自動チェック
11 |
12 v
13強制されるポリシー

判断について説明すべきはプロンプトだ。

不変条件を強制すべきは harness である。

繰り返されるミスはすべて、この階段を一段ずつ下げていくべきだ。

最終的に、モデルはその教訓を覚えている必要がなくなる。

環境がモデルの代わりに覚えてくれるからだ。

11. 実行を記録する

完璧な成果物が、ひどい実行プロセスを隠すことがある。

エージェントが間違ったソースにアクセスしたかもしれない。

失敗したコマンドを無視したかもしれない。

外部アクションを 2 回繰り返したかもしれない。

想定予算の 10 倍を使ったかもしれない。

間違った理由で正解を出したかもしれない。

何が起きたかを再構成できるだけの情報を記録する。

text
109:14 タスクコントラクト作成
209:15 architecture.md 読み込み
309:17 checkout.ts 編集
409:18 フォーカステスト失敗
509:21 実装修正
609:22 フォーカステスト通過
709:24 統合テスト通過
809:25 デプロイブロック:承認が必要

有用なトレースには、コンテキストソース、ツール呼び出し、状態変化、検証結果、リトライ理由、承認判断、コスト、レイテンシが含まれる。

ログ集めを楽しむのが目的ではない。

失敗箇所を局所化するのが目的だ。

ステップ 18 で壊れたなら、ステップ 18 だけを修正できるべきだ。

実行全体を巻き戻す必要はない。

12. すべての実行にレシートを発行する

40 メッセージ分のログを人間にレビューさせるべきではない。

結果を小さなレシートにまとめる。

text
1OBJECTIVE(目的)
2
3クーポンの重複適用を修正する。
4
5CHANGED(変更点)
6
7checkout のバリデーション
8回帰テスト
9
10VERIFIED(検証済み)
11
12lint 通過
13ユニットテスト通過
14統合テスト通過
15
16NOT VERIFIED(未検証)
17
18本番環境の決済プロバイダー
19
20RISKS(リスク)
21
22レガシーモバイルクライアントが利用不可
23
24APPROVAL NEEDED(要承認)
25
26ステージング環境へのデプロイ

これは、モデルが「こうなった」と主張した内容の要約ではない。

harness が「こうなった」と証明できる内容の要約だ。

この違いがあるからこそ、レシートはレビュー、引き継ぎ、将来のエージェントセッションで役立つ。

13. すべての失敗で harness を改善する

多くのチームは、失敗した出力だけを修正する。

より良いアプローチは、その失敗を許してしまったシステム自体を修正することだ。

text
1コンテキスト不足
2-> プロジェクトマップを改善
3
4間違ったツール
5-> ルーティングまたはツールコントラクトを改善
6
7悪い出力
8-> バリデーターを追加
9
10無限ループ
11-> リトライ上限を追加
12
13危険なアクション
14-> 権限ゲートを追加
15
16判断の消失
17-> 状態を永続化
18
19原因不明の失敗
20-> トレース機能を改善

ここで Harness Engineering の複利効果が生まれ始める。

1 つの出力を修正しても、助かるのは 1 回の実行だけだ。

harness を 1 つ修正すれば、それ以降のすべての実行が改善される。

最高のエージェントシステムが信頼性を増していくのは、ミスがインフラという遺産を残すからだ。

14. 最小限の有用な harness から始める

始めるのに巨大なオーケストレーション基盤は不要だ。

層を重ねて構築する。

text
1LEVEL 0
2
3prompt
4model
5
6LEVEL 1
7
8task contract
9project map
10tools
11
12LEVEL 2
13
14structured state
15verification
16bounded loop
17
18LEVEL 3
19
20permissions
21traces
22recovery
23human gates

短い調査タスクなら、プロンプトと 1 回のレビューだけで十分なこともある。

ファイルアクセス、ネットワークアクセス、デプロイ機能を伴う 6 時間のコーディングタスクなら、ずっと多くのものが必要だ。

複雑さを追加するのは、失敗の可能性がそれを正当化するときだけにする。

エージェントアーキテクチャがかっこよく見えるからではない。

Harness Engineering チェックリスト

エージェントに意味のある自律性を与える前に、こう問いかけよ:

text
1[ ] 実行前に成功が定義されているか?
2
3[ ] エージェントはすべてを読み込まずに
4 適切なコンテキストを見つけられるか?
5
6[ ] すべてのツールに明確な目的、
7 スキーマ、失敗時の状態が定義されているか?
8
9[ ] 重要な判断が会話の外に
10 保存されているか?
11
12[ ] 完了に証拠が求められているか?
13
14[ ] リスクの高いアクションがポリシーで保護されているか?
15
16[ ] すべてのループにリトライ上限があるか?
17
18[ ] 中断後に実行を再開できるか?
19
20[ ] すべての重要なアクションを再構成できるか?
21
22[ ] 失敗がルール、ツール、
23 テスト、マップ、権限のいずれかを改善するか?
24
25[ ] 最終的な変更をロールバックできるか?

複数の答えが「ノー」なら、より強力なモデルを使ってもエージェントは自動的には信頼できない。

単に失敗が速く、高くつくようになるだけかもしれない。

本当のパラダイムシフト

Prompt engineering はこう問う:

モデルに何を伝えるべきか?

Context engineering はこう問う:

モデルは今何を知っているべきか?

Harness engineering はこう問う:

モデルが行動し、自身の作業を検証し、失敗から復旧し、安全に動作できるシステムとは何か?

text
1PROMPT
2-> 指示
3
4CONTEXT
5-> 作業用の視界
6
7HARNESS
8-> 実行環境
9
10LOOP
11-> 局所的な修正
12
13GRAPH
14-> 協調

モデルは変わり続ける。

持続的な優位性は、その周囲に宿る。

あなたのコントラクトは良くなる。

あなたのツールは良くなる。

あなたのテストは良くなる。

あなたの状態管理は整理される。

あなたの権限制御は安全になる。

あなたのリカバリーロジックは賢くなる。

あなたの失敗はインフラに変わる。

そうやって、有能なモデルは信頼できるエージェントになる。

それが Harness Engineering だ。

ここまで読んでくれたあなたへ

このガイドをブックマークしてほしい。

X でフォローする: x.com/0xjmori

Substack を購読する: substack.com/@lunarresearcher

エージェントの失敗を、まだ長いプロンプトで解決しようとしている人にこの記事を送ってあげてほしい。

ワンクリック保存

YouMindでバイラル記事をAI深読み

ソースを保存し、的を絞った質問をし、主張を要約して、バイラル記事を再利用できるノートに変えます。すべてを1つのAIワークスペースで行えます。

YouMindを探索
クリエイターのために

あなたの Markdown をきれいな 𝕏 記事に

自分の長文を投稿するとき、画像・表・コードブロックを 𝕏 向けに整形するのは手間がかかります。YouMind は Markdown 全体を、そのまま投稿できるきれいな 𝕏 記事に変換します。

Markdown → 𝕏 を試す

解読すべきパターンをもっと

最近のバイラル記事

バイラル記事をもっと見る