AI Agent における Harness と Model の役割分担

Multi Agent が広がる背景にある、Model と Harness の責任の再配置を、時系列と Sub-agent as tool パターンを軸に整理してみる

ogawaMay 1, 2026

Multi Agent という言葉をよく聞くようになりました。リサーチを並列で進めたり、書いたコードを別の AI にレビューさせたり、長時間かかるタスクを分担して進めたりと、複数の AI が協力することで AI に任せられる仕事の幅は確実に広がっています。

こうした進化の背景には、Model(考える AI 部分)と Harness(Model を動かす外側の仕組み)の役割分担が、ここ 1〜2 年で大きく変わってきているという事情があります。Harness とは Model を呼び出すループや、ツール実行、会話履歴の管理など、Model が単発でできないことを引き受けている部分のことです。

本記事では、Multi Agent 周辺の動向をこの役割分担の変化という視点で整理してみます。

そもそも LLM とどうやってやり取りしているのか

Agent の話に入る前に、まず LLM(Large Language Model、以下 Model と表記)そのものがどう動いているのかを押さえておきます。これが後の話の土台になります。

Claude のような Model を、自分のアプリから使う場合、やっていることは意外と素朴です。HTTPS で JSON を送り、JSON が返ってくるだけです。

リクエストとレスポンスの基本形

例として、Anthropic の Claude にメッセージを送るときのリクエストはこんな形をしています。

POST https://api.anthropic.com/v1/messages
Authorization: Bearer sk-ant-...
Content-Type: application/json
 
{
  "model": "claude-opus-4-7",
  "max_tokens": 1024,
  "messages": [
    {"role": "user", "content": "東京の天気を教えてください"}
  ]
}

レスポンスもただの JSON で返ってきます。

{
  "id": "msg_01ABC...",
  "type": "message",
  "role": "assistant",
  "content": [
    {"type": "text", "text": "東京の天気についてですが、リアルタイムの情報は持っていないため..."}
  ],
  "stop_reason": "end_turn",
  "usage": {"input_tokens": 18, "output_tokens": 42}
}

つまり、Model の利用は Web API を叩くのとほとんど同じで、HTTP クライアントが上記のようなリクエストを送っているだけです。

Model は Stateless

ここで一つ大事な性質があります。Model そのものは Stateless で、過去のやり取りを何も覚えていません。会話を覚えているように見えるのは、アプリ側が会話履歴を保持していて、毎回それを全部送り直しているからです。

たとえば、2 回目のやり取りではこうなります。

{
  "model": "claude-opus-4-7",
  "max_tokens": 1024,
  "messages": [
    {"role": "user", "content": "東京の天気を教えてください"},
    {"role": "assistant", "content": "東京の天気についてですが..."},
    {"role": "user", "content": "じゃあ大阪は?"}
  ]
}

messages の配列に、これまでの全履歴が入っているのが分かるかと思います。Model は毎回これを丸ごと受け取って、最後の発言に対する応答を返しています。

このシンプルな仕組みが、後で出てくる Harness の話に効いてきます。会話を覚える役割は Model 本体ではなくその外側のコードが担っている、という構造になっています。

ツールを使わせる (tool use)

Model ができるのはテキストを返すことだけ、というイメージがあるかもしれません。しかし最近の Model は、このツールを使ってくださいと指示を返すこともできます。これを tool use と呼びます。

たとえば、ユーザーが東京の天気を聞いてきた場合に、Model に天気取得ツールを使わせたいとします。リクエストにツール定義を加えます。

{
  "model": "claude-opus-4-7",
  "max_tokens": 1024,
  "tools": [
    {
      "name": "get_weather",
      "description": "指定された都市の現在の天気を取得します",
      "input_schema": {
        "type": "object",
        "properties": {
          "city": {"type": "string", "description": "都市名"}
        },
        "required": ["city"]
      }
    }
  ],
  "messages": [
    {"role": "user", "content": "東京の天気を教えてください"}
  ]
}

すると Model は、テキストで答えるのではなく、get_weather というツールを {"city": "東京"} で呼んでほしい、という構造化された応答を返してきます。

{
  "content": [
    {
      "type": "tool_use",
      "id": "toolu_01XYZ...",
      "name": "get_weather",
      "input": {"city": "東京"}
    }
  ],
  "stop_reason": "tool_use"
}

ここがポイントなのですが、Model は実際に天気を取得するわけではありません。このツールを呼びたい、と言うだけです。実際にツールを実行するのはアプリ側の責任です。

アプリ側で get_weather を実行して結果を得たら、それを tool_result として履歴に追加して再度 Model に送ります。

{
  "model": "claude-opus-4-7",
  "max_tokens": 1024,
  "tools": [...],
  "messages": [
    {"role": "user", "content": "東京の天気を教えてください"},
    {
      "role": "assistant",
      "content": [
        {"type": "tool_use", "id": "toolu_01XYZ...", "name": "get_weather", "input": {"city": "東京"}}
      ]
    },
    {
      "role": "user",
      "content": [
        {
          "type": "tool_result",
          "tool_use_id": "toolu_01XYZ...",
          "content": "晴れ、22℃"
        }
      ]
    }
  ]
}

これを受け取った Model は、東京は晴れで気温は 22℃ です、のような自然なテキストを返してくれます。

このやり取りを繰り返すのが Agent

ここまでをまとめると、Model とアプリのやり取りはこういう構造になっています。

  1. アプリが Model にメッセージを送る
  2. Model がツールを使いたいと返す
  3. アプリがツールを実行する
  4. アプリが結果を履歴に追加して、もう一度 Model に送る
  5. Model が次の判断(さらにツールを使う、または最終回答)を返す
  6. 終了条件まで繰り返す

このツール呼び出しを含むループこそが、最近よく聞く Agent の最も基本的な仕組みです。ポイントは、どのツールをいつ呼ぶかを決めているのは Model 側だ、ということです。アプリ側は使えるツールの一覧を渡しているだけで、その中から何をどの順番で呼ぶかは Model が判断する。アプリは Model の判断に従ってツールを実行し、結果を渡し返している、という関係になります。

つまり、何をするかの判断は Model、それを動かすための段取り(API を叩く、ツールを実行する、結果を履歴に追加する、続けるか終わるかを判定する)はアプリ側、という分業です。次のセクションでは、この段取りを担っている Harness について見ていきます。

Harness が担う仕事

Model とのやり取りは、メッセージを送る → 応答を受け取る → ツールを実行する → 結果を含めてもう一度送る、というループの繰り返しです。このループを実際に回しているプログラムのことを Harness と呼びます。

Harness が担っていること

具体的に Harness が何をしているかというと、こんな感じです。

  • Model の API を叩く(HTTPS リクエストを送る)
  • 会話履歴を保持して、毎回それを送り直す
  • Model が tool use を返してきたら、対応するツールを実行する
  • ツールの結果を tool_result として履歴に追加する
  • 終了条件(最終回答が出た、ターン数の上限に達した、など)を判定する
  • エラーが起きたらリトライする

Model は何も覚えていない、覚えているのは外側のコードでした。その外側のコードが Harness です。Model そのものは次に何をすべきかを判断するだけで、それ以外のすべては Harness の責任になります。

Agent / Harness / Model の関係

ここまでで Agent / Harness / Model という 3 つの言葉が出てきたので、整理しておきます。

  • Model : 判断する側。次に何をすべきか(テキストで答えるか、どのツールを呼ぶか)を返す。
  • Harness : 段取りをする側。Model の API を叩き、ツールを実行し、履歴を管理する。
  • Agent : Model と Harness とツールを合わせた全体。ユーザーから見たときの 1 つの動くもの。

判断は Model、段取りは Harness、合わせて Agent、というシンプルな関係です。なお、Harness が回している、観察 → 判断 → 実行 → 観察、というサイクル自体は Agentic loop と呼ばれることもありますが、本記事では Harness 側の実装の話に焦点を当てます。

Model が賢くなれば Harness は不要になるのか

Model が賢くなれば Harness は要らなくなるのでは?と思うかもしれません。実際、最近の SDK には Harness を最小限にする、という設計思想のものもあります。

ただ、現実には Harness が消えるどころか、別の方向で複雑になり続けています。会話履歴が長くなりすぎたときの圧縮、長時間動かすための状態保存、人間の承認を挟む仕組み、複数の Sub-agent の調整、など、Model が単発で扱えない領域がどんどん Harness の責任になってきました。

このあたりの、Model が賢くなることで Harness のどこが軽くなり、どこが重くなったかを、次のセクションでは時系列で追いかけてみます。

Model 進化の歴史(何が Model 側に移ったか)

ここまでで、Model と Harness のやり取り、Harness が担っている仕事の概観を見てきました。実はここで見た仕組みは、Model が今のように賢くなる前は、もっと違う形で動いていました。

最近 1〜2 年の Model の進化に伴って、それまで Harness が担っていた仕事の一部が Model 側に移っていくという動きが起きています。このセクションでは、その流れを 4 つの転換点で追ってみます。

転換点 1 : ReAct パターン(2022 年 10 月)

最初の転換点は、Google の研究者が発表した ReAct という論文です。Thought(思考)→ Action(行動)→ Observation(観察)を交互に繰り返させる、というプロンプトの書き方を提案しました。

当時はまだ Model がツール呼び出しを構造化された形で返す機能を持っていませんでした。なので、Harness 側で頑張る必要がありました。

  • プロンプトに、次のフォーマットで答えてください、というテンプレートを書く
  • Model の応答テキストを正規表現でパースして、Action を抽出する
  • Observation の形式に合わせて結果を整形して、もう一度 Model に送る

つまりこの時代は、Model にどう振る舞ってほしいかを Harness が文字列レベルで指示し、応答も文字列レベルで解釈する必要がありました。

転換点 2 : Function calling と Tool use(2023 年 6 月〜2024 年 5 月)

2023 年 6 月、OpenAI が Function calling を発表しました。これは Model が構造化された JSON でツール呼び出しを返せるようになった、という変化です。2024 年 5 月には Anthropic も Claude 3 で同じ機能 (tool use) を一般公開しました

これで何が変わったかというと、ReAct 時代に Harness がやっていたテンプレート設計と正規表現パースが Model 側に吸収されたわけです。

前のセクションまでに見た tool_use ブロックや tool_result の往復は、まさにこの仕組みの上に成り立っています。Model が、get_weather を {"city": "東京"} で呼んでください、と JSON で返してくれるので、Harness はそれをそのまま辞書として扱える。文字列処理から解放されました。

ただし、ループを回す責任そのものは Harness に残っています。Model がツールを呼びたいと言うだけで、実際にツールを実行して結果を履歴に追加して再度送るのは、依然として Harness の仕事です。

転換点 3 : Reasoning モデルの登場(2024 年 9 月)

2024 年 9 月、OpenAI が o1 というモデルを発表しました。これは、応答する前に内部で多段階の推論をする、という新しいタイプの Model で、Reasoning モデルと呼ばれるカテゴリの始まりになりました。

それまでの Model は、聞かれたら即答するだけでした。o1 以降は、複雑な問題に対しては、まず内部で考える時間を取って、その後で答えることができるようになりました。

ここで Model 側に移ったのは、ツール選択や次の手順の判断の質です。Reasoning モデル登場前は、Model 単体の判断力が頼りないことを前提に、Plan-and-Execute や Reflexion のように思考と実行を別コールで分けて補強するパターンが多用されていました。Reasoning モデルでは内部で多段の推論が走るので、こうした思考補強のための追加コールを Harness 側で挟まなくても、1 回の Model コールで深い思考が済むケースが増えています(これらのパターンが消えたわけではなく、コスト最適化や複雑な計画立案では今も使われます)。

ReAct や function calling の時代は、Model の判断が頼りないことを前提に、Harness 側で次に何をすべきかを構造的にサポートしていました。LangChainLangGraph のように、フローを明示的にコードで書くフレームワークが主流だった理由でもあります。

Reasoning モデルの登場で、Model 自身に深く考えさせれば Harness で構造を強制しなくてもうまく回るのでは?という発想が成立するようになりました。2025 年に登場した AWS Strands Agents や Anthropic Claude Agent SDK のような、Harness を薄くして Model に判断を委ねる思想のフレームワークは、この流れの上にあります。

転換点 4 : Adaptive thinking(2026 年 2 月)

そして直近の転換点が、2026 年 2 月に Claude Opus 4.6 で導入された Adaptive thinking です。

それまでの Reasoning モデルは、どれくらい深く考えるかを開発者が手動で設定する必要がありました(Anthropic の場合、max_thinking_tokens というパラメータで、最大 10,000 トークンまで考えていい、のように指定)。

Adaptive thinking では、Model 自身が、考えるか / どれくらい考えるか / いつツールを呼ぶかを動的に判断するようになりました。簡単な質問には軽く答え、複雑な問題には時間をかけて深く考える。これを Model が自分で決めます。

開発者が指定するのは thinking_level (low / medium / high / max) という大まかな指針だけで、具体的な思考量の調整は Model に任せる、という形です。

ここで Model 側に移ったのは、思考の深さの制御です。それまで Harness が頑張って調整していた、どこで深く考えさせるか、どこで省力化するか、が Model 自身の判断に委ねられるようになりました。

一枚で見る

年月出来事Model 側に移ったもの
2022 年 10 月ReAct パターン(まだ Model にツール使用能力なし)
2023 年 6 月〜2024 年 5 月OpenAI Function calling / Anthropic Tool useテンプレート設計、テキストパース
2024 年 9 月OpenAI o1 (Reasoning)ツール選択や次手の判断の質
2025 年 2 月Claude 3.7 Extended thinking思考量を手動で指定できるように
2026 年 2 月Claude Opus 4.6 Adaptive thinking思考の深さの制御

この時系列を踏まえて、次のセクションでは、具体的にどんな新しいパターンが可能になったかを 1 つ取り上げてみます。それが Sub-agent as tool。ツールを呼び出す感覚で、別の Agent を呼び出すパターンです。

Sub-agent as tool

Model の進化が新しいパターンを可能にした例として、Sub-agent as tool を取り上げます。Reasoning モデルや Adaptive thinking で親 Agent が Sub-agent を呼び分ける判断を Model 自身に任せられるようになったことで、ようやく実用化が進んだパターンです。

ここまで見てきた Harness + Model + ツールの組み合わせは、1 つの Agent を構成しています。Sub-agent as tool は、この Agent(以下、親 Agent)が、ツールを呼ぶのと同じ感覚で別の Agent(Sub-agent)を呼び出す、というパターンです。

どういう仕組みか

先ほど見たツール呼び出しの仕組みを思い出してください。Model が tool_use で、このツールを呼びたい、と返してきて、Harness がそれを実行して tool_result で結果を返す、というやり取りでした。

Sub-agent as tool は、このツールの実行の中身を、もう一つの Model 呼び出しのループにするだけのアイデアです。親 Agent から見れば普通のツール呼び出しに見えますが、その中身は独立したコンテキストで動く別の Agent になっている、という構造です。

たとえば、記事を書く執筆 Agent が、出来上がった文章を検証 Agent に評価してもらうケースを考えます。執筆 Agent から見ると verify_article というツールを呼んでいるだけですが、そのツールの実装は検証 Agent が独自にウェブ検索したりして文章を検証する小さなループになっている、というイメージです。

なぜこのパターンが注目されるのか

このパターンが注目される理由はいくつかあります。大きなものとして次の 3 つです。

  • Model が呼び分けを判断する : ツールと同じインターフェースで Sub-agent を呼ぶので、いつ・どの Sub-agent を呼ぶかの判断は親 Agent の Model に任せられます。Harness 側で、この条件ならこの Agent、と分岐を書く必要がありません。
  • コンテキストの分離 : Sub-agent を呼び出すと、内部での詳細なやり取り(ウェブ検索を 10 回繰り返した、など)は親には見えず、最終結果だけが返ってきます。親のコンテキストを綺麗に保てます。
  • 実装の単純さ : 親から見れば普通のツール呼び出しなので、既存のツール呼び出しの仕組みをそのまま再利用できます。新しい呼び出しプロトコルや状態管理を追加で設計する必要がありません。

これらを通じて、Multi Agent 一般の利点(並列化、専門化)も、シンプルな実装のまま享受できるところがポイントです。

Anthropic が 2025 年 6 月に公開した Research システムの解説記事では、この設計によって 単一 Agent と比べて性能が向上した(社内評価で +90.2%) と報告されています。一方でトークン消費量は約 15 倍になったとも書かれていて、トレードオフがあることも示されています。

このパターンが定着するまでの流れ

このパターン自体は急に出てきたわけではなく、徐々に形になってきました。

  • 2023 年 10 月 : Microsoft の AutoGen で、Agent の中で別の Agent 群との会話を実行する Nested Chats が提供される
  • 2024 年 1 月 : LangGraph 公式ブログで、Supervisor は他の Agent をツールとして持つ Agent とも考えられる、という言及
  • 2024 年 12 月 : Anthropic が Building Effective AgentsOrchestrator-Workers パターンを命名。サブ Model 呼び出しを使うワークフローの定型として整理
  • 2025 年 3 月 : OpenAI Agents SDKAgent.as_tool() という形で、Agent をツールにラップする API を一級概念として提供
  • 2025 年 6 月 : Anthropic が Research システムの内部構造を公開。親 Agent が Task ツール経由で並列に Sub-agent を起動する、という具体例として大きな影響
  • 2025 年 7 月 : LangChain も Deep Agents という別パッケージで似た API を提供(明示的に Claude Code を参考にしたとされる)
  • 2025 年 9 月 : Claude Agent SDKagents パラメータと Agent ツール(旧 Task ツール)として API レベルで体系化

ここまでで分かるのは、主要なフレームワークがほぼすべて、何らかの形で Sub-agent as tool に対応しているということです。OpenAI Agents SDKClaude Agent SDK、LangChain (Deep Agents)、LangGraphAutoGenCrewAI。実装の細部は違いますが、親 Agent が Model の判断で Sub-agent を起動する、という構造は共通になっています。

ただし、各フレームワークが採用している設計思想には違いがあります。同じ Sub-agent as tool パターンでも、フローを誰が決めるかについては考え方が分かれていて、これは後のセクションでもう少し詳しく見ていきます。

ReAct 時代に文字列パースと正規表現で頑張るところから始まった Agent が、今では Sub-agent をツールとして自然に呼び分けるところまで来た、という変化です。

Harness 側にも新しい仕事が積まれる

ここまで、Model が賢くなって、Harness の仕事が Model 側に移っていった、という話を中心にしてきました。ただ、これだけだとだから Harness はどんどん薄くなっていくと読まれてしまうかもしれません。実際にはそう単純ではないので、補足しておきます。

Harness は別領域で複雑化している

確かに ReAct 時代と比べると、Harness が担っていた仕事のいくつかは Model 側に移りました。プロンプトのテンプレート設計、テキストパース、思考の深さの制御、などです。

ただ、その分 Harness が軽くなったかというと、現実には逆で、別の領域で複雑になっています。具体的には、こんな仕事が積み上がっています。

  • コンテキスト管理 : Agent を長く動かすと履歴がどんどん溜まっていきます。これを適切なタイミングで圧縮したり要約したりする必要があります。
  • 状態の永続化 : 数時間〜数日にわたって動く Agent だと、途中でクラッシュしたり再起動したりしても続きから再開できる必要があります。
  • 権限制御とサンドボックス : Agent がファイルを書き換えたりコマンドを実行したりするとき、何を許可するか、危険な操作をどう止めるか、という仕組みが要ります。
  • Sub-agent のオーケストレーション : 前のセクションで見たような Sub-agent as tool を本番で運用するには、並列実行の調整やエラー時のフォールバックなどの設計が必要になります。
  • 観測性 (observability) : Agent が何をどう判断したかを後から追えるようにするためのログやトレース。

これらは Model がいくら賢くなっても、Model の外側で誰かが用意しないといけない仕組みです。むしろ Model が賢くなって複雑なタスクを任せられるようになるほど、これらの責任は重くなります。

つまり Harness と Model の間では、双方向の動きが起きています。

  • Model 側に移る仕事もある(テンプレート設計、思考の深さ制御)
  • Harness 側に新しく積まれる仕事もある(コンテキスト管理、Sub-agent 調整、観測性)

ハーネスはモデルが出来ないことの仮定をエンコードしている

Anthropic のエンジニアリングブログにこんな表現があります(意訳)。

ハーネスはモデルが出来ないことについての仮定をエンコードしており、その仮定はモデルの進化に伴って陳腐化する。

少し固い表現ですが、平たく言えば Harness は、ここは Model にはまだ任せられない、という前提に基づいて作られていて、Model が進化するとその前提が古くなる ということです。古くなれば、Harness の一部の仕事は消える一方で、新しく任せられるようになった領域に対する新しい仕組みが必要になります。これがまさに再配置を端的に表しています。

たとえば、以前は Sonnet 4.5 ではコンテキストの強制リセットが必要だったが、Opus 4.5 ではそれを削除できた、というような具体例も、同じブログで紹介されています。Model の進化に合わせて、Harness 側も継続的に書き換えていく必要があるということです。

Multi Agent の構成と思想

ここまでの話を踏まえて、Multi Agent 周辺の動向を整理する 2 つの切り口を示しておきます。

Multi Agent と一言で言っても、いくつかの形がある

Multi Agent と言われると、複数の AI が対等に協力するイメージを持ちがちです。ただ実際には、構成にいくつかの段階があり、それぞれ用途が違います。

  1. Single Agent + ツール
    • 1 つの AI が複数のツールを使い分ける構成。最近は MCP (Model Context Protocol) によって外部ツールの追加が容易になり、これだけでもかなり多くのことができます。
  2. シンプルなワークフロー
    • 生成 → レビュー → 再生成、のような決まった手順を、コードで明示的に組み合わせる構成。手順が固定化されているケースに向きます。
  3. オーケストレーター + Sub-agent
    • 前のセクションで見た Sub-agent as tool パターン。親 Agent がタスクに応じて Sub-agent を呼び分けます。タスクが多様で事前に手順を決められない場合に向きます。
  4. 対等な Agent 連携 (A2A)
    • 異なる組織やベンダーをまたいだ Agent 同士の連携。Google が提唱した A2A プロトコルが整備されつつあり、これからの広がりが期待される領域です。

下に行くほど構成が高度になりますが、それぞれに適した用途があります。何かのフレームワークや事例に触れたときに、これはどの段階の話だろう?と当てはめてみると位置関係が見えやすくなります。

フレームワーク間の哲学を読み解く視点

ここまでのセクションで、Reasoning モデル登場以降、Harness を薄くして Model に判断を委ねるフレームワークが出てきたこと、また Sub-agent as tool パターンに対するアプローチがフレームワークごとに少しずつ違うことに触れてきました。これらを踏まえて、最近の Multi Agent 関連のフレームワークを並べてみると、設計思想が大きく 2 派に分かれていることに気づきます。

構造主導派

LangGraph や AutoGen のように、Agent 同士の連携をコードで明示的にグラフとして書く思想のフレームワーク。誰が次に動くか、いつループを止めるかを Harness 側のコードに書きます。フローが固定的・手順が明確なタスクで読み解きやすいのが特徴です。

Model 主導派

Claude Agent SDK や AWS Strands のように、フロー制御も Model の判断に委ねる思想のフレームワーク。Sub-agent もツールとして登録するだけで、Model がいつ呼ぶか、いつ止めるかを判断します。コード量が少なく、Model の判断に広く委ねたいケースに向きます。

両派は完全に排他というわけではなく、LangGraph でも Sub-agent as tool パターンを書けますし、Claude Agent SDK でも自前のループを書けます。あくまで自然に書ける書き方の方向性が違う、という理解が現実に近いと思います。

この 2 派の存在自体が、本記事のメインメッセージである責任の再配置の現れでもあります。Model がどこまで賢くなったかについての判断が違うからこそ、フレームワークの哲学が分かれている、と読み解けます。

おわりに

ソフトウェアの歴史を振り返ると、これは AI Agent に固有の動きではない、と気づきます。コンパイラの登場で、それまでアセンブリで人間が書いていた最適化の一部が機械側に移りました。GC の登場で、メモリ管理が言語ランタイム側に吸収されました。クラウドの登場で、サーバーの面倒を見る仕事が事業者側に移りました。

そのたびに、人間が書く部分と機械が判断する部分の境界が動いてきました。そして境界が動いた先で、人間は別の領域でより複雑な仕事を引き受けるようになってきました。AI Agent における Model と Harness の責任の再配置も、この長い文脈の上にあります。

Model がどこまで賢くなっても、Harness 側で誰かが Model に何を任せるかを決めなければならない、という関係は変わりません。境界が動き続ける中で、それを観察し、Model に任せられるところは任せ、まだ任せられないところに新しい仕組みを足していく。AI Agent を作るというのはそういう仕事なのかもしれないですね。

おわり 🎉