🎼

AOAI を使って MCP を軽く試してみた

に公開

MCP の勉強をしている中で、へーしゃ同僚の @mochizuki875 さんがサンプルを置いてくださっていたので、試してみました。

なお、けっこう世の中の情報としては Azure ではない「OpenAI」の API キーを使った情報が多かったり、LLM に Azure OpenAI (AOAI) にデプロイしたモデルを利用しているものの少し古めの情報だったりしたので、LLM に AOAI にデプロイしたモデルを利用する観点でも残せればな、と思っています。すぐ陳腐化しそうですが😅

環境

  • Windows 10
    • WSL 2 (Ubuntu 22.04)

試してみる

パッケージのインストール

まずは WSL2 上で Python 仮想環境に入ります。

python3 -m venv aoaimcptest
. aoaimcptest/bin/activate

その後、必要なパッケージをインストールします。

pip install -qU langgraph langchain-openai langchain-mcp-adapters python-dotenv langsmith tavily-python langchain-community

MCP サーバ側の準備

冒頭のリポジトリを参考に restaurant_server.py, tavily_server.py, weather_server.py を作成します。今回は StreamableHTTP のものを利用します。

なお、各コードには「# 環境変数」として OpenAI の API キーを設定する箇所がありますが、今回の 3 つのファイルでは不要です。

MCP サーバの起動

ターミナルで各 MCP サーバを起動しておきます。なお、ターミナルを 1 つだけにするなら、バックグラウンドで動作させておいても良いですね。

python weather_server.py &
python restaurant_server.py &
python tavily_server.py &

MCP クライアント側の準備

冒頭のリポジトリを参考に main.py を作成します。

AOAI にアクセスするように環境変数の部分を調整します。なお、LangSmith は使いませんでした😅
また、本記事執筆時点では一部の実装が動かないため main() の中身も変えています。

AOAI に関するエンドポイント等の情報は、記事執筆時点では Azure AI Foundry の「モデル + エンドポイント」画面が一番わかりやすいと思います。

こちらの緑で囲った箇所の情報が、それぞれ該当します。あ、API キーは左上の「キー」ですね。

  • endpoint: <AOAI のエンドポイントの URL>
  • subscription_key (左上の「キー」): <AOAI の API キー>
  • deployment: <AOAI のデプロイの名前>
  • api_version: <AOAI の API バージョン>
main.py
from dotenv import load_dotenv
import os
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent
import asyncio
from langchain_mcp_adapters.client import MultiServerMCPClient
from langchain_openai import AzureChatOpenAI

# 環境変数
load_dotenv()
# os.environ["OPENAI_API_KEY"] = ""
os.environ["AZURE_OPENAI_ENDPOINT"] = "<AOAI のエンドポイントの URL>"
os.environ["AZURE_OPENAI_API_KEY"] = "<AOAI の API キー>"
os.environ["AZURE_OPENAI_DEPLOYMENT_NAME"] = "<AOAI のデプロイの名前>"
os.environ["AZURE_OPENAI_API_VERSION"] = "<AOAI の API バージョン>"

# モデルの定義
model = AzureChatOpenAI(
    azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
    azure_deployment=os.environ["AZURE_OPENAI_DEPLOYMENT_NAME"],
    openai_api_version=os.environ["AZURE_OPENAI_API_VERSION"],
)
prompt = """
"あなたは旅行アシスタントです。"
"ユーザーからの質問に答えてください。"
"各ツールを実行して特定の情報を取得できなかった場合は、その内容について必ずWeb検索を行い、その結果を踏まえて回答してください。"
"Web検索は、web_searchツールを使用してください。"
"""

async def main():

    client = MultiServerMCPClient(
        {
            "weather": {
                "url": "http://localhost:8080/mcp/",
                "transport": "streamable_http",
            },
            "restaurant": {
                "url": "http://localhost:8081/mcp/",
                "transport": "streamable_http",
            },
            "tavily": {
                "url": "http://localhost:8082/mcp/",
                "transport": "streamable_http",
            }
        }
    )
    
    tools = await client.get_tools()
    agent = create_react_agent(model, tools, prompt=prompt)
    result = await agent.ainvoke({"messages": "山形で餃子が食べたいな。天気も心配だ。"})

    print("=== 全てのメッセージを表示 ===")
    for message in result["messages"]:
        print(f"{message.__class__.__name__}: {message}")

    print("=== 最終的な回答のみを表示 ===")
    print(result["messages"][-1].content)


if __name__ == "__main__":
    asyncio.run(main())

MCP クライアントの実行

ここまで準備ができたら、下記のコマンドでクエリを投げてみます。

python main.py

特にエラーなく応答が返ってくれば成功です。転記は割愛しますが、JSON など色々なデータが表示されるはずです。

おわりに

ということで、サクッと AOAI で試してみました。
今後もコンテナ化して Azure Container Apps でホストする等、夢が広がる昨今ですね!

Discussion