AIエージェントの勝負所は「モデル性能」ではなく「ハーネス設計」にある
はじめに
2026年に入り、AIエージェント開発の世界で急速に広まっている概念がある。「Agent Harness(エージェント・ハーネス)」 だ。
LLMの性能は日々向上し、Claude Opus 4.6、GPT-5、Gemini 2.5 Pro といったモデルが次々とリリースされている。しかし、現場のエンジニアたちは気づき始めている——同じモデルを使っていても、エージェントの体感品質はまるで別物になるということに。その差を生むのがモデルの「外側」にある仕組み、すなわちAgent Harnessである。
この記事では、Philipp SchmidのAgent Harness論、Lance MartinのContext Engineering解説、そしてManusの実装例を手がかりに、エージェント開発の新しいパラダイムを整理する。
Agent Harness・AIエージェント・LLM の関係
まず、3つの概念の関係を整理する。混乱しやすいのは、これらが入れ子構造になっているからだ。
レイヤー構造
graph TB
subgraph UserLayer["ユーザー"]
U["指示を出す / 結果を受け取る"]
end
subgraph AgentLayer["AIエージェント = アプリケーション層"]
A1["ユーザー固有のロジック・目的"]
A2["例: コードアシスタント、リサーチエージェント、カスタマーサポートBot"]
end
subgraph HarnessLayer["Agent Harness = OS層"]
H1["コンテキスト管理 / ツール実行 / 権限制御"]
H2["メモリ管理 / 再試行 / フォールバック / 承認ポイント"]
end
subgraph LLMLayer["LLM = CPU層"]
L1["言語理解・推論・生成"]
L2["例: Claude Opus 4.6, GPT-5, Gemini"]
end
UserLayer --> AgentLayer
AgentLayer --> HarnessLayer
HarnessLayer --> LLMLayer
Philipp Schmidのコンピュータの比喩を使うと:
| コンピュータ | AIエージェント | 役割 |
|---|---|---|
| CPU | LLM | 処理能力そのもの。賢さの源泉 |
| RAM | コンテキストウィンドウ | 作業メモリ。揮発性で容量制限あり |
| OS | Agent Harness | リソース管理、プロセス制御、I/O |
| アプリ | AIエージェント | ユーザーが触れる最終的な製品 |
重要な点:OSがなければアプリは動かない。 同様に、Harnessなしではエージェントはまともに動作しない。同じCPU(LLM)を使っていても、OS(Harness)の出来で体感性能が全く変わるのだ。
エージェントループの実際の流れ
エージェントが1つのタスクを処理する際、内部では以下のループが回っている:
sequenceDiagram
actor User as 👤 ユーザー
participant Agent as 🤖 エージェント
participant Harness as ⚙️ Harness
participant LLM as 🧠 LLM
participant Tools as 🔧 ツール群
participant Ext as 💾 外部ストレージ
User->>Agent: タスクを依頼
Agent->>Harness: タスクを渡す
rect rgb(240, 248, 255)
Note over Harness,Ext: エージェントループ(Harnessが制御)
Harness->>Harness: コンテキスト構築<br/>(Reduce: 古い履歴を圧縮)
Harness->>Ext: 必要な情報を取得<br/>(Offload: 外部から参照)
Ext-->>Harness: 参照データ
Harness->>LLM: プロンプト送信
LLM-->>Harness: 応答(テキスト or ツール呼び出し)
alt ツール呼び出しの場合
Harness->>Harness: 権限チェック・バリデーション
alt 高リスク操作
Harness-->>User: 承認を求める
User-->>Harness: 承認 / 拒否
end
Harness->>Tools: ツール実行
Tools-->>Harness: 実行結果
Harness->>Harness: 結果を圧縮してコンテキストに追加
Note over Harness: ループ継続 → LLMに再送信
else 最終回答の場合
Harness-->>Agent: 結果を返す
end
end
Agent-->>User: 回答を表示
ここで注目すべきは、LLMは「考える」だけで、Harnessが全ての制御を担っているということだ。LLMが「ファイルを読みたい」と言っても、実際にファイルを読む判断・実行・結果の加工はすべてHarnessの仕事だ。
3者の責務の違い
graph LR
subgraph LLM["🧠 LLM の責務"]
L1[テキスト理解]
L2[推論・判断]
L3[テキスト生成]
L4[ツール選択の提案]
end
subgraph Harness["⚙️ Agent Harness の責務"]
H1[コンテキスト管理]
H2[ツール実行制御]
H3[権限・安全管理]
H4[メモリ管理]
H5[リトライ・エラー処理]
H6[サブエージェント管理]
end
subgraph Agent["🤖 AIエージェントの責務"]
A1[ユーザーとの対話]
A2[タスクの受付・提示]
A3[ドメイン固有のロジック]
end
Agent -->|依存| Harness
Harness -->|依存| LLM
一言でまとめると:
- LLM = 「考える」(推論エンジン)
- Agent Harness = 「制御する」(実行基盤・ガードレール)
- AIエージェント = 「使わせる」(ユーザー向け製品)
Claude Code ユーザーが体験する各レイヤー
抽象的な3層モデルは、Claude Code を日常的に使っているユーザーにとって「あの画面のあれか」と結びつけると理解しやすい。以下の図は、ユーザーが実際に目にする機能や画面要素を各レイヤーにマッピングしたものだ。
graph TB
subgraph You["あなた(ターミナル)"]
U1["プロンプト入力"]
U2["ツール実行の承認 / 拒否"]
U3["回答の確認"]
end
subgraph AgentL["エージェント層 — あなたが直接触れるUI"]
A1["CLIインターフェース<br/>(claude コマンド)"]
A2["スキル<br/>(/commit, /review-pr, /today 等)"]
A3["会話の表示・対話フロー"]
A4["CLAUDE.md<br/>(プロジェクト固有の指示書)"]
end
subgraph HarnessL["Harness 層 — 裏側で自動的に動く制御基盤"]
H1["コンテキスト自動圧縮<br/>(会話が長くなると発動)"]
H2["ツール実行と権限管理<br/>(Read, Edit, Bash 等の許可制御)"]
H3["サブエージェント<br/>(Agent ツールによる並列調査)"]
H4["Auto Memory<br/>(~/.claude/memory/ への自動記憶)"]
H5["settings.json / permissions<br/>(allowlist, denylist)"]
end
subgraph LLML["LLM 層 — モデルそのもの"]
L1["/model で切り替え可能"]
L2["Opus 4.6 = 高精度・低速"]
L3["Sonnet 4.6 = バランス型"]
L4["Haiku 4.5 = 高速・低コスト"]
end
You --> AgentL
AgentL --> HarnessL
HarnessL --> LLML
具体的な対応表
普段のClaude Code操作が、どのレイヤーに対応するかを一覧にまとめる。
| あなたの操作・体験 | レイヤー | 役割 |
|---|---|---|
ターミナルで claude を起動する | エージェント | CLIアプリケーションの起動 |
/commit /review-pr 等のスキルを使う | エージェント | ドメイン固有のワークフロー |
CLAUDE.md にプロジェクトルールを書く | エージェント | エージェントへの指示書 |
| ツール実行時に「Allow / Deny」を選ぶ | Harness | 権限制御・承認ポイント |
settings.json で許可ツールを設定する | Harness | ガードレールの設定 |
| 会話が長くなると「messages compressed」と出る | Harness | コンテキスト自動圧縮(Reduce) |
| 「Agent: exploring codebase…」と表示される | Harness | サブエージェント起動(Isolate) |
~/.claude/memory/ に知識が保存される | Harness | メモリ管理(Offload) |
Read Edit Bash 等のツールが実行される | Harness | ツール実行制御 |
/model でモデルを切り替える | LLM | 推論エンジンの選択 |
| Opus / Sonnet / Haiku の応答品質の違い | LLM | モデル固有の能力差 |
ユーザー体験から見た3原則の発動タイミング
sequenceDiagram
actor You as あなた
participant CC as Claude Code
participant Harness as Harness(裏側)
You->>CC: 大きなリファクタリングを依頼
Note over Harness: Offload 発動
Harness->>Harness: CLAUDE.md を読み込み<br/>(外部ファイルから参照)
Note over Harness: Isolate 発動
CC->>You: 「Agent: exploring codebase...」
Harness->>Harness: サブエージェントで<br/>コードベースを並列調査
Harness->>Harness: 結論だけメインに返す
CC->>You: 修正計画を提示
You->>CC: 承認
loop ファイル修正ループ
CC->>You: 「Edit src/foo.ts」(許可を求める)
You->>CC: Allow
Harness->>Harness: ツール実行・結果を記録
end
Note over Harness: Reduce 発動
Harness->>Harness: 古いツール結果を圧縮
CC->>You: 「messages compressed」
CC->>You: 修正完了の報告
つまり、Claude Code ユーザーはすでに日常的にHarnessの恩恵を受けている。「会話が圧縮された」「サブエージェントが調査している」「ツール実行の許可を求められた」——これらすべてがHarness層の仕事だ。ユーザーが意識せずとも、Harnessが品質を支えている。
Harnessの設計思想——Bitter Lesson が教えること
前のセクションで、Harnessがエージェントの品質を左右する重要なレイヤーだと確認した。では、そのHarnessをどう設計すべきか? 自然に浮かぶのは「最高のHarnessを作り込もう」という発想だろう。複雑な条件分岐、巧妙なプロンプトハック、精緻なルール体系…。
しかし、ここでAI研究の歴史的教訓が立ちはだかる。
Bitter Lesson とは
Rich Suttonの「The Bitter Lesson」は、AI研究における金言だ。汎用的な計算手法は、最終的には手作りの賢さ(ドメイン知識やヒューリスティクス)を上回る。 チェスAIも画像認識も、人間が組み込んだ知識より、計算量の力押しが勝った。
この教訓がいま、エージェント開発にもそのまま当てはまっている。モデルが急速に賢くなるため、Harness側に組み込んだ「補助的な賢さ」がすぐ不要になるのだ。
実例:繰り返される「作り直し」
- Manus: 2024年3月の公開以降、5回アーキテクチャを作り直した
- LangChain Open Deep Research: 1年間で3回全面再構築
- Vercel: エージェントツールの80%を削除して性能向上
モデルの進化が速すぎて、今日の最適な設計が半年後には負債になる。作り込むほど、モデル更新のたびに前提が崩れて壊れる。
パラドックス:「Harnessは重要だが、賢く作ってはいけない」
ここに本セクションの核心がある。
graph LR
A["Harnessは重要だ"] --> B["では最高のHarnessを<br/>作り込もう?"]
B --> C["Bitter Lesson:<br/>モデルが賢くなると<br/>その工夫は不要になる"]
C --> D["結論: シンプルに作り<br/>作り直せるようにしろ"]
D --> E["→ 3原則<br/>Reduce / Offload / Isolate"]
結論:作り込みより「作り直せる構造」「剥がせる構造」が重要。
この教訓から導かれる設計原則は3つだ:
- Start Simple — 複雑な制御フローを避け、堅牢な原子的ツールを提供する
- Build to Delete — モジュラーに設計し、いつでもコードを削除できる状態にする
- The Harness as Dataset — 競争優位はプロンプトではなく、実行軌跡(trajectory)の蓄積にある
3原則はなぜ「シンプルさ」を志向するのか
Bitter Lesson があるからこそ、この後に続く3原則が「賢さ」ではなく「シンプルさ」を志向している意味がわかる。
| 原則 | 「作り込み」のアプローチ | Bitter Lesson 後のアプローチ |
|---|---|---|
| Reduce | 複雑なルールで何を残すか判断 | 閾値を超えたら機械的に圧縮 |
| Offload | RAGパイプラインで高度な検索 | ファイルに保存して grep で参照 |
| Isolate | 精密なタスク分類ロジック | サブエージェントに丸投げして結論だけ受け取る |
右列の「雑に見えるやり方」が勝つのは、モデルが賢くなるにつれて左列の精巧な仕組みが不要になるからだ。Harnessの仕事は「賢く判断すること」ではなく「シンプルな枠組みを提供すること」——これが次のセクション以降を読むための前提になる。
Harnessの最大の仕事——コンテキスト管理
Harnessは「シンプルな枠組みを提供する」と述べた。では、そのシンプルな枠組みの中で最も重要な仕事は何か? それがコンテキストの状態管理だ。
LLMは与えられたコンテキスト(プロンプト + 過去の会話 + ツール結果)だけを頼りに思考する。つまり、コンテキストの質 = LLMの判断の質 である。どんなに優れたモデルでも、ゴミだらけのコンテキストを渡されれば、ゴミのような判断しかできない。
コンテキストを「何を入れ、何を捨て、どこに逃がすか」——この管理こそがHarnessの中核的な責務であり、エージェントの品質を直接左右する。
なぜコンテキストがボトルネックになるのか
しかし、エージェントが長時間タスクを実行すると、ツール結果やログがコンテキストに蓄積され、管理なしでは破綻する。これが引き起こす3つの問題:
- コスト増大 — トークン数に比例してAPI費用が膨らむ
- レイテンシ悪化 — 長いコンテキストは推論時間を増加させる
- 品質劣化(Context Rot) — 100万トークンのコンテキストウィンドウがあっても、情報が増えすぎるとモデルの指示追従が落ち、ノイズに判断が鈍る
graph LR
subgraph problem["コンテキスト膨張の悪循環"]
direction TB
T1["ツール呼び出し #1"] --> C1["結果をコンテキストに追加"]
C1 --> T2["ツール呼び出し #2"]
T2 --> C2["結果をコンテキストに追加"]
C2 --> T3["... #50"]
T3 --> C3["コンテキスト肥大化"]
C3 --> P1["コスト爆発"]
C3 --> P2["レイテンシ悪化"]
C3 --> P3["Context Rot(品質劣化)"]
end
Philipp Schmidは「Pre-Rot閾値」を256kトークンに設定することを推奨している。つまり、コンテキストウィンドウの限界まで使おうとしてはいけない。遥か手前で品質劣化が始まる。
放置すれば必ず破綻する。だからこそ、Harnessがコンテキストを能動的に管理する必要がある。その具体的な手法が次の3原則だ。
コンテキスト設計の3原則
コンテキスト膨張という問題に対し、Harnessは Reduce・Offload・Isolate という3つのシンプルな原則で対処する。「賢く判断する」のではなく「機械的に制御する」——Bitter Lessonの教訓どおりだ。
graph TB
subgraph Main["メインエージェントのコンテキスト"]
direction TB
Current["現在の判断に必要な情報だけ"]
end
subgraph Reduce["① Reduce(削る)"]
direction TB
R1["古いツール結果を要約に圧縮"]
R2["長い履歴を現在地だけ残す"]
end
subgraph Offload["② Offload(外に出す)"]
direction TB
O1["全文ログをファイル/DBへ"]
O2["根拠資料を外部ストレージへ"]
O3["必要時だけ参照"]
end
subgraph Isolate["③ Isolate(隔離する)"]
direction TB
I1["調査をサブエージェントAへ"]
I2["要約をサブエージェントBへ"]
I3["コード生成をサブエージェントCへ"]
I4["結論だけメインに返す"]
end
Reduce -->|圧縮済み情報| Main
Offload -->|参照リンクのみ| Main
Isolate -->|結論のみ| Main
原則① Reduce(削る)
古い情報を要約・圧縮して置き換える。
- Compaction(可逆的): ツール結果からファイルパスのみを保持し、中身を削除する。必要時に再取得可能
- Summarization(非可逆的): 一定の閾値(例:128kトークン)を超えたら、LLMで過去の履歴を要約に変換。最新のツール呼び出し結果だけは生のまま保持
狙い:未来の判断に不要な情報を切り落とし、精度と速度を守る。
Claude Codeでは、会話がコンテキスト制限に近づくと自動的にメッセージを圧縮する仕組みが実装されている。
原則② Offload(外に出す)
プロンプトに詰め込むのではなく、外部に退避する。
- 全文ログや根拠資料はDB、ファイルシステム、ログサービスに保存
- 必要な時だけ参照する設計にして、常時コンテキストを太らせない
- ツールは増やしすぎない — Manusは20個未満の原子的ツールに限定
Manusの実装では、ツールを3段階の階層で設計している:
- Level 1:
file_write、bash、search等の基本ツール - Level 2: CLI コマンドラップ(
mcp-cli) - Level 3: コードライブラリの直接実行
Bash のような汎用ツール1つで「行動空間」を確保し、専用ツールを大量に定義してコンテキストを圧迫する設計を避けている。
原則③ Isolate(隔離する)
トークンを大量消費する作業をサブエージェントに切り出す。
Go言語の並行処理の格言がそのまま当てはまる:「メモリ共有で通信するな、通信でメモリ共有しろ。」
graph TB
Main["メインエージェント<br/>(判断・統括)"]
Sub1["調査エージェント"]
Sub2["要約エージェント"]
Sub3["コード生成エージェント"]
Main -->|"タスクを委譲"| Sub1
Main -->|"タスクを委譲"| Sub2
Main -->|"タスクを委譲"| Sub3
Sub1 -->|"結論だけ返す"| Main
Sub2 -->|"要約だけ返す"| Main
Sub3 -->|"成果物だけ返す"| Main
Sub1 -.->|"独自コンテキスト(汚染されない)"| Sub1
Sub2 -.->|"独自コンテキスト(汚染されない)"| Sub2
Sub3 -.->|"独自コンテキスト(汚染されない)"| Sub3
Manusのマルチエージェント構成:
- プランナー: タスク割り当てと全体統括
- 知識管理者: 会話レビューとファイルシステム更新の判定
- エグゼキューター: 個別コンテキストを持つサブエージェント
メインエージェントには「結論・判断材料だけ」が返る。調査、要約、コード生成、評価、デバッグなどの重い作業はすべてサブエージェントに委譲される。
狙い:ノイズ汚染を防ぎ、失敗時の原因切り分けも容易にする。
エージェント開発の2つの難所
難所① 評価と観測(Observability)
AIエージェントの出力は非決定的だ。同じ入力でも異なる結果が返る。これを「どう測って改善するか」が最大の壁になる。
- 既存のベンチマークはシングルターンの出力しか評価できない
- 実運用では「50回目、100回目のツール呼び出し後にモデルがどう振る舞うか」が問題になる
- ベンチマークより、実運用ログ・失敗パターンから学ぶ比重が大きい
- 評価設計が弱いと、改善が「気合い」になる
Philipp Schmidは「モデルドリフト」——長時間実行中にモデルの指示追従が劣化する現象——を次のフロンティアと位置づけ、Harnessがモデルの「疲労」を検出する仕組みの必要性を指摘している。
難所② 自律性の設計
ワークフロー(手順固定)とエージェント(道筋選択)は連続体上にある。すべてを自律化すると事故が起きる。
graph LR
W["ワークフロー<br/>(手順固定)"]
H["ハイブリッド<br/>(部分自律)"]
A["フルエージェント<br/>(完全自律)"]
W -->|"自律性が増す"| H
H -->|"自律性が増す"| A
W ---|"安全・予測可能"| W
H ---|"柔軟 + 制御"| H
A ---|"高リスク"| A
リスクが高い操作ほど、人間の承認ポイントとフィードバックループが必須だ。
CNCFの4本柱フレームワークが参考になる:
- Golden Paths: 事前承認済みの構成(承認済みモデル、許可ツール)
- Guardrails: 強制的なポリシー(コスト上限、実行時間制限、ツールホワイトリスト)
- Safety Nets: 自動リカバリ(リトライ、フォールバック、サーキットブレーカー)
- Manual Review: 高リスク判断への人間のゲート
Claude Codeでは、ファイル削除やgit push –forceなど破壊的操作の前にユーザー確認を求める設計がまさにこの思想を体現している。
Claude Code に見るHarness設計の実践
Claude Code は、Agent Harness設計の優れた実践例だ。以下の図は、Claude Code のアーキテクチャをHarnessの観点で整理したものである。
graph TB
User["ユーザー(CLI)"]
subgraph AgentLayer["エージェント層"]
Session["会話セッション管理"]
Skills["スキル(/commit, /review 等)"]
end
subgraph HarnessLayer["Harness 層"]
CtxMgr["コンテキスト管理<br/>(自動圧縮・Compaction)"]
ToolExec["ツール実行エンジン<br/>(Read, Edit, Bash, Grep...)"]
Perm["権限システム<br/>(plan / default / bypass)"]
SubAgent["サブエージェント管理<br/>(Agent ツール・Isolate)"]
Memory["メモリ管理<br/>(CLAUDE.md / Auto Memory)"]
end
subgraph LLMLayer["LLM 層"]
Claude["Claude Opus 4.6 / Sonnet / Haiku"]
end
User --> AgentLayer
AgentLayer --> HarnessLayer
HarnessLayer --> LLMLayer
SubAgent -.->|"独立コンテキスト"| LLMLayer
- Context Compaction(Reduce): 会話がコンテキスト制限に近づくと自動でメッセージを圧縮
- Tool Isolation(Isolate): Agent ツールでサブエージェントを起動し、重い調査をメインコンテキストから隔離
- Atomic Tools(Offload):
Read、Edit、Write、Grep、Globなど原子的なツールセット。結果はファイルシステムに存在し、必要時に参照 - Permission System: 自律性レベルを段階的に制御(plan mode → default → bypass)
- Memory Management:
CLAUDE.mdと Auto Memory による永続的な知識管理
まとめ:賢さを足すより、コンテキストを制御する
2026年のAIエージェント開発で勝負を分けるのは、モデル選択ではない。モデルの外側にあるHarness設計だ。
graph TB
subgraph summary["Agent Harness = エージェントの品質を決める制御基盤"]
direction LR
subgraph R["① Reduce"]
R1["捨てる・圧縮する"]
R2["判断精度と速度の維持"]
end
subgraph O["② Offload"]
O1["外に逃がす"]
O2["コンテキスト膨張の防止"]
end
subgraph I["③ Isolate"]
I1["別コンテキストに隔離"]
I2["ノイズ汚染の防止"]
end
end
R --> O --> I
I --> Result["同じLLMでも体感品質が別物に"]
これを前提に、評価で回し、モデル進化に合わせてHarnessを作り直せるようにする。
最大の成果は「複雑さの追加」ではなく「複雑さの削除」から生まれる。Manusチームの言葉を借りれば:
「複雑なRAGパイプラインではなく、要素を削除することで性能向上を達成した。」
モデルは明日もっと賢くなる。だからこそ、今日の仕事は「モデルを賢く使う仕組み」ではなく、「明日作り直せる構造」を設計することにある。
参考リンク
- The importance of Agent Harness in 2026 - Philipp Schmid
- Context Engineering for AI Agents: Part 2 - Philipp Schmid
- AI Agent Harness, 3 Principles for Context Engineering, and the Bitter Lesson Revisited - Hugo Bowne-Anderson
- Context Engineering in Manus - Lance Martin
- Agent Harnesses: Why 2026 Isn’t About More Agents — It’s About Controlling Them - DEV Community
- AIエージェントの性能差のキー、ハーネスエンジニアリング - Seiji Takahashi