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エージェント役割
CPULLM処理能力そのもの。賢さの源泉
RAMコンテキストウィンドウ作業メモリ。揮発性で容量制限あり
OSAgent 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つだ:

  1. Start Simple — 複雑な制御フローを避け、堅牢な原子的ツールを提供する
  2. Build to Delete — モジュラーに設計し、いつでもコードを削除できる状態にする
  3. The Harness as Dataset — 競争優位はプロンプトではなく、実行軌跡(trajectory)の蓄積にある

3原則はなぜ「シンプルさ」を志向するのか

Bitter Lesson があるからこそ、この後に続く3原則が「賢さ」ではなく「シンプルさ」を志向している意味がわかる。

原則「作り込み」のアプローチBitter Lesson 後のアプローチ
Reduce複雑なルールで何を残すか判断閾値を超えたら機械的に圧縮
OffloadRAGパイプラインで高度な検索ファイルに保存して grep で参照
Isolate精密なタスク分類ロジックサブエージェントに丸投げして結論だけ受け取る

右列の「雑に見えるやり方」が勝つのは、モデルが賢くなるにつれて左列の精巧な仕組みが不要になるからだ。Harnessの仕事は「賢く判断すること」ではなく「シンプルな枠組みを提供すること」——これが次のセクション以降を読むための前提になる。


Harnessの最大の仕事——コンテキスト管理

Harnessは「シンプルな枠組みを提供する」と述べた。では、そのシンプルな枠組みの中で最も重要な仕事は何か? それがコンテキストの状態管理だ。

LLMは与えられたコンテキスト(プロンプト + 過去の会話 + ツール結果)だけを頼りに思考する。つまり、コンテキストの質 = LLMの判断の質 である。どんなに優れたモデルでも、ゴミだらけのコンテキストを渡されれば、ゴミのような判断しかできない。

コンテキストを「何を入れ、何を捨て、どこに逃がすか」——この管理こそがHarnessの中核的な責務であり、エージェントの品質を直接左右する。

なぜコンテキストがボトルネックになるのか

しかし、エージェントが長時間タスクを実行すると、ツール結果やログがコンテキストに蓄積され、管理なしでは破綻する。これが引き起こす3つの問題:

  1. コスト増大 — トークン数に比例してAPI費用が膨らむ
  2. レイテンシ悪化 — 長いコンテキストは推論時間を増加させる
  3. 品質劣化(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_writebashsearch 等の基本ツール
  • 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本柱フレームワークが参考になる:

  1. Golden Paths: 事前承認済みの構成(承認済みモデル、許可ツール)
  2. Guardrails: 強制的なポリシー(コスト上限、実行時間制限、ツールホワイトリスト)
  3. Safety Nets: 自動リカバリ(リトライ、フォールバック、サーキットブレーカー)
  4. 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): ReadEditWriteGrepGlob など原子的なツールセット。結果はファイルシステムに存在し、必要時に参照
  • 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パイプラインではなく、要素を削除することで性能向上を達成した。」

モデルは明日もっと賢くなる。だからこそ、今日の仕事は「モデルを賢く使う仕組み」ではなく、「明日作り直せる構造」を設計することにある。


参考リンク