コードからOpenAI Agent SDKのMCP対応の理解を深める
1. はじめに
Makiさんが取り上げていた、ニケちゃんのOpenAIのAgents SDKを使用して、MCPサーバーを利用したAIエージェントの最小構成が非常に勉強になりました。
Githubのソースコードを読み解きながら、OpenAI Agent SDKのMCP対応の理解を深めていきます。
お二方には本当に感謝です!
私の記事の中で、OpenAI Sgent SDKのMCP対応に関する概要記事もあります。ご参考になれば幸いです。
2. 全体アーキテクチャの概要
提供されたコードは、次の主要コンポーネントで構成されています:
- OpenAI Agents SDK: AIエージェントの作成と実行の基盤
- Model Context Protocol (MCP): 外部ツールとLLM(大規模言語モデル)を接続する標準プロトコル
-
Brave Search MCP Server: MCPを通じてBrave検索APIを利用可能にするサーバー
この構成により、LLMの知識を拡張し、最新情報にアクセスできる検索アシスタントが実現されています。
3. コードの詳細分析
詳細分析にあたり全体的な構成を見ていきましょう。いろいろ調べながら、下記構成と理解しています。この図を頭に入れながらコードを詳細に見ていきましょう。対象はmain.pyです。
3.1 必要なライブラリのインポート
import asyncio
import os
from agents import Agent
from agents import Runner
from agents.mcp import MCPServerStdio
from dotenv import load_dotenv
-
asyncio
: 非同期処理のためのライブラリ(MCPサーバーとの通信に必要) -
os
: 環境変数へのアクセスに使用 -
Agent
,Runner
: OpenAI Agents SDKの中核クラス -
MCPServerStdio
: stdio経由でMCPサーバーと通信するためのクラス -
load_dotenv
: 環境変数を.envファイルから読み込むためのユーティリティ
3.2 環境変数の読み込み
load_dotenv()
この行は.env
ファイルから環境変数(Brave APIキー、OpenAI APIキー)を読み込みます。APIキーのような機密情報をコードに直接記述せず、環境変数として管理するのはセキュリティのベストプラクティスです。
3.3 メイン関数の定義
async def main():
非同期処理を行うためのメイン関数です。async
キーワードにより、この関数内でawait
を使った非同期処理が可能になります。
3.4 MCPサーバーの初期化
async with MCPServerStdio(
params={
"command": "npx", # Linux環境用
# "command": "/Users/user/.volta/bin/npx", # MacOS環境用
# "command": "C:\\Program Files\\nodejs\\npx.cmd", # Windows環境用
"args": ["-y", "@modelcontextprotocol/server-brave-search"],
"env": {"BRAVE_API_KEY": os.getenv("BRAVE_API_KEY")},
}
) as server:
この部分は、MCPServerStdio
クラスを使用してBrave検索MCP serverをサブプロセスとして起動しています:
-
command
: 実行するコマンド(ここではnpx
) -
args
: コマンドに渡す引数-
-y
: プロンプトに自動的に「はい」と応答 -
@modelcontextprotocol/server-brave-search
: 実行するNPMパッケージ
-
-
env
: サーバープロセスに設定する環境変数(Brave APIキー)
async with
構文は、ブロックの開始時にサーバーを適切に起動し、終了時に正しく停止させることを保証します。
3.5 サーバーからツール一覧の取得
await server.list_tools()
この行は、起動したMCPサーバーが提供するツール(機能)のリストを取得します。この情報はLLMに利用可能なツールを認識させるために使用されます。
3.6 エージェントの作成
agent = Agent(
name="検索アシスタント",
instructions="あなたは検索アシスタントです。ユーザーの質問に対して、"
"Brave検索を使用して情報を調査し、日本語で分かりやすく回答してください。"
"情報源も明記してください。",
mcp_servers=[server],
)
ここでは、Agent
クラスのインスタンスを作成しています:
-
name
: エージェントの識別子(ログやデバッグ用) -
instructions
: エージェントの行動を導くシステムプロンプト- 日本語で応答すること
- Brave検索を使用して情報を調査すること
- 情報源を明記すること
-
mcp_servers
: エージェントが利用できるMCPサーバーのリスト
3.7 エージェントの実行
result = await Runner.run(
agent, "2025年にされたOpenAIの発表について教えて下さい"
)
print(result.final_output)
Runner.run()
メソッドは「エージェントループ」と呼ばれる反復処理を開始します:
- LLMに現在の入力とメッセージ履歴を提供
- LLMの応答を分析(最終出力、タスク委譲、ツール呼び出しなど)
- ツール呼び出しの場合、対応するツールを実行し結果をメッセージ履歴に追加
- 最終出力が生成されるまで繰り返し
このケースでは、エージェントはBrave検索ツールを使用して「2025年にされたOpenAIの発表」に関する情報を検索し、結果を日本語でまとめて返します。
3.8 メイン関数の実行
if __name__ == "__main__":
asyncio.run(main())
スクリプトが直接実行された場合にmain()
関数を実行するための標準的なPythonイディオムです。asyncio.run()
は非同期関数を実行するためのエントリーポイントとして機能します。
4. 技術的詳細
4.1 OpenAI Agents SDKの主要コンポーネント
Agents SDKには以下の中核的な概念があります:
- Agent: 特定の指示でセットアップされ、ツールを使用できるLLM
- Tool: エージェントの能力を拡張する関数やサービス
- Handoff: 特定のタスクを別のエージェントに委譲する機能
- Guardrail: 入出力を検証する安全性チェック
- Runner: エージェントのタスク実行を管理
4.2 Model Context Protocol (MCP)の仕組み
MCPは「AIアプリケーション用のUSB-Cポート」とも表現される、標準化されたプロトコルです:
- クライアント-サーバーアーキテクチャ: LLMアプリケーション(クライアント)と外部データソース/ツール(MCPサーバー)を接続
- JSON-RPC 2.0: MCPクライアントとMCPサーバー間の通信プロトコル
- トランスポートメカニズム: stdio(標準入出力)やHTTP over SSEなど
本コードではstdioトランスポートを使用しており、サーバーは子プロセスとして実行され、標準入出力を通じて通信します。
4.3 Brave Search MCP Serverの機能
@modelcontextprotocol/server-brave-search
は以下の機能を提供します:
- brave_web_search: 一般的なウェブ検索実行
- brave_local_search: ローカルビジネスやサービスの検索
これにより、AIエージェントはウェブ上の情報にアクセスし、最新データを含む回答を生成できます。
5. まとめ
OpenAI Agents SDKとModel Context Protocolを活用して、外部知識にアクセスできる検索AIアシスタントを構築する最小構成のソースコードを見ていきました。MCPサーバーを通じてBrave検索APIに接続することで、LLMの能力を大幅に拡張し、最新情報や特定領域の知識を提供できるインテリジェントなアプリケーションを実現しています。
この記事をきっかけに、OpenAI Agent SDKやMCPの理解が深めて頂けたら幸いです!
Discussion