この動画では、PydanticとLogfireの開発者であるSamuel Colvinが、MCPがエージェント間通信の多くの課題を解決できる強力なツールであることを解説している。MCPのサンプリング機能により、リモートMCPサーバーが元のエージェントのLLMアクセスを共有できる仕組みや、実際のコード例を通じてBigQueryを使った研究エージェントの実装方法を紹介している。

講演の概要とサミュエル・コルビンの紹介
皆さん、「MCPが全て」というテーマでお話しさせていただきます。まず始めに、私について少し紹介させていただきます。私はPydanticの創設者として最もよく知られています。PydanticはPython用のデータ検証ライブラリで、現在非常に広く使われており、月間約3億6000万回ダウンロードされています。つまり1秒間に約140回ダウンロードされているということを、誰かが指摘してくれました。
PydanticはPython開発全般で使用されていますが、生成AIの分野でも活用されています。基本的にPythonのSDKやエージェントフレームワークのすべてで使用されています。Pydanticは2023年初頭に会社となり、それ以来Pydantic以外に2つのプロダクトを構築しました。Pydantic AIは、Pydanticと同じ原則で構築されたPython用のエージェントフレームワークです。そしてPydantic Logfireは観測プラットフォームで、これが私たちのビジネスの商業的な部分となっています。
MCPとは何か、そして「MCPが全て」の真意
私は同時に、MCP Python SDKの多少非アクティブな共同メンテナーでもあります。「MCPが全て」というタイトルは、明らかにJason LouがAI Engineerで行った「Pydanticが全て」という講演のパロディです。最初の講演はほぼ2年前、2回目の「Pydanticがやはり全て」は多分昨年のこの時期でした。
基本的な考え方は同じで、人々は単一のツールで対応できることを過度に複雑化しているということです。もちろん、このタイトルは完全に非現実的です。Pydanticが全てではありませんし、MCPもすべてに対応できるわけではありません。しかし、MCPができることは非常に多く、人々がエージェント間通信の新しい方法を考案しようとして状況を過度に複雑化していることがあると考えています。
MCPの設計目的と使用ケース
ここで具体的に話しているのは、自律エージェントや皆さんが書いているコードについてです。Claude DesktopやCursor、Windsurf等のコーディングエージェントの使用ケースについて話しているわけではありません。それらは元々MCPが主に設計された用途でした。David Pereiraが、私たちがPythonからMCPを使用していることを誤用とは言わないでしょうが、MCPの主要な設計用途ではなかったと思います。
MCPの原始的機能のうち、プロンプトとリソースの2つは、この使用ケースではあまり活用されません。これらはCursorタイプの使用ケースでは非常に有用であるべきですが、私たちがここで話していることには実際には適用されません。しかし、3番目の原始的機能であるツール呼び出しは、私たちがここで実現しようとしていることにとって極めて有用です。
ツール呼び出しの複雑さとMCPの利点
ツール呼び出しは、最初に思うよりもずっと複雑です。多くの人がMCPについて、「これはOpenAPIではだめなのか?なぜカスタムプロトコルが必要なのか?」と聞いてきます。いくつかの理由があります。
動的ツールという概念があります。これは、エージェント実行中にサーバーの状態に応じて現れたり消えたりするツールです。ログ機能もあります。ツールがまだ実行中でもユーザーにデータを返すことができます。サンプリング機能もあり、これについて今日詳しくお話しします。これはMCPの中で最も紛らわしい名前の部分かもしれません。それ以外にも、トレースや観測性などの機能があります。
また、MCPが標準入力と標準出力を通じて効果的にサブプロセスとして動作できる方法も、多くの使用ケースにとって極めて有用で、OpenAPIではこれらの問題を解決できません。
MCPの基本アーキテクチャ
これは多くの人がMCPについて紹介する際に見る典型的な図です。アイデアは、何かのエージェントがあり、そのエージェントに接続できる任意の数の異なるツールがあるということです。重要な点は、エージェントがこれらの特定のツールを念頭に置いて設計される必要がなく、ツールもエージェントについて何も知らずに設計でき、ブラウザーとウェブアプリケーションの関係のように、2つを単純に組み合わせることができるということです。
ウェブサイトはブラウザーについて何も知る必要がありません。今は事実上ブラウザーのモノカルチャーに生きていますが、少なくとも元々の理想では、多くの異なるブラウザーがすべて同じプロトコルで接続できるはずでした。MCPも同じアイデアに従っています。
より複雑なアーキテクチャとサンプリングの必要性
しかし、これはもっと複雑になることがあります。システム内のツール自体がエージェントであり、エージェント的な作業を行い、LLMへのアクセスを必要とする状況があります。それらは当然、MCPや他のツールへの直接接続を通じて他のツールに接続することができます。これは美しく、エレガントに機能します。
しかし問題があります。システム内のすべてのエージェントがLLMへのアクセスを必要とします。そのため、それを設定し、リソースを把握する必要があります。リモートMCPサーバーを使用している場合、そのリモートMCPサーバーがLLMを使用する必要があるとき、そのコストがどうなるかを心配する必要があります。
リモートエージェントがツールとして動作し、元のエージェントがアクセスできるモデルを効果的に便乗利用できるとしたらどうでしょうか。それがサンプリングが提供してくれるものです。
サンプリング機能の詳細
サンプリングは、私が言うように、多少紛らわしい名前です。これは、MCPプロトコル内で、サーバーがクライアントを通じてLLMに効果的にリクエストを送り返す方法という考え方です。
この場合、クライアントがリクエストを行い、何らかの質問を開始し、LLMを呼び出します。LLMが戻ってきて、その特定のツール(MCPサーバー)を呼び出したいと言います。クライアントがそのMCPサーバーへの呼び出しを処理します。MCPサーバーが今度は、「実際にこの質問に答えるためにLLMを使用できる必要がある」と言います。
それがクライアントに送り返され、クライアントがそのリクエストをLLMにプロキシし、LLMからレスポンスを受け取り、それをMCPサーバーに送信し、MCPサーバーが結果を返して、処理を続行できます。サンプリングは非常に強力ですが、現時点ではそれほど広くサポートされていません。
今日、Pydantic AIでサンプリングをデモンストレーションします。正直に言うと、現在はプルリクエストの段階ですが、まもなくマージされる予定です。私たちは、クライアントとしてのサンプリングサポート、つまりLLM呼び出しをプロキシする方法を知っていることと、サーバーとして基本的にMCPクライアントをLLMとして登録して使用できることの両方をサポートしています。
実装例:研究エージェントの構築
この例は、明らかにすべての例と同様に、画面に収めるために簡略化されています。アイデアは、オープンソースパッケージやライブラリを研究してくれる研究エージェントを構築していることです。実際にこれに必要な多くのツールの1つを実装しました。
そのツールは、Pipパッケージの特定のパッケージのダウンロード数を取得するために、BigQueryのパブリックデータセットを照会しています。これは非常に標準的なPydantic AIのコードです。しばらく後でお見せするLogfireを設定しています。
エージェントが実行中にアクセスできる依存関係があります。LLMが間違ったデータを返した場合にリトライできるように設定しています。基本的にテーブルのスキーマを提供し、何をすべきかを伝え、いくつかの例を示す大きなシステムプロンプトがあります。
バリデーションとログ機能
しかし、おそらく強力な部分はここです。出力バリデーターとして、まずSQLからMarkdownブロック引用符を削除し(ある場合)、テーブル名が正しく、照会対象が適切であることをチェックし、そうでない場合は修正するよう指示します。そして、クエリを実行し、重要なことに、クエリが失敗した場合、Pydantic内でmodel_retryを発生させ、LLMに再試行を求めるリクエストを再度行います。
この間、context.mcp_context.logというものを使用していることがわかります。depsタイプを定義したときに、これがMCPサーバーを呼び出したときに取得するMCPコンテキストのインスタンスになると言いました。
ここで行っているのは、この場合はエージェントバリデーター内で、望むならツール呼び出し内でも可能ですが、そのコンテキストにアクセスするタイプセーフな方法を提供することです。ここで、タイプがMCPコンテキストであることがタイプレベルでわかります。
このログ機能があり、そのシグネチャがわかり、このログ呼び出しを行うことができます。重要な点は、これがクライアントに、そして最終的には処理が完了する前に見ているユーザーに返されることです。つまり、進行中の進捗更新を受け取ることができます。
MCPには、ここでは使用していませんが、進捗の概念もあります。クエリがどの程度進んでいるかがわかれば、進捗の更新を表示することも可能です。この種のログの元々の原則は、Cursorスタイルのエージェントが実行されていて、ユーザーに更新を提供したいということだと思います。まだ処理中であることと、何が起こっているかを正確に伝えたいのです。
XMLフォーマットとMCPサーバーの設定
しかし、これがウェブアプリケーションとして実行されている研究エージェントでMCPを使用している場合にも有用であることが想像できます。ユーザーに何が起こっているかを示したい場合です。この詳細な研究は実行に数分かかるかもしれません。ツール呼び出しがまだ実行中でも、これらのログを提供できます。
そして、出力を取得し、辞書のリストに変換し、XMLとしてフォーマットします。素晴らしいモデルは基本的にXMLデータのレビューが得意です。そのため、クエリ結果がどのようなものであれ、LLMが解釈しやすいXMLish形式のデータとして返します。
次に、MCPの部分に進みます。このコードでは、fast MCPを使用してMCPサーバーを設定しています。現在、fast MCPには2つのバージョンがあります。紛らわしいことに、これはMCP SDK内部のものです。
関数のdocstringを使用しています。ここでは1つのツール、Pipi downloadsを登録しており、その関数のdocstringが、最終的にそれを呼び出すことを選択するLLMに供給されるツールの説明になります。
中央エージェントでのSQL生成の問題
ユーザーの質問を渡します。ここで重要なことの1つは、もちろん中央エージェント内でSQLを生成するように設定することもできるということです。ツールの説明内にSQLの説明や指示をすべて含めることもできます。
モデルは、ツールの説明内にそれほど多くのデータがあることを好まないようです。しかし、より重要な点は、これらのクエリの作成方法に関するすべてのコンテキストをメインエージェントに送り込むと、メインエージェントのコンテキストウィンドウを爆発させてしまうということです。これは、この特定のツールを呼び出すかどうかに関係なく、そのエージェントへのすべての呼び出しでオーバーヘッドとなります。
そのため、ツール内で推論を行うこのような方法は、実行中のメインエージェントのコンテキストウィンドウを効果的に制限する強力な方法です。そして、ここから返される値である文字列であるこの出力を返し、MCPサーバーを実行するだけです。デフォルトでは、MCPサーバーは標準IOで実行されます。
メインアプリケーションの実装
次に、メインアプリケーションに進みます。ここでエージェントの定義があります。先ほど紹介したスクリプト、Pipi MCPサーバーを実行する1つのMCPサーバーを定義しているのがわかります。そのため、このエージェントがクライアントとして機能し、呼び出し可能なツールとしてそれを登録します。
また、現在の日付を提供します。エージェントがよくするように2023年であると仮定しないようにです。そして、最終的にメインエージェントを実行できます。例えば、Pydanticが今年何回ダウンロードされたかを尋ねます。勇気を出して実行してみて、何が起こるかを見てみましょう。
成功しました。私たちが今年16億回のダウンロードがあったと教えてくれました。しかし、おそらくもっと興味深いのは、Logfireでそれがどのように見えるかを確認することです。
Logfireでの観測性とトレース
Logfireに表示されるかどうか確認します。正直に言うと、これは私がステージに上がる直前の実行ですが、まったく同じように見えるでしょう。MCP内での観測性やトレースがどのように機能するかについて詳しくは話しません。直後に私の後でそれについて話す講演があることを知っているからです。これは今後の内容のネタバレと考えてください。
外部エージェントを実行していることがわかります。GPT-4oを呼び出すことを決定し、確実にこのツールを呼び出すことを決定します。SQLを生成することについて考える必要はありません。実行しようとしているクエリの自然言語記述を持つだけで済みます。
ここで見えるように、MCPクライアントがMCPサーバーに呼び出しを行います。それが再び異なるPydantic AIエージェントを実行し、それがクライアント経由でプロキシすることでLLMを呼び出します。サービスがクライアント、サーバー、クライアント、サーバーと進んでいるのがわかります。
最終的に、トップレベルのモデルとの交換を見ると、クエリを実行することから得られた最終的な出力がこの種のXMLishデータであり、LLMがそれを何が起こっているかの人間による説明に変換することができたことがわかります。
実際のSQLクエリの確認
おそらく他に興味深いことは、実際に呼び出されたSQLを確認できることです。これはMCPサーバー内のエージェント呼び出しで、ここで書かれたSQLを見ることができ、確実に正しく見えることを確認できます。
まとめと今後の展開
ここで終わりにして、ありがとうございました、と言わせていただきます。私たちはPydanticブースにいます。これについて質問がある方、これが他の多くのエキサイティングな方法で失敗するのを見たい方がいらっしゃいましたら、ぜひお話ししたいと思います。ぜひお立ち寄りください。


コメント