この記事では、OpenAI Agents SDKを用いたエージェント開発の基礎として、ツール呼び出しとハンドオフ(エージェント間引き継ぎ)の仕組みを整理する。最終的なゴールは、単一エージェントではなく、役割分担された複数エージェントによる柔軟な処理フローを理解することにある。
1.開発環境と前提知識
OpenAI Agents SDKは、Python仮想環境上で利用することを前提とし、APIキー設定後、最小構成のエージェント実行で動作確認を行う。SDKはPythonの型ヒント(Type hint)、ドッグストリング(Docstring)、デコレーター(Decorator)を活用しており、これらがLLMにとってのメタデータとして機能する。特に、ツール定義では関数シグネチャと説明文が、そのままLLMが理解する操作仕様になる点が重要である。また、非同期実行やPydanticによる入出力検証も、信頼性の高いエージェント設計に不可欠な要素となる。
2.最小エージェントから実用エージェントへ
以下は単純なカスタマーサポート用エージェントのコード例である。この段階では、自然言語入力に応答するだけの構成でもよいが、実務では問い合わせ内容に応じて外部処理を呼び出す能力が求められる。そこで、注文状況を返すツールを追加する。
from agents import Agent, function_tool
@function_tool
def fetch_delivery_state(order_ref: str) -> str:
"""注文番号に対応する配送状況を返す"""
dummy = {
"A001": "発送済み",
"A002": "準備中",
}
return dummy.get(order_ref, "該当する注文が見つからない")
support_agent = Agent(
name="サポート受付エージェント",
instructions="利用者からの問い合わせ内容を整理し、必要に応じて配送状況を確認する。",
tools=[fetch_delivery_state],
model="gpt-4o",
)
ここで重要なのは、ツールの中身よりも「どんな入力を受け、何を返すか」を自然言語と型で明確にする点にある。
3 .ハンドオフによるマルチエージェント化
次に、エージェントに分業をさせる。すべての判断を1体に任せるのではなく、特定の状況では別の専門エージェントに処理を委ねる。これがハンドオフである。例として、解約や強い不満を示す利用者に対応するため、リテンション専用エージェントを用意する。
retention_agent = Agent(
name="継続対応エージェント",
instructions="解約や不満を示す利用者に対し、共感的に対応し、条件改善の提案を行う。",
model="gpt-4o",
)
support_agent = Agent(
name="サポート受付エージェント",
instructions="問い合わせ内容を一次対応し、必要なら専門エージェントに引き継ぐ。",
tools=[fetch_delivery_state],
handoffs=[retention_agent],
model="gpt-4o",
)
上のコードでは、サポート受付エージェント(support_agent)が常に窓口となり、ツール呼び出しで足りる場合は自ら処理し、解約・不満対応が適切だと判断した場合には、リテンションエージェント(retention_agent)へハンドオフする。
4.ハンドオフの要否はどのように判断されるか
ハンドオフの判断は、エージェント名だけで行われるわけではない。モデルには、①現在のユーザー入力、②自分自身のinstructions、③handoffsに登録された各エージェントのinstructionsが同時に与えられている。LLMはそれらを比較し、「自分で最終回答を出すべきか」「ツールを使うべきか」「別エージェントに任せるべきか」を推論する。したがって、ハンドオフ用エージェントのinstructionsには「どのような状況を専門とするか」を明確に書く必要がある。
5.SDK内部で起きていること
制御ロジックのループ中、LLMがfinal_outputを返さず、ハンドオフを選択した場合、Runnerがそれを検知し、同一のユーザー入力コンテキストを次のエージェントに引き継ぐ。以降は、そのエージェントが主導権を持ち、最終回答を生成する。この一連の流れはトレーシング機能によって可視化でき、どのエージェントがいつ動いたか、どの時点で切り替わったかを確認できる。
6.まとめ
このように、型ヒントとドッグストリングによるツール定義、instructionsによる役割設計、ハンドオフによる分業という3点を押さえるだけで、少ないコード量でも適応的なマルチエージェント構成を組むことができる。