🤖

Local LLMを用いたMCP(Model Control Protocol)入門: (概要編: 基本的な関数呼び出し)

に公開

Local LLMを用いたMCP(Model Control Protocol)入門: (概要編: 基本的な関数呼び出し)

はじめに

MCP(Model Control Protocol)は、AI言語モデルが外部ツールやシステムと標準化された方法で連携するためのプロトコルです。

従来、AIアプリケーションを構築する際には、各々が独自の方法でツール連携を実装する必要がありましたが、MCPによりこのプロセスが大幅に簡素化され、異なるAIモデル間での互換性も実現されました。

この記事では、作成したサンプルコードを詳しく説明し、プロンプトエンジニアリングとJSONパースを通じてGemma 3モデルに関数呼び出しを行う方法を解説します。基本的な概念からより堅牢な実装への進歩を示す2つの主要なサンプルを検証します。

本記事で使用するツール: Gemma3

今回の実装では、Googleが開発したオープンソース言語モデル「Gemma3」を使用します。Gemma3は以下の特徴を持つLocal LLMです:

Gemma3の主な特徴:

  • ローカル実行可能: クラウドAPIに依存せず、自分のマシン上で動作
  • Function Calling対応: ツール呼び出し機能をネイティブサポート
  • 軽量設計: 比較的少ないリソースで高性能を実現
  • 商用利用可能: オープンライセンスによる柔軟な利用が可能

Gemma3を選択する理由は、MCPのツール呼び出し機能を検証するのに十分な性能を持ちながら、ローカル環境での実行が容易である点にあります。これにより、外部APIの制約やコストを気にせずに、MCPの仕組みを深く理解できます。

前提条件

  • Python 3.8+
  • Ollama がインストール済みで動作していること
  • Gemma 3 モデルがプル済み: ollama pull gemma3:12b (メモリ容量が足りない場合はgemma3:4bに変更してください)

AIが現実世界と繋がる時

「商品の到着が遅れています。すぐに状況を確認して、お客様に連絡してください」
この緊急の一言で、AIアシスタントがあなたの代わりに以下のすべてを瞬時に実行する——これは、もはや遠い未来の話ではありません:

  • 在庫管理システムにアクセスして商品の現在位置を特定
  • 配送業者のAPIから最新の配送状況を取得
  • 天気予報APIで配送ルート上の交通状況を確認
  • 顧客データベースから連絡先情報を検索
  • 状況に応じたお詫びメールを自動生成して送信
  • 代替配送オプションを提案
  • 在庫補充の優先度を自動調整

想像してみてください。ある日曜日の夜、あなたがAmazonで注文した商品が予定通りに届かないとします。通常なら、カスタマーサービスに電話をかけ、長時間待たされた後、オペレーターが複数のシステムを手動で確認し、ようやく「配送トラックが渋滞に巻き込まれています」という回答を得るでしょう。
しかし、MCPを活用したAIシステムなら、あなたが「注文した商品はどこ?」と尋ねた瞬間に、AIが自動的に配送業者のトラッキングシステム、交通情報、天気データ、そして過去の配送パターンを同時に分析し、「現在、配送トラックは高速道路の事故渋滞で2時間遅れています。明日の午前10時頃には到着予定です。お急ぎでしたら、近くの店舗での受け取りも可能です」という具体的で有用な回答を提供できます。
この魔法のような体験の背後にあるのが、MCPの力です。
従来のAIは、まるで「優秀だが外出できない事務員」のような存在でした。膨大な知識を持ちながらも、現実世界の動的な情報——リアルタイムの在庫状況、配送状況、天気情報、交通渋滞——にアクセスすることができませんでした。倉庫管理者が「この商品の在庫は?」と尋ねても、AIは「申し訳ありませんが、リアルタイムの在庫情報にはアクセスできません」と答えるしかなかったのです。
しかし、物流の世界では、情報は生きています。商品は移動し、在庫は変動し、配送状況は刻々と変化します。顧客の期待は高まり、「なぜ今の状況がわからないの?」という疑問が当然の要求となっています。
MCPは、この現実世界とAIの間に存在していた大きな壁を取り払います。AIの「脳」と物流システムの「神経網」を繋ぐ架け橋として、倉庫管理システム、配送追跡、在庫データベース、顧客管理システムなど、複雑に絡み合った物流インフラへのアクセスを、驚くほどシンプルに実現します。
まるで経験豊富な物流コーディネーターが初めての倉庫でも瞬時に全てのシステムを理解し、効率的に作業を進めるように、MCPを活用したAIは新しい物流環境に自動的に適応し、インテリジェントに行動できるのです。
その結果、「商品はいつ届くの?」という単純な質問に対して、AIが複数のシステムを横断して情報を収集し、「現在の配送状況、交通情報、天気予報を総合すると、明日の14:30頃の到着予定です。もし午前中の受け取りをご希望でしたら、近くの営業所での受け取りに変更できます」という、人間の専門スタッフ以上に詳細で実用的な回答を提供できるようになるのです。

サンプル:基本的な関数呼び出し(basic_example.py

目的と学習目標

基本サンプルは最小限の実装として機能し、コアなコンセプトを理解するのに最適です。以下を実演します:

  • 関数呼び出しの基本的なJSON形式
  • シンプルなシステムプロンプト設計
  • 基本的なJSON抽出技術
  • 2ステップの会話フロー

主要コンポーネント分析

システムプロンプト設計

SYSTEM_PROMPT = """You can call these functions:

1. get_time() - Returns current time
2. add_numbers(a, b) - Adds two numbers

To call a function, respond with JSON in this format:
{"tool_call": {"name": "function_name", "arguments": {"param": "value"}}}

Examples:
- {"tool_call": {"name": "get_time", "arguments": {}}}
- {"tool_call": {"name": "add_numbers", "arguments": {"a": 5, "b": 3}}}
"""

このようにシステムプロンプトを入力する段階で時刻取得: get_time関数と足し算を行う: add_numbers関数の入力や説明文を記載します。
また、関数呼び出しはJSON形式で応答するよう指示を行います。

JSON抽出ロジック

def extract_function_call(response: str):
    """Extract function call from Gemma's response."""
    try:
        if '{"tool_call":' in response:
            start = response.find('{"tool_call":')
            # Simple JSON extraction - find matching braces
            brace_count = 0
            end = start
            for i in range(start, len(response)):
                if response[i] == '{':
                    brace_count += 1
                elif response[i] == '}':
                    brace_count -= 1
                    if brace_count == 0:
                        end = i
                        break
            
            json_str = response[start:end + 1]
            return json.loads(json_str)["tool_call"]
    except:
        pass
    return None

簡潔な実装ですが、{"tool_call":応答内に存在する時に埋め込まれたJSONを処理します。
パースされたJSONの情報に従って、

def execute_function(name: str, args: dict):
    """Execute the requested function."""
    if name == "get_time":
        return get_time()
    elif name == "add_numbers":
        return add_numbers(args.get("a", 0), args.get("b", 0))
    else:
        return f"Unknown function: {name}"

指定の関数を実行します。

python examples/basic_example.py

サンプルを実行すると、

User: What time is it?
Gemma says: {"tool_call": {"name": "get_time", "arguments": {}}}
Calling function: get_time with args: {}
Function result: Current time: 14:30:25
Final answer: The current time is 14:30:25.

のような結果が得られます。

チャット形式でのサンプルプログラムも用意していますので、ぜひ試してみてください。

python examples/basic_example.py

次回以降は、詳細なMCPの仕組みや実際のユースケースを想定したツールの作成をできればと考えています。

Discussion