🥳

A2A × MCPで初マルチAIエージェント開発!

に公開

はじめに

初めまして!Givery AIラボでAIエンジニアをしている李です。
みなさん、AIと聞いたとき、最初にどんなキーワードを思い浮かべますか?私の場合は、AIエージェントです。「AIが自律的に行動まで」を意味するAIエージェントへの世の中の注目度は右上がりする一方です。

AIエージェントは「個」から「群」の時代へ 🚀

驚くほど高性能な生成AIモデルが次々と登場する最近ですが、現実世界の複雑なタスクを本当の意味で自律的かつ効率的に処理するには、個々のAIが持つ能力を組み合わせた「グループワーク」が不可欠です。

つまり、強力な1つのAIだけに頼る時代から、(ドメイン特化した)複数のAIエージェントが連携する「マルチAI」の時代に移り変わろうとしているのです。

全テクノロジー業界にとって大きなターニングポイントと言えるこの変化、転換点こそが、今の「生成AI登場によるAIの波」が継続するため乗り越える必要のある課題です。

マルチエージェント実現の鍵:A2A × MCP

マルチエージェント時代を実現するためには、異なる能力を持つAIエージェント同士をいかに連携させ、情報を共有し、共同作業を進めさせるかという課題の解決が必要です。

そこで、今回の記事は、「AIエージェント同士のチームワーク」を実現するための鍵となる二つプロトコル:Agent2Agent (A2A) ProtocolとModel Context Protocol (MCP)にスポットを当てます。

また、これらプロトコルを活用した実際の、「Pythonコードの生成からテストまでを自動化するマルチAIエージェントシステム」の開発経験も共有して、マルチエージェント時代の実現可能性等について考えてみたいと思います!

本記事内容のまとめ

  • A2AとMCPはなぜ重要で、それぞれ何ができるのか

  • プロトコルを通じて具体的にAIエージェントがどんな風に連携されるのか

  • 実際に動くシステムのデモ

  • 今後のAI開発、どう変わっていくのか

本記事が、「A2AやMCPがまず気になる」「複数のAIを協力させたいけど具体的な方法が分からない」と悩んでいるエンジニアのみなさんにとって、役立つ情報になればとても嬉しいです!

第1章:「あったらいいな」でスタート、Python開発自動化への挑戦

生成AI時代のソフトウェア開発

(Python等の)ソフトウェア開発では、コードスニペット・テストコード・テストケースの作成、あるいは簡単なリファクタリングといった作業パターンのリピートが多く、時間が費やされる場合がよくあります。このようなルーチンワークはAI活用で速やかに、開発者はより価値の高い生産に取り組むという考え方は、今の時代ではもはや常識となりました。

そこで、「仕様の理解からのコード生成」「コードテストの設計」「テストの実行および結果分析」までの一連のタスクをアシスト・自動化させる!というのが、今回のモチベーションとなります。既にOpenAIの推論モデルだったりClaudeGemini等とのチャットベース、またはClineCodexなど(良かったらCodex活用ガイド記事もご覧ください!)のアドインを活用される方も多いと思います。

コード開発アシスタントを「マルチAI」にすることの意味

コード作成やテストなど、各タスクに特化したAIエージェントをそれぞれ連携させることで、より効率的かつ高レベルな自動化が実現できるという考え方で、まるで開発者が対話しながら成果物をやり取りするように、「コード生成AI」と「コードテストAI」が協力するイメージです。

指示が簡単に  まずタスクを分割して各エージェントに任せるので、指示内容の過剰によるプロンプトの複雑化を防げます。高レベルの自動化が実現されると、「〜〜の処理をして、OOの出力してください」みたいな指示を出す必要もなく、AIが次のアクションをレコメンドし、他エージェントと連携して実行までしてくれるので、そもそもプロンプトを書く必要がなくなります。

軽量モデルが使える  タスクごとにAIを特化させるので、あらゆるタスク全てを上手く処理できる「Lサイズの」AIモデル以外にも、低コストで応答も早い「Sサイズの」モデルも活用できます。実際に今回は、生成から回答まで10秒もかからない Googleの軽量フリーモデル Gemini-2.0-flashを使いました。

コンテキストウィンドウの制約が緩和  触れた経験のある方だとすぐ共感できるお話ですが、長いテキストを扱うコード開発にて、LLMのコンテキストウィンドウの制約は、各種AIコーディングツールの出力精度の低下の主な原因です。タスクを分担して作業しながらも、連携でよりコンパクトに情報共有できる「マルチAI」仕組みは、実践的なコーディング問題にて良い精度を記録してます。

第2章: AIエージェント連携の鍵! A2AとMCPプロトコル解説

複数のAIエージェントが円滑に協力し、効率よくタスクを達成するためには、エージェント間で使う「共通の言葉」や「情報のやり取り方法」を標準化する必要があります。その課題を解決するために誕生したのが、 Agent2Agent Protocol (A2A)Model Context Protocol (MCP) という二つのプロトコルになります。

2.1. Model Context Protocol (MCP) – LLMに「文脈」と「ツール」を与える

MCPとは何か?

Model Context Protocol (MCP) は、LLMに対して、外部のツールやタスク遂行に必要なコンテキスト情報を、標準化された方法で提供するためのオープンプロトコルです。簡単に言うと、外部ツールとのやりとりする方法を決めて、AIエージェントとして行動を起こすための手段を与える技術標準になります。

なぜMCPが必要なのか?

AIエージェントが、情報検索等の外部API呼び出しといった「ツール」を利用したり、ユーザーとの対話履歴などの「コンテキスト情報」を理解する際などに、そのやり取りの方法を明確なパターン化することで、開発者がより効率よくAIアプリケーションを構築・管理できるように支援します。

MCPの主な機能とメリット

MCPの導入で得られる一番の価値は、「拡張性」です。サービスを利用する側も、提供する側も、MCP標準のことだけを考えて開発し、モジュールとして自由に組み合わせることで、様々なAIアプリケーションの実装が可能になります。

ツール利用の標準化  エージェントが外部ツールを呼び出し、その結果を受け取るための明確なパターンを提供します。これにより、エージェントの能力を動的に拡張できます。

コンテキスト管理  LLMに与えたい情報を構造化して効果的に伝達します。例えば、VSCodeで開いているファイル名のリストや、ツールの実行結果・エラーメッセージなどの情報を、LLMに効率よく提供できます。

応答処理の明確化  エージェントからの応答形式(テキスト、データ、あるいはUI要素など)を管理し、多様なアウトプットに対応できるようにします。

mcp_code_runner_server/main.py
# MCP標準に沿った形で「Pythonコード実行ツール」をポスト
@app.post(
    "/mcp/tools/execute_python_code_v1/invoke",
    response_model=CodeExecutionResult,
    summary="Execute Python code snippet",
    operation_id="execute_python_code_v1"         
)
async def execute_code_tool(request: CodeExecutionRequest) -> CodeExecutionResult:
    result_dict = await asyncio.to_thread(
        execute_python_code_in_subprocess,
        request.code_src,
        request.test_expr,
        request.expected_output_str,
    )
    return CodeExecutionResult(**result_dict)
mcp_code_runner_server/models.py
# ポストしたツールを利用するための入力フォーマットを定義
class CodeExecutionRequest(BaseModel):
    code_src: str
    test_expr: str
    expected_output_str: Optional[str] = None

# ポストしたツールの出力フォーマットを定義
class CodeExecutionResult(BaseModel):
    test_case: str
    execution_time: float
    stdout: str
    stderr: str
    return_code: int
    expected: Optional[Any] = None
    actual: Optional[Any] = None
    success: Optional[bool] = None
    error_type: Optional[str] = None
    error_message: Optional[str] = None

今回の開発では、AIが設計したPythonコードのテストを実行するツールとして、MCP標準のサーバーを作りました。このサーバーと、LLMモデルをMCP標準で繋ぐことで、「Pythonコードを実行できるAIエージェント」が誕生します。


2.2. Agent2Agent Protocol (A2A) – AIエージェント間の対話ルール

A2Aとは何か?

Agent2Agent Protocol (A2A) とは、Googleが提唱したAIエージェント間の相互運用性を実現するオープンプロトコルで、「タスクを依頼する側(クライアント)」と「タスクを実行する側(リモート)」の間のコミュニケーションをスムーズにする仕組みです。

一見、MCPとあんまり変わらないよう思われますが、他エージェントの情報・タスクの進捗状況・作業内容のやりとりなど、エージェント同士の協業によりフォーカスされている面があります。

なぜA2Aが必要なのか?

異なるエージェント同士がまるで同じ「言語」を話すようにコミュニケーションできれば、マルチAIシステムの柔軟性や拡張性が飛躍的に向上します。A2Aはまさにその課題を解決するために設計されました。

A2Aの主な機能とメリット

標準的メッセージ形式  複雑なインテグレーション作業を軽減し、迅速なシステム構築をサポート

タスク委任と実行  標準化されたメッセージで、クライアントからリモートエージェントへのタスク依頼と結果の返却を実現

エージェント発見性  「エージェントカード」というメタデータで、他エージェントの機能や利用方法を簡単に把握可能

A2Aの一番特徴的なところは、「エージェントカード」です。エージェントサーバーによって公開されるエージェントカードは、まるで人の名刺みたいに、各エージェントのID、能力、スキル、エンドポイントURL、認証要件などが記述されており、「どのようなエージェントが存在し、何ができて、どのように話しかければよいか」を把握できるようにする機能です。

code_generation_agent/agent_card_def.py
# Pythonコードを生成するエージェントを定義
# エージェントカード
cga_agent_card = AgentCard(
    name='Pythonコード作成エージェント',
    description='自然語記述のプロンプトからPythonコードを作成するAIエージェント',
    url=CGA_URL,
    version='1.0.0',
    defaultInputModes=['application/json'],
    defaultOutputModes=['application/json'],
    capabilities=AgentCapabilities(streaming=True),
    skills=[generate_code_skill],
    authentication=AgentAuthentication(schemes=['public'])
)

# スキル定義
generate_code_skill = AgentSkill(
    id='generate_python_code',
    name='Pythonコードの作成',
    description='自然語プロンプトからPythonコードを作成できる',
    tags=['code generation', 'python'],
    inputModes=['application/json'],  # {"code_description": "コード説明"} 形式のJSONを期待
    outputModes=['application/json'], # {"generated_code": "code string"}
    examples=['フィボナッチ数を計算するメソッドを作成してください']
)

code_testing_agent/agent_card_def.py
# Pythonコードのテストケースを生成して実行、テスト結果を返すエージェントを定義
# エージェントカード
cta_agent_card = AgentCard(
    name='Pythonコードテストエージェント',
    description='Pythonコードのテストプランを作成・実行し、その結果を提供するAIエージェント',
    url=CTA_URL,
    version='1.0.0',
    defaultInputModes=['application/json'],
    defaultOutputModes=['application/json'],
    capabilities=AgentCapabilities(streaming=True),
    skills=[test_code_skill],
    authentication=AgentAuthentication(schemes=['public'])
)

# スキル定義
test_code_skill = AgentSkill(
    id='test_python_code',
    name='Pythonコードのテスト',
    description='与えられたPythonコードのテストケースを作成・実行し、その結果を (stdout, stderr, success/failure, execution_time)として提供する',
    tags=['python', 'code test'],
    inputModes=['application/json'],  # {"code_to_test": "code string"}
    outputModes=['application/json'], # テスト結果を含むJSON
    examples=["print('Hello world')"]
)

実装したシステムには、「仕様情報からPythonコードを作成するエージェント」と、「Pythonコードからテストを設計・実行するエージェント」があります。各エージェントの詳細情報をカードとして定義することで、相手と協業するために必要な情報を取得できます。


2.3. A2AとMCPの関係 - 競合か補完か?

A2AMCP は、それぞれ異なる側面から来るAIエージェント時代における標準化をリードしています。A2Aがエージェント間の「通信路」とその上での対話フローを標準化するのに対し、MCPはその通信路を通じて交換される「情報の中身」、特にツール利用やコンテキスト情報の「フォーマット」を標準化します。

Agent2Agent Protocol Model Context Protocol
主な目的 AIエージェント間における通信と相互運用性の標準化 LLM(エージェントの頭脳)へのツール利用とコンテキスト提供の標準化
スコープ エージェント間の対話フロー全体、タスクの委任と結果の授受 エージェント内部のLLMと外部リソース(ツール、データ)との連携
主要な概念 クライアント/リモートエージェント、エージェントカード、タスク定義 ツール定義、コンテキスト提供、パラメータ形式、レスポンス形式
本システムでの主な役割 エージェント間のタスク依頼・結果通知の実現 各エージェントが持つ機能(ツール)のインターフェース定義とコンテキスト伝達

今回の開発経験から、この2つプロトコルは相互補完的な関係であると強く感じました。仮に片方だけあったとしたら、倍以上のエフォートがかかっていたのでは、と思います。

第3章: 開発事例から理解を深める!

ここでは、今回取り組んでみました、初A2A × MCPのマルチAIエージェント開発、「Pythonコードの生成からテストまでを自動化するシステム」の開発経験について共有します。まずはこちら、デモ動画をご覧ください!

デモ: マルチAIエージェントによる、Pythonコードの生成からテスト

https://youtu.be/RSegWrMQXio

生成させたいPythonコードを書いてボタンを押すと裏でエージェントがコードを生成、その後コードテストボタンを押すとテストケースを生成・実行して、その結果を分析して返すようになっております。


3.1. システム機能の紹介

>> デモ動画の詳細説明はこちら <<

ステップ1:コードの生成

欲しいPythonコードについてUI上に記述して、下の Generate Code ボタンを押すことでコード生成エージェントに「コード生成」タスクのリクエストが送信されます。

ボタンを押すと、エージェントのタスクが終わるまで Running... とUIの右上に表示されて、

このように、キャンバス的な感じで画面下に生成したコードが出力されます。

ステップ2:コードのテスト

続けて、生成されたコード下のUIで、テストケースの数を入力して Test Code ボタンを押すと、コードテストエージェントに「コードテスト」タスクのリクエストを送ることができます。

Test Code を押したあと少し待つと、コードテストのレポートがテストケース単位にまとまって作成されます。

レポートには、次のような内容が含まれてます。

  1. コード実行時間:テストケースの実行にかかった時間(秒)
  2. 出力期待値:テストエージェントがインプットと合わせて生成した出力期待値の Expected output
  3. 出力結果値:実際にコードをMCPツール経由で実行して得た出力の Returned output
  4. テスト結果:出力期待値と結果値が一致しているか
  5. 結果コメント:テスト結果における、テストエージェントからのコメント内容




ちなみに、コードテストエージェントは「批判的」なペルソナを付与して、正常ケース1:エッジケース1:エラーケース1比率としてテストケースを生成するように注文しています(笑)。

ユーザーはレポート内容を見て、コードが望み通り作成されたのかをチェックできます。また、レポート内容をコード作成エージェントに与えることで、コードの再作成や改善をリクエストすることも可能です。


3.2. システム全体図

a2a_mcp_multi_agent_system/
├── streamlit_app/
│   ├── app.py               # Streamlit UIとオーケストレーションロジック
│   └── a2a_client.py        # A2Aクライアント通信のヘルパー関数
├── code_generation_agent/
│   ├── main.py              # コード作成エージェントのA2Aサーバーロジック
│   ├── agent_executor.py    # エージェント機能実装
│   └── agent_card_def.py    # AgentCardを定義
├── code_testing_agent/
│   ├── main.py              # コードテストエージェントのA2Aサーバーロジック
│   ├── agent_executor.py    # エージェント機能実装
│   └── agent_card_def.py    # AgentCardを定義
├── mcp_code_runner/
│   ├── main.py              # コードテストを実行するMCPサーバーロジック
│   ├── execution.py         # サーバー機能実装
│   └── models.py            # やりとりするデータのフォーマット定義
├── .env                     # 環境変数
└── requirements.txt         

紹介しましたシステムは、

  1. Streamlit UI
  2. Pythonコードを生成するAIエージェント
  3. Pythonコードのテストケースを生成するAIエージェント
  4. Pythonコードを実行するMCPサーバー

の4つコンポーネントで構成されています。

左のワークフローは Generate Code ボタンの動作を、右のワークフローは Test Code を表しています。

システム特徴

マルチエージェントによるタスク専門化  2つエージェントをそれぞれ「コード作成」と「テストケース作成」だけに集中・特化させたことで、軽量モデルを使った高速でローコストなシステムを実装しました。

シームレスな連携による操作の簡潔さ  Streamlit および A2A / MCP を適切に活用、数ステップの簡単な操作でエージェント間のスムーズな「バトンパス」と実装し、一連の機能を直感的かつ使いやすく実装しました。

このような特徴は、今回の記事で紹介しました、A2AMCP の2つプロトコルをベースとして成立しています。


3.3. 技術スタック

ロール A2A/MCP Context
Python 全てのコンポーネント(エージェント、オーケストレータ、MCPサーバー)のコア開発言語 a2a-pythonライブラリはPythonベースであり、システム全体がPythonエコシステム内で完結
Gemini API AIエージェントの「頭脳」としての機能。コード生成やテスト設計のロジックの基盤となるLLM A2Aがこの「知能」をオーケストレートし、MCPがこの知能にツールやコンテキストを提供する対象
a2a-python A2Aプロトコルに基づくエージェント間通信ロジックおよびサーバー/クライアント機能の実装 エージェント間のA2Aメッセージングを実現するためのコアライブラリ
FastAPI AIエージェントが持つツールをMCP標準のエンドポイントとして公開するためのWebサーバーおよびサーバー/クライアント機能の実装 FastApiMCPを通じて、MCPツールインターフェースのためのHTTPサーバー基盤を提供
Streamlit ユーザーインターフェースの提供、およびAIエージェント群の対話を統括するオーケストレータ A2Aクライアントとして機能し、各エージェントとのA2A基盤タスクを開始・管理し、全体のワークフローを制御する

第4章: 初A2A × MCP開発の感想と発見、そして今後の展望

A2AMCP の導入を通じて得た学び・感想や、今度の開発にて遭遇した問題、そしてこのシステムの今後の展望について触れます。

4.1. 初A2A × MCP導入で得た知見・学び

標準プロトコルが持つ威力  A2AMCP という、コミュニケーションにおける「ルール」が存在することで、エージェント間のインターフェース設計が格段に明確になりました。結果、各エージェントの内部ロジック開発だけに集中できるようになります。プロトコルの詳細は python-a2a のようなライブラリに実装されているので、マルチAI開発のハードルは今後どんどん低くなっていくと思います。

エージェントのタスク分割の重要性  開発する側としてマルチAIエージェント構造は、物凄くメリットのある特徴だと感じました。コードの生成とテストというタスクを明確に切り分けしたことで、各エージェントのロジックおよびプロンプトがシンプルになり、精度改善などの工夫が独立した状態実施できる点は、サービスの完成度や管理コストの低下に繋がるポイントです。


4.2. マルチAIエージェント開発における課題と工夫点

エージェント間の状態同期  複数のエージェントを連携させてタスクを処理する場合、タスクにおけるエージェントの状態や、各状態で共有すべきコンテキスト情報を明確に定義する必要があります。

code_generation_agent/agent_executor.py
from a2a.types import TaskStatus, TaskState

# コード生成エージェントのロジック
class CodeGenerationAgentExecutor(AgentExecutor):
    @override
    async def execute(
        self,
        context: RequestContext,
        event_queue: EventQueue,
    ) -> None:

        ...

        # 初期タスク状態を送信
        initial_task_status = TaskStatus(
            state=TaskState.working,
            message=_new_agent_message("Code generation started.")
        )

        ...
        (タスクを処理して)
        ...
        
        # 最終タスク状態を送信
        final_task_status = TaskStatus(
            state=TaskState.completed,
            message=_new_agent_message("Code generation completed.")
        )

エラーハンドリング  あるエージェントがタスクに失敗した場合(例えば、LLMから想定してないレスポンス形式が返ってきたり、タイムアウトなど)、その状態を他のエージェントにどうシェアしてハンドリングするべきかを予め考えて対応する必要があります。

マルチAIのためのプロンプト  各エージェントが高いパフォーマンスを発揮するためには、それぞれのタスクに最適化されたプロンプトの設計が不可欠です。また、LLMの回答をLLMの入力にさせることになるので、各エージェントの入出力に対する工夫がより大事になってきます。

エージェントデバッグ  複数のエージェントが非同期的に動作する場合など、問題の原因特定が難しくなることがあります。今回の開発では、各エージェントのA2Aメッセージのロギングやトレーシングが非常に有効でした。


4.3. 開発したシステムの今後の課題

機能拡張による包括的な開発支援

  • リファクタリングエージェント: 生成されたコードや既存コードの品質を向上させるためのリファクタリングを提案・実行するエージェント
  • ドキュメント作成エージェント: 生成されたコードに対する説明コメントや、APIドキュメントを 作成するエージェント
  • デプロイメント支援エージェント: 生成・テストされたコードを特定の環境へデプロイするためのスクリプト生成や手順をサポートするエージェント
  • セキュリティ脆弱性診断エージェント: 生成されたコードに潜むセキュリティリスクを検査するエージェント
  • パフォーマンス分析エージェント: コードの実行効率を分析し、ボトルネックを特定するエージェント

自律性の向上と高度な協調
現状の、Streamlit 主導の連携から一歩進んで、エージェント同士がより自律的に状況を判断し、共同作業する仕組みこそが、マルチAIが目指すべき究極点だと思います。例えば、コードテストエージェントが失敗ケースを検出した場合、コード作成エージェントにその情報を自動でフィードバックし、コードの修正改善を試みるといったループの形成です。

おわりに

本記事では、Pythonコードの作成からテストまでを自動で行うマルチAIエージェントシステムを開発事例として、AIエージェント間の連携を実現する上で鍵となる Agent2Agent Protocol (A2A)Model Context Protocol (MCP) の特徴および重要性、具体的な活用方法について紹介しました。

本記事のまとめ

  • A2AMCP は、それぞれエージェント間の「通信路」と「情報形式」を標準化することで、多様なAIエージェントが協調して動作するための強力な基盤を提供するプロトコル

  • 紹介したPythonコード作成・テスト自動化システムでは、コード作成・テストに特化した2つエージェントを、A2AとMCPを同時活用して連携させることができました

  • 各プロトコルはライブラリ化されており、マルチエージェントシステムの開発ハードル・コストを多く下げています

AIエージェントは、もはや「個」として機能するだけでなく、互いにその能力を補い合い、より複雑で高度なタスクをこなす「へと進化しつつあります。A2AMCP 2つプロトコルは、この進化をリードしていくための、より強力で、柔軟で、相互補完的なAIシステムを構築するための重要な鍵です。

当記事へのご感想や、皆様が考えるマルチエージェントシステムのアイデア、あるいは A2A / MCP に関する疑問点などのコメントはいつでも大歓迎です!最後までご覧いただき、ありがとうございました!引き続きよろしくお願いいたします。

Givery AI Labについて

Givery AI Labが独自保有するフリーランス・副業の高単価AI案件や、随時開催しているセミナーやパーティなどのイベントにご興味ございましたら、ぜひTrack Worksのアカウント登録いただき、最新情報を受け取ってください!

https://job.tracks.run/track-works?utm_source=zenn&utm_medium=articles&utm_campaign=20250527

「Track Works」とは?
Givery AI Labの運営会社である株式会社ギブリーが提供する、AI時代のフリーランスエンジニアとして「スキル」と「実績」を強化できる実践的なAI案件を、ご経歴やスキルに合わせてご紹介するフリーランスエンジニア案件マッチングサービスです。Givery AI Labが独自保有するフリーランス・副業案件を紹介したり、AI関連技術やエンジニアのキャリアに関するイベントを随時開催しています。

また、Givery AI Labメンバーとして就職・転職をご検討いただく場合は、下記からご応募くださいませ!
https://hrmos.co/pages/givery/jobs?category=1688060102702190592
(運営会社である株式会社ギブリーのエンジニア向け求人一覧ページです)

【企業のご担当者様へ】
Givery AI Labでは、PoCで終わらせない「AIの社会実装」を実現するため、AI開発プロジェクトのPoCから本格実装・運用まで、幅広く伴走支援しております。ぜひお気軽にお問合せください。
・AI開発プロジェクト伴走支援サービス:https://givery.co.jp/services/ai-lab/
・生成AI技術に関するお悩み解決サービス「Givery AI 顧問」:https://givery.co.jp/services/ai_advisor/

Givery AI Lab

Discussion