MCP を見ていて、Function calling の延長線上で考えられそうだったので、その方向でまとめてみました。また、プッシュ型・プル型のコンテキストでも考えてみます。
比較
Function calling と MCP は、LLM が外部呼び出しを要求するという点では共通していますが、その後のフローに違いがあります。
Function calling では、LLM は関数呼び出しのパラメータを生成するだけで、実際の関数実行はアプリケーション側で行う必要があります。関数実行の結果を使って最終的な応答を生成するための処理フローは、開発者が独自に実装する必要があります。
アプリケーションが主体となって LLM を制御して、回答を生成します。
一方、MCP ではプロトコルとして、LLM が MCP サーバーへデータを要求して、その結果を LLM が受け取り、それを情報源として LLM が最終的な応答を生成するまでの一連のフローが規定されています。これにより、開発者は個別にデータ取得後の処理フローを実装する必要がなく、MCP に準拠したシステムを構築するだけで、LLM が外部データを活用した応答生成まで一貫して行うことができます。
LLM が主体となって回答を生成します。
このように、MCP は Function calling よりも外部データの活用をより包括的に実現するプロトコルとなっています。
細かく見れば、MCP でも LLM のクライアントアプリケーションが LLM と MCP サーバーの間に入っています。そのため Claude ではデスクトップアプリケーションが必要になります。上図では、LLM とそのクライアントアプリケーションを一体のものとして考えています。
ユーザー視点では、Function calling はアプリケーションに隠蔽されるため意識する必要はありませんが、MCP はプラグインのようなものに見えます。
追記
クライアントアプリケーションの部分を作り込めば、Function calling から MCP サーバーが利用できるのでは?という発想ができます。それを実際に実装することで、GPT-4o で MCP サーバーを利用する記事があります。
プッシュ型・プル型
Function calling と MCP は、どちらも LLM が外部システムに対して何らかの要求を行うという点では同じですが、その要求の性質が異なります。
Function calling では、LLM が関数実行の要求を外部にプッシュします。「この関数をこのパラメータで実行してほしい」という具体的な実行要求を送り、その結果を受け取って処理するフローを開発者が作り込む必要があります。
一方、MCP では、LLM が外部システムから情報をプルする形になっています。必要な情報やコンテキストを「このような情報が欲しい」という形で要求し、その情報を直接取得して応答生成に活用します。このプル型のデータ取得は、プロトコルとして規定されているため、開発者は個別の処理フローを実装する必要がありません。
このように、LLM から見た操作の方向性という観点で、Function calling は「実行要求のプッシュ」、MCP は「情報のプル」という特徴の違いがあります。
関連記事
参考
シーケンス図でフローが示されます。
プッシュ型・プル型という分類は情報配信の形態としてよく使われますが、個人的には XML パーサーに馴染みがあります。