📌 目次
- はじめに — 「Bitter Lesson」とは何か
- Agent Harness とは何か — OSの比喩
- なぜ抽象化(フレームワーク)は失敗するのか
- 99%はモデルの中にある
- 鍵となるインサイト — アクション空間の問題
- 逆転の発想 — 最大から始めて制限する
- ほとんどのHarnessがBitter Lessonを活かせていない理由
- プロダクション・ハーネスの6つのコアコンポーネント
- コンテキスト管理の3原則 — Reduce / Offload / Isolate
- 実世界のケーススタディ
- 設計哲学 — 「削れる構造」を作れ
- よくある障害パターン
- まとめ
- 参考リンク
1. はじめに
2019年、強化学習の権威 Rich Sutton は「The Bitter Lesson(苦い教訓)」と題した短文を発表しました。
「70年間のAI研究から読み解ける最大の教訓は、計算能力を活用する汎用手法が最終的に最も効果的であり、その差は圧倒的だということだ。」
— Rich Sutton, 2019
この「苦さ」の正体は、研究者の直感に反するという点にあります。私たちは常に自分の理解をシステムに組み込もうとします。精巧なルール体系、ドメイン知識、ヒューリスティクス — しかし歴史は繰り返し同じ結論を示しています。
手作りの賢さは、計算量の力押しに最終的に負ける。
チェスの世界では、Deep Blueが膨大なチェス知識を駆使してカスパロフを破りましたが、後にAlphaZeroが白紙から自己対戦だけで全てのチェスエンジンを打ち負かしました。画像認識では、SIFTやHOGといった手作り特徴量が、ピクセルから直接学習するDeep Learningに圧倒されました。
そして今、この教訓は AIエージェント開発 に直撃しています。
2026年現在、AIエージェント開発の世界で急速に広まっている概念が「Agent Harness(エージェント・ハーネス)」です。
同じモデル(Claude, GPT-5, Gemini)を使っていても、体感品質はまるで別物になる — その差を生み出すのがモデルの「外側」にある仕組み、すなわち Agent Harness です。
2. Agent Harness とは
コンピュータの比喩
Agent Harnessを理解する最も直感的な方法は、コンピュータのアナロジーです。
| コンピュータ | AIエージェント | 役割 |
|---|---|---|
| CPU | LLM | 処理能力そのもの。賢さの源泉 |
| RAM | コンテキストウィンドウ | 作業メモリ。揮発性で容量制限あり |
| OS | Agent Harness | リソース管理、プロセス制御、I/O |
| アプリ | AIエージェント | ユーザーが触れる最終的な製品 |
重要な点:OSがなければアプリは動かない。同様に、Harnessなしではエージェントはまともに動作しない。
3つのレイヤー構造
ユーザー(指示を出す / 結果を受け取る)
│
AIエージェント = アプリケーション層
│ (ユーザー固有のロジック・目的)
│ (例: コードアシスタント/リサーチエージェント)
│
Agent Harness = OS層
│ (コンテキスト管理 / ツール実行 / 権限制御)
│ (メモリ管理 / 再試行 / フォールバック / 承認)
│
LLM = CPU層
(言語理解・推論・生成)
(例: Claude Opus, GPT-5, Gemini)
3者の責務
| 役割 | 何をするか |
|---|---|
| 🧠 LLM | テキスト理解、推論・判断、テキスト生成、ツール選択の提案 |
| ⚙️ Agent Harness | コンテキスト管理、ツール実行制御、権限・安全管理、メモリ管理、リトライ・エラー処理、サブエージェント管理 |
| 🤖 AIエージェント | ユーザーとの対話、タスクの受付・提示、ドメイン固有ロジック |
一言でまとめると:
- LLM = 「考える」(推論エンジン)
- Agent Harness = 「制御する」(実行基盤・ガードレール)
- AIエージェント = 「使わせる」(ユーザー向け製品)
💡 業界の格言:「The model is commodity. The harness is moat.(モデルはコモディティ。ハーネスが競合優位の源泉だ。)」
3. なぜ抽象化は失敗するのか
Browser Useの共同創業者 Gregor Zunic は、自らの失敗体験からこの教訓を語っています。
抽象化は知性の「仮定を凍結」する
「エージェントはメッセージのfor-loopに過ぎない。モデルがツール呼び出しを止めるまで動き続ける — それだけだ。」
Browser Use の最初のエージェントは何千行もの抽象化の上に成り立っていました。計画モジュール、検証レイヤー、出力パーサー — どれも一見「スマート」に見えますが、実はモデルの動作に対する 自分たちの思い込みを符号化していた に過ぎません。
問題はここにあります:
- モデルは 数百万ものサンプル で訓練されている
- モデルはあなたが予測できる以上のパターンを見てきた
- あなたの「賢い」ラッパーは、モデルが学習したものを使うことを 妨げる制約 になる
❌ 悪いアプローチ:
「計画モジュール → 検証レイヤー → 出力パーサー → ツール呼び出し」
手作りのパイプラインがモデルの自由を制限する
✅ 正しいアプローチ:
完全なアクション空間 + シンプルなfor-loop + 明示的な終了条件
モデルが自ら推論する
Bitter Lesson の教えは明確です:汎用手法が手作りの知識を最終的に凌駕する。エージェントフレームワークは、この間違いの最新事例に過ぎない。
4. 99%はモデルの中にある
Browser Use チームが気づいたことがあります。
仕事の99%はモデル自身の内部で行われている。その外側に複雑なフレームワークは不要だ。
わかりやすい例:
Claude Code は AppleScript を直接書けます。Spotify の情報が必要になった時、専用の「Spotifyコンピューター利用ツール」は不要です。AppleScript をmacOSで直接書けばよい。なぜなら:
- モデルは 完璧なコンテキスト を持っている
- このユースケースで十分に訓練されている
- あなたが全てのユースケースを予測する必要はない — モデルはすでに知っている
5. 鍵となるインサイト
Browser Use チームが到達した最も重要な洞察:
「エージェントフレームワークが失敗するのは、モデルが弱いからではない。アクション空間が不完全だからだ。」
従来のアプローチは、考えられる全てのアクションを事前に定義しようとします。しかしこれは根本的に間違っています。
正しい問い: 「LLMが最も得意とすることは何か — そしてモデルが良くなるにつれて何が変わらないか?」
答え: LLMには 可能な限り自由を与え、その後 evals(評価)に基づいて制限を加える。
❌ 従来の発想:
全てのアクションを事前定義 → モデルに選ばせる
✅ Bitter Lesson に則った発想:
モデルにほぼ何でもできる自由を与える → 制限していく
6. 逆転の発想
Browser Use は「逆転(Inversion)」の原則でBU Agentを構築しました:
最大限の能力から始めて、制限を加えていく。
具体的には:
- モデルに 生のブラウザ制御サーフェス へのアクセスを与える
- Chrome DevTools Protocol(CDP)命令を直接発行できる
- ブラウザ拡張機能APIも組み合わせる
- CDPと拡張機能APIはそれぞれ盲点があるが、組み合わせることでほぼ完全なアクション空間を形成する
このレベルの自由があると、驚くことが起きます:
「一つのアプローチが失敗すると、モデルは別の経路を探す。ツールが壊れても、別の方法を見つける。原則として全てが可能である限り、LLMはリアルタイムで自己修正することが非常に得意だ。」
「完了(done)ツール」パターン
@tool('Signal that the current task is complete.')
async def done(message: str) -> str:
raise TaskComplete(message)
ナイーブなアプローチ(ツール呼び出しがなくなったら停止)は機能しません。エージェントが早期終了してしまうからです。
解決策は 明示的な完了シグナル として done ツールを使うことです。Claude Code も Gemini CLI も同じアプローチを採用しています。
エフェメラルメッセージ(Ephemeral Messages)
@tool("Get browser state", ephemeral=3) # 直近3回分だけ保持
async def get_state() -> str:
return massive_dom_and_screenshot
ブラウザエージェントでは、毎回のブラウザ状態取得が50KB以上になる場合があります。
エフェメラルメッセージはX回のツール呼び出し後に過去の出力を削除します。モデルには 最新の状態 だけが必要であり、古いスナップショットはノイズです。
「苦い真実」
「全ての抽象化は負債だ。全ての『ヘルパー』は障害点だ。モデルは賢くなった。本当に賢くなった。RL(強化学習)でコンピュータ利用、コーディング、ブラウジングで訓練された。あなたのガードレールは不要だ。苦い教訓:作るものが少ないほど、うまく動く。」
7. ほとんどのHarnessが活かせていない理由
多くのエージェントアーキテクチャは同じ過ちを犯しています:
「モデルが十分に信頼できないから、信頼性をフレームワーク側に書き込もう」
これはプロダクト観点では合理的に見えますが、本質的には 複雑さをスケール可能な部分(モデル)からスケール不可能な部分(手作りのコード)へ移動させている だけです。
反パターン① ワークフロー陷阱(Workflow Trap)
ビジュアルなワークフロービルダーで「調査 → 要約 → 執筆」をつなぐと、タスク分解に関する自分の前提をアーキテクチャに直接コードで書き込んでいることになります。
問題:
モデルが進化しても、ワークフローは自動的に簡素にならない。
チームはそのフローチャートに縛りつけられたまま。
Bitter Lesson の観点:
手作りのタスク分解ロジック → 計算量で上回られる
反パターン② 専門サブエージェント幻想(Specialized Subagent Illusion)
「調査エージェント」「コーディングエージェント」「執筆エージェント」という固定の役割分担は、人間組織の構造をAIに持ち込んでいる だけです。
- 人間の組織構造は「認知の限界」「コミュニケーションコストの高さ」という制約の中で進化した
- AIにはこれらの制約が必ずしも当てはまらない
- 固定の役割分担をアーキテクチャに凍結することは、計算資源の優位性ではなく、人間の限界を輸入している
反パターン③ ループの天井(For-Loop Ceiling)
「LLM + ループ + ツールで十分」は一見シンプルに見えますが、唯一のスケールのつまみはイテレーション回数だけです。
- 複雑なタスクには一次元のスケールしか効かない
- 並列化が難しい
- トークンを無駄遣いしやすい
「正しい方向」の判断基準
「もし来年モデルの能力が2倍になったとき、大幅な再構築なしに、あなたのシステムは顕著にシンプルに、安く、信頼性高くなるか?
YESなら、あなたはBitter Lessonの側にいる。
スケールプランが『ノード・役割を追加する』なら、あなたは人力をスケールしている。
『モデルが汎用手法でより多くの計算資源を割り当てる』なら、あなたは計算をスケールしている。」
8. プロダクションハーネスの6つのコアコンポーネント
プロダクション品質のAgent Harnessは6つの根幹コンポーネントを持ちます。各コンポーネントの成熟度が、エージェントの信頼性の上限を決めます。
コンポーネント①:コンテキストエンジニアリング(Context Engineering)
実行の各ステップでモデルが何を見るかを決める実践です。プロンプトエンジニアリングより広い概念で、入力パイプライン全体を含みます:
- システムプロンプト
- 検索されたドキュメント
- 会話履歴
- ツール実行結果
- 環境状態
課題: コンテキストウィンドウは広大に見えて(128K〜200K トークン)、タスクが50ステップを超えると、有用な情報が視野外に追い出される。
対策: 何が残り、何が要約され、何が削られるかを能動的に管理する。
コンポーネント②:ツールオーケストレーション(Tool Orchestration)
各ステップでモデルが利用できるツールとその実行を管理します:
- ツール選択
- 引数バリデーション
- 実行のサンドボックス化
- タイムアウト管理
- エラーハンドリング
Vercelの教訓: ツールを80%削減したら結果が改善した。プロダクションハーネスはタスクのフェーズに応じてツールを動的にスコープする。計画ステップにファイル書き込みアクセスは不要。コード実行ステップにウェブ検索は不要。
ナイーブなアプローチ:
50個のツールを与えてモデルに選ばせる → 確実に失敗
プロダクションアプローチ:
タスクフェーズに応じて利用可能ツールを動的にスコープ
コンポーネント③:状態とメモリ管理(State & Memory)
長時間(分〜時間)実行するエージェントには耐久性のある状態が必要です。
- チェックポイント再開(Checkpoint-Resume): ハーネスがクラッシュした時、最初からやり直しになるのか、途中から再開できるのか
- セッション間メモリ: 翌日タスクを再開した時、エージェントは何を覚えているか
Anthropicのアプローチ(claude-progress.txt パターン):
エージェントが構造化されたスクラッチパッドファイルを維持する
内容: 完了ステップ / 現在のブロッカー / アーキテクチャ決定 / 次のアクション
効果: フルな会話を再生する代わりに圧縮されたサマリーを提供
コンポーネント④:検証と安全(Verification & Safety)
エージェントの出力が現実世界に到達する前にチェックします。
- 各ツール呼び出し後のレスポンススキーマ確認
- コードをコミットする前のテスト実行
- 期待値に対する出力バリデーション
- 失敗出力はリトライまたはエスカレーション
実績: 構造化検証を追加することで、タスク完了率が83%から96%に向上した事例あり。モデルは変わっていない。ハーネスが変わった。
コンポーネント⑤:Human-in-the-loop(人間の介在)
全てのエージェントアクションが自律であるべきではありません。高リスク操作には承認ゲートが必須:
- データ削除
- 外部通信の送信
- 金融トランザクション
- インフラ変更
設計上の課題: キャリブレーション。承認ゲートが多すぎると、手動でタスクをやった方が速い。少なすぎると、幻覚した一回のAPIコールでプロダクションインシデントが発生する。
コンポーネント⑥:ライフサイクル管理(Lifecycle Management)
エージェントの起動・ヘルスモニタリング・グレースフルシャットダウン・クラッシュリカバリを包含します:
- ヘルスチェック(エージェントはまだ進捗しているか、ループにはまっていないか)
- リソース制限(タスクあたり最大トークン・最大所要時間)
- グレースフルシャットダウン(状態保存・リソース解放・最終ステータス報告)
- クラッシュリカバリ(障害検出・チェックポイントロード・バックオフ付き再開)
9. コンテキスト管理の3原則
コンテキストの膨張はエージェントの最大の敵です。
多ステップエージェントの成功確率の数学:
- 各ステップの成功率: 95%
- 20ステップ後の完了率: 0.95^20 ≈ 36%
- → これがハーネスが検証ループ・リトライ・チェックポイント再開を必要とする理由
Harnessがこの問題に対処するシンプルな3原則:
原則① Reduce(削る)
古い情報を要約・圧縮して置き換える。
| 手法 | 説明 | 可逆性 |
|---|---|---|
| Compaction | ツール結果からファイルパスのみ保持、中身は削除。必要時に再取得可能 | ✅ 可逆 |
| Summarization | 閾値(例:128Kトークン)を超えたら、LLMで過去履歴を要約に変換 | ❌ 非可逆 |
Claude Code では、会話がコンテキスト制限に近づくと自動でメッセージを圧縮する仕組みが実装されています(「messages compressed」表示)。
原則② Offload(外に出す)
プロンプトに詰め込まず、外部に退避する。
- 全文ログ・根拠資料は DB / ファイルシステム / ログサービスに保存
- 必要な時だけ参照する設計
- ツールは増やしすぎない(Manusは20個未満の原子的ツールに限定)
Manusのツール階層:
Level 1: file_write / bash / search などの基本ツール
Level 2: CLIコマンドラップ(mcp-cli)
Level 3: コードライブラリの直接実行
→ bash のような汎用ツール1つで「行動空間」を確保
専用ツールを大量定義してコンテキストを圧迫しない
原則③ Isolate(隔離する)
トークンを大量消費する作業をサブエージェントに切り出す。
メインエージェント(判断・統括)
│── 調査タスク → 調査エージェント(独立コンテキスト) → 結論のみ返す
│── 要約タスク → 要約エージェント(独立コンテキスト) → 要約のみ返す
└── コード生成 → 生成エージェント(独立コンテキスト) → 成果物のみ返す
狙い:
- ノイズ汚染を防ぐ
- 失敗時の原因切り分けを容易にする
- 並列実行で効率化
3原則の比較
| 原則 | やること | 防ぐ問題 |
|---|---|---|
| Reduce | 捨てる・圧縮する | コンテキスト肥大化 |
| Offload | 外に逃がす | 常時コンテキスト汚染 |
| Isolate | 別コンテキストに隔離 | ノイズ汚染・複雑性の波及 |
10. 実世界のケーススタディ
🔴 Manus — 5回のアーキテクチャ全面書き直し
Manusは2024年3月の公開以降、同じモデルを使いながら5回ハーネスアーキテクチャを全面的に書き直しました。
- モデルは変えていない
- ハーネスが変わるたびに信頼性とタスク完了率が改善
- 学び: 「複雑なRAGパイプラインではなく、要素を削除することで性能向上を達成した」
🔵 LangChain Deep Research — 4回の全面再構築
LangChainのチームはDeep Research(LangGraph)のエグゼキューションエンジンを1年間で4回全面的に再構築しました。
- モデルの改善があったからではない
- ワークフロー・コンテキスト管理・サブタスク調整のより良い構造化方法を発見した
🟢 Vercel — ツールを80%削減したら結果が改善
Vercelのv0コーディングエージェントでの発見:
- 利用可能ツールの80%を削除
- 結果: タスク完了率が向上
- ツールが多いほど混乱が増え、誤ったツール選択が増え、失敗タスクが増えた
- 逆説: 能力を減らすと信頼性が上がる
この3つのケースに共通すること:
最大の改善は「複雑さの追加」ではなく「複雑さの削除」から生まれた
11. 設計哲学
Bitter Lesson から導かれる設計原則は3つです:
原則 1: Start Simple(シンプルから始めよ)
複雑な制御フローを避け、堅牢な原子的ツールを提供するところから始める。
最も一般的なミスは、エージェントの実際の障害パターンを理解する前にハーネスを過剰設計することです。
フェーズ別実装ロードマップ:
| フェーズ | やること | 効果 |
|---|---|---|
| Phase 1 | 検証ループの追加 | 最もコストパフォーマンスが高い改善 |
| Phase 2 | 状態永続化の追加 | 障害時のコスト30〜50%削減 |
| Phase 3 | オブザーバビリティの追加 | 問題の可視化 |
| Phase 4 | Human-in-the-loopの追加 | プロダクション安全網 |
原則 2: Build to Delete(削除できる設計)
モジュラーに設計し、いつでもコードを削除できる状態にする。
- モデルの進化で今日の最適設計が半年後に負債になる
- 「作り込む」ほどモデル更新ごとに前提が崩れて壊れる
- 「作り直せる構造」「剥がせる構造」の方が重要
原則 3: The Harness as Dataset(ハーネスはデータセット)
競合優位は「プロンプト」ではなく、実行軌跡(trajectory)の蓄積にある。
- ハーネスがどんな入力でどんな出力を生み、どこで失敗したか — これが本当の資産
- プロンプトはコピーできるが、軌跡データは短期間では蓄積できない
12. よくある障害パターン
🚨 コンテキスト腐敗(Context Rot)
長時間タスクで、エージェントのコンテキストにノイズが蓄積する現象。
症状:
- 既に解決した問題を再度解こうとする
- 自身の以前の決定と矛盾する
- 元のタスク目標を見失う
対処: 能動的なコンテキスト管理(要約・剪定)とAnthropicのProgress Fileパターン
🚨 ツール爆発(Tool Explosion)
一度に多すぎるツールへのアクセスがパフォーマンスを劣化させる現象。
症状:
- モデルがどのツールを使うか考えるのにトークンを費やす
- 誤ったツール選択が増える
- 不正なツール呼び出しが増える
対処: 動的なツールスコーピング(タスクフェーズに応じて関連ツールのみ公開)
🚨 サイレント失敗(Silent Failures)
エージェントがツールを呼び出し、エラーや空レスポンスを受け取り、成功したかのように処理を続ける最も危険なパターン。
症状:
- 下流のステップが欠損データで動作
- 一見もっともらしく見えるが間違った出力
対処: 全てのツール呼び出し後の構造化アウトプット検証
🚨 無限ループ(Infinite Loop)
エージェントがエラーにあたり、リトライし、同じエラーにあたり、永遠にリトライし続ける現象。
症状:
- 朝起きたら何千ドルものAPIコストが発生していた
対処:
- 最大リトライ回数の強制
- 指数バックオフ
- ヒューリスティックなループ検出(同じアクションを進捗なしで繰り返している場合の検知)
13. まとめ
核心メッセージ
| 従来の思い込み | Bitter Lesson の教え |
|---|---|
| モデルが賢くなれば解決する | 問題はアクション空間の不完全さ |
| 賢いフレームワークで制御する | シンプルな構造でモデルに自由を与える |
| ツールを増やせば能力が上がる | ツールを減らすと信頼性が上がる |
| 精巧なパイプラインが最良 | 削除できる設計が最良 |
| モデル選択が競合優位 | ハーネス設計が競合優位 |
設計の3原則と障害パターンの対応関係
コンテキスト管理戦略
├── Reduce(削る)
│ └── 防ぐ問題: コンテキスト腐敗(Context Rot)
├── Offload(外に出す)
│ └── 防ぐ問題: ツール爆発(Tool Explosion)
└── Isolate(隔離する)
└── 防ぐ問題: サイレント失敗・ノイズ汚染
実装の第一歩
最小限ハーネスから始める:
# エージェントの本質:シンプルなfor-loop
async def agent_loop(task: str, tools: list):
messages = [{"role": "user", "content": task}]
while True:
response = await llm.ainvoke(messages, tools)
if response.tool_calls is None:
# CLI mode: 暗黙的完了
return response.content
for tool_call in response.tool_calls:
if tool_call.name == "done":
# Autonomous mode: 明示的完了
return tool_call.args["message"]
# ツール実行 + 検証(ここがハーネスの核心)
result = await execute_and_verify(tool_call)
messages.append({"role": "tool", "content": result})
# コンテキスト管理: Reduce / Offload / Isolate
messages = context_manager.compact(messages)
最後に
Browser Use の Gregor Zunic の言葉で締めくくります:
「苦い教訓:作るものが少ないほど、うまく動く。(
The bitter lesson: The less you build, the more it works.)」
モデルは明日もっと賢くなります。だからこそ、今日の仕事は「モデルを賢く使う仕組みを作り込むこと」ではなく、「明日作り直せる構造を設計すること」にあります。
14. 参考リンク
| タイトル | 著者 | 言語 |
|---|---|---|
| The Bitter Lesson of Agent Harnesses | Gregor Zunic (Browser Use) | 🇺🇸 EN |
| The Bitter Lesson of Agent Frameworks | Gregor Zunic (Browser Use) | 🇺🇸 EN |
| The importance of Agent Harness in 2026 | Philipp Schmid (Hugging Face) | 🇺🇸 EN |
| The Complete Guide to Agent Harness | Dr. Sarah Chen | 🇺🇸 EN |
| Learning the Bitter Lesson | Lance Martin (LangChain) | 🇺🇸 EN |
| 2025 Was Agents. 2026 Is Agent Harnesses. | Aakash Gupta | 🇺🇸 EN |
| AIエージェントの勝負所は「モデル性能」ではなく「ハーネス設計」にある | hdknr | 🇯🇵 JP |
| The Bitter Lesson (Original) | Rich Sutton | 🇺🇸 EN |