🤝

AIエージェントを複数つなぐと、最初に壊れるのは精度ではなく責任境界です。triage agent が調査を専門 agent に渡す。review agent が修正 agent に渡す。incident agent が rollback agent に渡す。見た目は自然ですが、渡す情報が多すぎると不要な秘密情報まで流れ、少なすぎると次の agent が勝手に推測します。

この記事では、AIエージェントの 引き継ぎ設計 を handoff contract として整理します。複数エージェントの全体パターンは マルチエージェントオーケストレーション4パターン、本番前の評価は AIエージェント評価設計ガイド、実行直前の人間承認は AIエージェント承認フロー設計ガイド、稼働中に止める監視は AIエージェント本番監視設計ガイド に分けています。

今回扱うのは、agent A から agent B へ仕事を渡す瞬間に何を固定するかです。つまり「複数 agent をどう並べるか」ではなく、「渡した後に責任が溶けないようにする設計」です。

先に結論: handoff は会話転送ではなく契約として扱う

handoff を「今までの会話を全部渡すこと」と捉えると、ほぼ失敗します。次の agent は前段のノイズ、途中仮説、不要な tool output、secret に近い値まで受け取り、何を根拠に作業すべきか判断しにくくなります。

私なら、handoff は次の6項目を持つ契約として扱います。

項目書くこと失敗すると起きること
handoff_id引き継ぎ単位のID監査ログで追えない
from / to渡す側と受ける側責任者が曖昧になる
task次の agent がやる作業作業範囲が広がる
context_summary判断に必要な要約だけ会話全文依存になる
allowed_actionsread / draft / write / external action権限が前段から漏れる
return_contract返す形式と戻し先親 agent が統合できない

OpenAI Agents SDK では handoff は agent 間の delegation であり、LLM から見ると handoff 用 tool として表現されます。さらに input_type で reason や priority のような小さな構造化メタデータを渡せます。ここから分かるのは、handoff は「雰囲気で任せる」機能ではなく、渡す理由と入力形を設計する場所だということです。

まず「渡すもの」と「渡さないもの」を分ける

handoff で一番重要なのは、次の agent が見る入力を絞ることです。

渡すべきものは、次の判断に直接必要な情報だけです。

  • ユーザーの最終目的
  • 現在の状態
  • 既に試したこと
  • 失敗した仮説
  • 使ってよい tool と使ってはいけない tool
  • 返してほしい形式

逆に、渡さない方がよいものもあります。

  • 長い会話履歴全文
  • 古い仮説や却下済み案
  • secret、token、個人情報を含む raw log
  • 前段 agent の内部 reasoning
  • 次の agent が使えない tool の出力全文

OpenAI Agents SDK の handoff input filter は、handoff 先に見せる履歴を調整できます。公式 docs でも、必要なら tool call を履歴から除去する例が示されています。Claude Code の subagents でも、subagent は独立 context で動き、main conversation へ戻すのは結果要約です。この考え方は同じです。全部渡すのではなく、次の agent が判断できる最小の文脈へ圧縮するべきです。

最小の handoff contract

実務では、最初から複雑な schema を作る必要はありません。まずは YAML で十分です。

handoff_id: hf-20260610-pr-review-01
from: triage-agent
to: code-review-agent
task: "PR #123 の認証まわりだけを read-only で確認する"
context_summary:
  user_goal: "release 前に auth regression がないか確認したい"
  current_state: "CI は green。差分は auth middleware と session refresh"
  tried:
    - "unit test は通過"
    - "manual QA は未実施"
  known_risks:
    - "session refresh path が 401 を握りつぶす可能性"
allowed_actions:
  read: true
  draft: true
  write: false
  external_action: false
forbidden:
  - "branch push"
  - "package install"
  - "production API call"
return_contract:
  format: "findings"
  severity: ["P0", "P1", "P2", "P3"]
  must_include:
    - "根拠ファイル"
    - "再現条件"
    - "修正が必要かどうか"
on_failure:
  ask_back_to: triage-agent
  stop_if: "対象外ファイルの変更が必要になった"

この程度でも、handoff の事故はかなり減ります。特に allowed_actionson_failure が効きます。agent は失敗すると「自分で進めよう」としがちなので、戻す条件を先に書きます。

権限は引き継がず、必ず狭め直す

handoff で危ないのは、前段 agent の権限をそのまま次へ渡すことです。

triage agent が read-only で調べていたのに、修正 agent に渡した瞬間に write できる。さらに外部 issue tracker や MCP server も読める。これでは、handoff が権限昇格の抜け道になります。

私なら、handoff のたびに権限を次の4段階で再評価します。

権限handoff 時の判断
readrepo、log、docs を読む原則ここから始める
draft修正案、PRコメント案、runbook案を書く人間確認前の標準
writebranch、file、issue を変更する明示承認がある時だけ
external actiondeploy、token revoke、顧客通知別承認と監査ログ必須

Claude Code subagents の docs でも、subagent には tool や MCP server、permission mode を個別に持たせられます。background subagent では permission prompt が必要な tool call は自動 deny されるため、広い権限を前提にした handoff は壊れます。これは制約というより、設計上の良い警告です。

handoff 先が必要とする最小権限を contract に書き、足りない場合は勝手に拡張させず、親 agent か人間へ戻す。この形にしておくと、監査ログと事故対応も追いやすくなります。

return contract を決めないと親 agent が壊れる

引き継ぎは渡す側だけでなく、戻す側も設計します。

よくある失敗は、専門 agent が長い調査メモを返し、親 agent がそれをまとめ直せず、重要なリスクを落とすことです。subagent を使って main context を汚さないつもりが、最後の返却で巨大な summary を戻してしまうパターンです。

return contract は、最低限これだけ決めます。

return_contract:
  status: "ok | blocked | needs_human | out_of_scope"
  summary: "3行以内"
  findings:
    - severity: "P0 | P1 | P2 | P3"
      claim: "何が問題か"
      evidence: "file / trace / tool log"
      next_action: "誰が何をするか"
  artifacts:
    - type: "diff | report | command_output"
      location: "URL or path"
  confidence: "high | medium | low"

この形式なら、親 agent は次の判断をしやすくなります。

  • ok なら次の工程へ進む
  • blocked なら不足情報を取りに行く
  • needs_human なら承認者へ戻す
  • out_of_scope なら routing をやり直す

Google ADK の delegation でも、agent の description が routing に使われるため、役割の違いを明確にすることが重要です。routing だけでなく戻り値も明確でないと、複数 agent の出力はすぐ読みにくくなります。

監査ログには handoff 自体を残す

handoff は内部処理に見えますが、運用上は監査対象です。どの agent が、なぜ、どの agent へ渡したのかが分からないと、失敗時に原因を追えません。

監査ログには、少なくとも次を残します。

項目
agent_run_id20260610-support-agent-01
handoff_idhf-20260610-02
from_agenttriage-agent
to_agentrefund-agent
reasonbilling decision required
input_summary_hashraw input を残さないための hash
allowed_actionsread,draft
result_statusok, blocked, needs_human

ここで raw input を全部保存する必要はありません。むしろ secret や個人情報を含む履歴を丸ごと保存すると、監査ログ自体がリスクになります。要約、hash、成果物の location、承認IDを残す方が扱いやすいです。

eval では「正しい agent に渡したか」を見る

handoff はプロンプトで祈るだけでは安定しません。eval に入れます。

最低限見るべきケースは5つです。

ケース落としたい失敗
正常 routing適切な専門 agent へ渡せるか
渡しすぎ不要な raw log や secret を渡さないか
渡さなすぎ次の agent が判断不能にならないか
権限昇格read-only task を write agent へ渡さないか
戻し先scope 外を人間または親 agent へ戻せるか

AIエージェント評価設計ガイド で書いた通り、final output だけを見る eval では足りません。handoff の eval では、trace 上の fromto、handoff reason、渡した input summary、戻り値 status を見ます。

実務でよくある失敗

私が一番警戒する失敗は、次の4つです。

1. specialist を増やしすぎる

専門 agent を増やすほど賢く見えますが、routing は難しくなります。最初は triage、worker、reviewer の3つで十分です。billing、legal、security、SRE のような細分化は、routing eval が通るようになってからでよいです。

2. handoff reason が曖昧

need help のような理由では監査にも eval にも使えません。auth regression suspectedexternal action approval requiredPII detected のように、後から集計できる粒度にします。

3. 親 agent が最終責任を捨てる

handoff しても、最終責任は親 agent または人間側に残します。専門 agent の出力をそのままユーザーに出すのではなく、親 agent が task と allowed_actions に照らして統合します。

4. 失敗時の戻し先がない

handoff 先が判断できないとき、勝手に仮説を作って進めるのが一番危険です。on_failure.ask_back_tostop_if を contract に入れておくと、この失敗を減らせます。

まとめ

AIエージェント引き継ぎ設計は、マルチエージェントを高度に見せるための飾りではありません。責任、文脈、権限、戻り値を小さく固定し、失敗時に止まれるようにするための運用設計です。

私なら、最初の handoff contract は次の順で作ります。

  1. 受け側 agent の役割を1文で書く
  2. 渡す context summary を3から5項目に絞る
  3. read / draft / write / external action を明示する
  4. return contract を status / findings / artifacts に分ける
  5. handoff を監査ログと eval dataset に入れる

この5つがないまま agent を増やすと、便利さより先に責任境界が崩れます。逆にここを固定すれば、複数 agent は「なんとなく分業する仕組み」ではなく、レビュー可能なワークフローになります。

参考資料

WRITTEN BY nidoneko

Full-stack engineer with 8+ years of experience in TypeScript, React, Node.js, and cloud-native development across healthcare, finance, HR, and IoT domains.

View Profile →