banner
Woiot

周末不写代码

MCP、FunctionCallの基礎知識

Tip

ヒント
以下将 MCP (主要指服务端) 和 FunctionCall (主要指 OpenAI chat 规范的函数调用) 都笼统称为 “プラグイン”,方便快速理解,

  • モデル自体は function または mcp サーバーを呼び出す能力を持っていません
  • 両者は、リモートモデルに対して、クライアントがどの追加機能(天気プラグイン、データベースプラグイン、図を描くプラグインなど)を持っているかを伝え、モデルは現在の文脈(現在の文)に基づいて、現在のシーンで特定のプラグインを実行すべきかどうか、またそのパラメータが何であるかを判断し、特別な応答を返し、その結果をクライアントに返します
  • モデル自体はさまざまな「テキスト」を返すだけです
  • クライアント(例:CherryStudio、NextChat、openwebui)がモデルが特定の応答テキストを返したことを観察すると、クライアントはモデルの応答テキストに記載されたプラグインを実行します。もちろん、クライアントはモデルの特別な応答を完全に無視することもできます

簡単なフローは以下の通りです
image.png

FunctionCall#

ローカルの天気を取得する例

リクエスト構造は以下の通りです:
functions または tools(最新の functions の別名)を通じて、モデルに現在のクライアントが天気を取得する能力を持っていることを伝えます

{
    "messages": [
        {
            "role": "system",
            "content": "あなたは役に立つアシスタントです。"
        },
        {
            "role": "user",
            "content": "今日は上海の天気はどうですか?湿度はどうですか?"
        }
    ],
    "functions": [
        {
            "name": "get_localtion_weather",
            "description": "get_localtion_weather、特定の場所の現在の天気状況を取得します",
            "parameters": {
                "type": "object",
                "properties": {
                    "localtion": {
                        "type": "string",
                        "description": "localtion,場所"
                    },
                    "need_humidity":{
                        "type":"boolean",
                        "description":"湿度を返すかどうか、デフォルトはfalse"
                    }
                },
                "required": [
                    "localtion"
                ]
            }
        }
    ],
    "function_call": "auto",
    "temperature": 0.5,
    "stream":false,
    "model": "gpt-4o"
}
curl --location 'https://api.xxxxx.com/v1/chat/completions' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer sk-xxxxx' \
--data '{
    "messages": [
        {
            "role": "system",
            "content": "あなたは役に立つアシスタントです。"
        },
        {
            "role": "user",
            "content": "今日は上海の天気はどうですか?湿度はどうですか?"
        }
    ],
    "functions": [
        {
            "name": "get_localtion_weather",
            "description": "get_localtion_weather、特定の場所の現在の天気状況を取得します",
            "parameters": {
                "type": "object",
                "properties": {
                    "localtion": {
                        "type": "string",
                        "description": "localtion,場所"
                    },
                    "need_humidity":{
                        "type":"boolean",
                        "description":"湿度を返すかどうか、デフォルトはfalse"
                    }
                },
                "required": [
                    "localtion"
                ]
            }
        }
    ],
    "function_call": "auto",
    "temperature": 0.5,
    "stream":false,
    "model": "gpt-4o"
}'

応答構造は以下の通りです:
image.png

クライアントはローカルの get_localtion_weather 関数を実行します

全体のフローは図の通りです(下の図は OpenAI のドキュメントからの抜粋で、翻訳は没入型翻訳からのものです)
image.png

MCP#

簡単に理解すると:functionCall は自分で書いたものであり、統一された規約はなく、MCP は一種の紳士協定であり、mcpServer(天気プラグインを照会する) は MCP プロトコルに従って開発され、mcpClient(カーソル)が呼び出します。本来は自分で関数を書く必要がありましたが、今は他人のライブラリを呼び出すことになりました

image.png

MCP の重点は、MCP クライアント(Cherry Studio)がどのように MCP サーバー(「プラグイン」)を発見し、「プラグイン」が持つ能力を理解し、「プラグイン」を呼び出し、「プラグイン」の応答結果を取得するかです

具体的には

  • 現在持っているプラグイン機能をモデルに送信する(functions(別名 tools)による記述方法、プロンプト方式)
  • MCP クライアント(Cherry Studio)がモデルの応答に基づいて「プラグイン」を実行するかどうか、どのプラグインを実行するかを判断するのはクライアント自身が定義します
  • MCP クライアントがプラグインの実行結果をモデルに返すことも自分で定義できます

以下の部分は、応用分野において、MCP の対話フローを結合した例を示しており、MCP という「紳士協定」について具体的に詳述しているわけではありません

Cherry Studio の例#

mcpServers の設定は以下の通りで、和風天气 のサーバーが一つだけです
出典:HeFeng Weather MCP Server | Glama

{
  "mcpServers": {
    "hefeng-weather": {
      "isActive": true,
      "command": "npx",
      "args": [
        "hefeng-mcp-weather@latest",
        "--apiKey=key-123132131321"
      ]
    }
  }
}

対話は以下の通りです
image.png

  1. ローカルでインターセプトした最初のリクエストを確認すると、tools による記述方法で、モデルに対してローカルがどの「プラグイン」を持っているか、またどの能力を持っているかを伝えています
{
  "model": "gpt-4o",
  "messages": [
    {
      "role": "user",
      "content": "今日は上海の天気はどうですか?"
    }
  ],
  "temperature": 0.7,
  "max_tokens": 2000,
  "stream": true,
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "fd71edc4f65924613b9fd8330e78eb243",
        "description": "中国国内の天気予報を取得します",
        "parameters": {
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "カンマ区切りの緯度経度情報 (例:116.40,39.90)"
            },
            "days": {
              "type": "string",
              "enum": [
                "now",
                "24h",
                "72h",
                "168h",
                "3d",
                "7d",
                "10d",
                "15d",
                "30d"
              ],
              "description": "予報日数、nowはリアルタイムの天気、24hは24時間予報、72hは72時間予報、168hは168時間予報、3dは3日予報、以降同様"
            }
          }
        }
      }
    }
  ]
}
  1. 最初の応答を確認すると、モデルが「天気プラグイン」を実行するかどうかを判断します。
    モデルは「天気プラグイン」を使用する必要があると判断し、モデル自体は判断を行っただけです

image.png

  1. MCP クライアント(Cherry Studio)は「天気プラグイン」を実行し、他人が書いたパッケージや API を呼び出したと簡単に考えることができます
  2. 実行結果をモデルに返し、対話の文脈に追加します
{
  "model": "gpt-4o",
  "messages": [
    {
      "role": "user",
      "content": "今日は上海の天気はどうですか?"
    },
    {
      "role": "assistant",
      "tool_calls": [
        {
          "id": "call_M4eYNv6oPaLunpZLe1iWdfiK",
          "function": {
            "name": "fd71edc4f65924613b9fd8330e78eb243",
            "arguments": "{\"days\":\"now\",\"location\":\"121,31\"}"
          },
          "type": "function"
        }
      ]
    },
    {
      "role": "tool",
      "content": "[{\"type\":\"text\",\"text\":\"場所: 121,31\\n観測時間: 2025-03-27T16:51+08:00\\n天気: 曇り\\n温度: 13°C\\n体感温度: 12°C\\n風向: 東北風\\n風力: 1級\"}]",
      "tool_call_id": "call_M4eYNv6oPaLunpZLe1iWdfiK"
    }
  ],
  "temperature": 0.7,
  "max_tokens": 2000,
  "stream": true,
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "fd71edc4f65924613b9fd8330e78eb243",
        "description": "中国国内の天気予報を取得します",
        "parameters": {
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "カンマ区切りの緯度経度情報 (例:116.40,39.90)"
            },
            "days": {
              "type": "string",
              "enum": [
                "now",
                "24h",
                "72h",
                "168h",
                "3d",
                "7d",
                "10d",
                "15d",
                "30d"
              ],
              "description": "予報日数、nowはリアルタイムの天気、24hは24時間予報、72hは72時間予報、168hは168時間予報、3dは3日予報、以降同様"
            }
          }
        }
      }
    }
  ]
}
  1. モデルは文脈(送信された対話履歴)に基づいて応答します
    その一部を抜粋します
    image.png

Cherry Studio は functionCall の方法を通じて、どの「プラグイン」の機能を実行すべきかを判断します

カスタムプロトコル(システムプロンプトの方法を使用)#

あなたはインテリジェントアシスタントであり、MCP 機能を持っています。MCP はローカル機能プラグインと理解できます。ユーザーの文がプラグインを呼び出す必要がある場合、以下の規定に従って厳密に応答を返す必要があります。規定は以下の通りです:
<plug>
	<pn>プラグイン名</pn>
	<fn>関数名(機能名)</fn>
	<arg1>パラメータ</arg1>
	<arg2>パラメータ2<arg2>
	<arg3>パラメータ3<arg3>
<plug/>。
ローカルで特定のプラグインが実行された後、結果は以下の形式で返されます
<tool_res>
	<plug>
		<pn>プラグイン名</pn>
		<fn>関数名(機能名)</fn>
		<res>実行結果<res/>
	<plug/>
<tool_res/>

現在のローカルプラグイン:
1. プラグイン名:get_localtion_weather
	説明:特定の場所の天気を照会するプラグイン
	 機能:
	 - query_now_weather:
	 	args:
	 		location:string,必須,照会場所
	 		need_humidity:boolean,非必須,デフォルトはfalse,湿度を返すかどうか

図中に示されているのは ChatBox であり、他のクライアントは <xx><xx/> を処理し、表示されません

image.png

image.png

参考動画とリンク🔗#

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。