Google ADK・Strands・Microsoft Agent Frameworkを、記法と思想で比較してみる
先端技術開発グループ(WAND)の加藤です。
ExaWizards Advent Calendar 2 日目を担当いたします!
2025 年頭に Google Agent Development Kit(Google ADK)が登場し、初めて主要なクラウドベンダーからエージェント構築のための OSS フレームワークが提供されました。
その後、AWS が Strands Agents を発表、10 月に Microsoft Agent Framework(MAF)を発表し、Google / AWS / Microsoft の主要クラウドベンダーがそれぞれ OSS のエージェントフレームワークを持つ形になりました。
エクサウィザーズでは現在、多くのエージェント開発を進めていますが、社内のエンジニアや BizDev からも 「どのフレームワークが良さそうですか?」 と聞かれる機会が増えてきました。
このフレームワークが絶対に良い!という答えはまだなく、大きな差分もそれほどありませんが、細かく見ると違いが見えて興味深いです。
そこで今回は、それぞれのフレームワークでシンプルなエージェントを構築してみて、「どんな記法で」「どんな思想で」開発されたフレームワークなのかを、簡単に比較してみたいと思います。
【前提】どのクラウドベンダーを使うかで選ぶのが最適
まず前提として、「どのクラウドベンダーを主に使うか」で選ぶのが良さそう、という点があります。
Google ADK は Cloud Run、Strands Agents は AWS Bedrock / AgentCore、Microsoft Agent Framework は AI Foundry でのデプロイ方法が提案されており、それぞれが最適化されています。
そのため、もしデプロイ先のクラウドベンダーが決まっている場合には、対応するフレームワークを利用することがベストプラクティスと言えるでしょう。
ただし、それだけを考えると クラウドベンダーが決まったらフレームワークが決まる だけになってしまいます。
実際には、機能や記法に着目してみると、それぞれのフレームワークが持つ思想的な違いが見えてきます。
それぞれのフレームワークの開発思想
まずは、それぞれのフレームワークがどんな思想で作られているかを、公式のページを見ながら比較してみましょう。
Google ADK
まずは Google ADK です。公式ページ を見てみると、このような記載があります。
Agent Development Kit (ADK) は、AI エージェントの開発とデプロイ(展開)のための、柔軟かつモジュール式なフレームワークです。
Gemini や Google のエコシステムに最適化されていますが、ADK は特定のモデルやデプロイ環境に依存しない(モデルアグノスティックかつデプロイアグノスティック)設計となっており、他のフレームワークとの互換性も確保されています。
ADK は、エージェント開発を従来のソフトウェア開発に近い感覚で行えるように設計されました。これにより、開発者は単純なタスクから複雑なワークフローに至るまで、幅広いエージェントアーキテクチャの構築、デプロイ、そしてオーケストレーション(統合管理)を容易に行うことができます。
Google ADK は、特徴として 「Code First」 という思想のもと、ソフトウェア開発者目線で作られたフレームワーク であることがわかります。
Agent Config といった YAML 形式でエージェントを構築できる機能もフレームワークでサポートされており、 エンジニアフレンドリーな体験でエージェントを構築することを重視 していると感じます。
Strands Agents
次に Strands Agents の公式ページを見てみましょう。
公式ページ の記載内容を、抜粋して引用します。
Strands Agents は、わずか数行のコードで AI エージェントを構築・実行するモデル駆動型アプローチを採用したオープンソース SDK です。Strands は、シンプルなエージェントのユースケースから複雑なものまで、そしてローカル開発から本番環境でのデプロイまで対応します。
開発者がエージェントに複雑なワークフローを定義する必要があるフレームワークと比較して、Strands は最先端モデルの計画、思考の連鎖、ツール呼び出し、リフレクションの機能を活用することでエージェント開発を簡素化します。Strands では、開発者はプロンプトとツールのリストをコードで定義するだけでエージェントを構築し、ローカルでテストしてクラウドにデプロイできます。Strands は、DNA の二重らせんのように、モデルとツールというエージェントの 2 つの核となる部分を結びつけます。Strands はモデルの高度な推論機能を使用してエージェントの次のステップを計画し、ツールを実行します。より複雑なエージェントのユースケースでは、開発者は Strands でエージェントの動作をカスタマイズできます。
Strands Agents は、 「モデル駆動型アプローチ」 を採用しており、 自律型エージェント(LLM が自律的にツールを選択して実行するエージェント)を主たるユースケースとして定義している点が特徴的 です。
モデル駆動型アプローチは、LLM の性能に積極的に寄りかかることで、 エージェント側のロジックをシンプルに保とうとする姿勢 とも言えます。
Microsoft Agent Framework
最後に、Microsoft Agent Framework の公式ページを見てみましょう。
公式ページ の記載内容を、抜粋して引用します。
Microsoft Agent Framework は、.NET および Python 用の AI エージェントとマルチエージェント ワークフローを構築するためのオープンソース開発キットです。セマンティック カーネルと AutoGen プロジェクトからアイデアをまとめ、拡張し、その長所を組み合わせて新しい機能を追加します。同じチームによって構築され、今後 AI エージェントを構築するための統合された基盤です。
Agent Framework には、次の 2 つの主要なカテゴリの機能が用意されています。
- AI エージェント: LLM を使用してユーザー入力を処理し、ツールと MCP サーバーを呼び出してアクションを実行し、応答を生成する個々のエージェント。エージェントは、Azure OpenAI、OpenAI、Azure AI などのモデル プロバイダーをサポートします。
- ワークフロー: 複数のエージェントと関数を接続して複雑なマルチステップ タスクを実行するグラフ ベースのワークフロー。ワークフローは、人間のループ内シナリオに対して、型ベースのルーティング、入れ子、チェックポイント処理、および要求/応答パターンをサポートします。
また、モデル クライアント(チャットの完了と応答)、状態管理用のエージェント スレッド、エージェント メモリのコンテキスト プロバイダー、エージェント アクションをインターセプトするためのミドルウェア、ツール統合用の MCP クライアントなど、基本的な構成要素も提供します。これらのコンポーネントを組み合わせることで、インタラクティブで堅牢で安全な AI アプリケーションを構築する柔軟性とパワーが得られます。
Microsoft Agent Framework では、設計思想の段階で、 明確に AI エージェントとワークフローが異なる機能として分かれている点が特徴的 です。
自律型エージェントの中には、ワークフロー AI の形で挙動を決定的にするパターンもありますが、そこをきちんと区別しているということですね。
一番後発のフレームワークとして、 AI エージェントの不安定性や、マーケットにおけるワークフロー AI へのニーズを踏まえて設計された思想がベースとなっている ように感じます。
マーケットポジションに即した設計思想が垣間見える
このように 3 つのフレームワークは一見似ているように見えても、その開発タイミングにおける各社のエージェント観や、AI エージェントの課題感を反映したフレームワークになっていると感じます。
Google ADK は最も早く提供されたフレームワークとして機能が充実しており、当社でも多くのプロジェクトで採用しています。
一方、まずはシンプルなエージェントを手早く構築したい場合には Strands を選ぶエンジニアも増えてきており、特に AWS を採用するお客様向けには Strands を使って実装するケースが増えている印象です。
Microsoft Agent Framework はまだ新しいフレームワークですが、ワークフローの実装が容易である点や、AutoGen の GroupChat のようなマルチエージェント構成を扱いやすい点などから、今後の伸びしろを感じています。
もともと Azure を使っているお客様向けに Semantic Kernel などを利用していたエンジニアや、.NET アプリケーションの開発を行うことが多いエンジニアの間で、徐々に注目度が上がっている印象です。
こうした思想的な違いを理解した上で、記法を見ていきましょう。
共通の仕様
ここまではそれぞれの設計思想を見てきましたが、次に、実際の仕様や記法がその設計思想にどう影響を受けているのかを見てみます。
比較する上で、実装するエージェントの仕様を以下のように共通化したいと思います。
機能仕様
- エージェント名:
weather_time_agent - 提供する機能:
-
get_weather(city: str) -> str- 「都市名を渡すと天気を答える」
-
get_current_time(city: str) -> str- 「都市名を渡すと現在時刻を答える」
-
- デモ簡略化のため New York のみサポート とし、それ以外はエラーメッセージを返します。
返り値仕様
-
get_weather("New York")-
"The weather in New York is sunny ..."などの自然文
-
-
get_current_time("New York")-
"The current time in New York is ..."などの自然文
-
エージェントへの指示
「
get_weatherとget_current_timeをうまく使って、ユーザーの質問に答える」
Google ADK での実装
Google ADK は、adk create でプロジェクトを作成し、agent.py に root_agent を定義する構成となります。
root_agent はいわゆるオーケストレーターであり、マルチエージェント構成ではサブエージェントに指示出しをする司令塔的なエージェントとなります。
エージェント実装
今回実装するエージェントを Google ADK で記述すると、以下のようになります。
import datetime
from zoneinfo import ZoneInfo
from google.adk.agents.llm_agent import Agent
def get_weather(city: str) -> str:
"""Return a natural language weather report for the given city.
今回はデモ用なので New York のみ対応。
"""
if city.lower() == "new york":
return (
"The weather in New York is sunny with a temperature of 25°C "
"(77°F)."
)
raise ValueError(f"Weather information for '{city}' is not available.")
def get_current_time(city: str) -> str:
"""Return a natural language string of the current time in the city.
同様に New York のみ対応。
"""
if city.lower() != "new york":
raise ValueError(f"Sorry, I don't have timezone information for {city}.")
tz_identifier = "America/New_York"
tz = ZoneInfo(tz_identifier)
now = datetime.datetime.now(tz)
return (
f"The current time in New York is "
f"{now.strftime('%Y-%m-%d %H:%M:%S %Z%z')}."
)
root_agent = Agent(
model="gemini-2.0-flash-exp", # 実際には利用可能なモデル名に合わせて変更
name="weather_time_agent",
description="Weather & time demo agent implemented with Google ADK.",
instruction=(
"You are a helpful assistant. "
"Use the tools `get_weather` and `get_current_time` to answer "
"questions about New York weather and time. "
"Always respond in Japanese."
),
tools=[get_weather, get_current_time], # Python 関数をそのままツールとして渡す
)
それぞれの tool は Python の関数をそのまま定義するだけでよく、これまで Python で実装してきた方からすると、とてもとっつきやすいと思います。
一方で、model で Gemini 以外の LLM を指定する場合には LiteLLM を使う必要があるなど、Gemini を LLM として使うことを想定した実装になっていると言えます。
実行例
プロジェクトを作成後、親ディレクトリから以下のコマンドを叩くことで実行できます。
adk run / adk web で CLI・Web UI からそのまま試すことができ、フルスタックな開発体験が可能となる点も特徴的です。
他のフレームワークでは別途エージェント用の UI を作らなければならないのに対して、ADK では簡易的な Web アプリケーションをすぐに立ち上げられるため、
エージェントの挙動を確認しながらデバッグしやすくなっています。
export GOOGLE_API_KEY="YOUR_API_KEY" # API キーの指定
adk run my_adk_agent # CLI
# もしくは
adk web --port 8000 # dev UI をブラウザから操作
Strands Agents での実装
Strands Agents は AWS が開発した OSS フレームワークですが、 モデルプロバイダーは Amazon Bedrock / OpenAI / Gemini などを差分なく選べる設計になっています。
エージェントそのものの実装は、Agent(tools=[...]) というシンプルな記法で記述できる実装の簡単さや、モデル駆動を意識した記法が特徴的です。
エージェント実装
Strands Agents で今回のエージェントを実装すると、以下のようになります。
ツールに対しては @tool というデコレーターを使うことで、明示的に各関数がエージェントのツールであることを示します。
import datetime
from zoneinfo import ZoneInfo
from strands import Agent, tool
from strands.models import BedrockModel # デフォルトは Bedrock モデル
@tool
def get_weather(city: str) -> str:
"""Return a natural language weather report for the given city.
Demo implementation that only supports New York.
"""
if city.lower() == "new york":
return (
"The weather in New York is sunny with a temperature of 25°C "
"(77°F)."
)
raise ValueError(f"Weather information for '{city}' is not available.")
@tool
def get_current_time(city: str) -> str:
"""Return a natural language string of the current time in the city.
Demo implementation that only supports New York.
"""
if city.lower() != "new york":
raise ValueError(f"Sorry, I don't have timezone information for {city}.")
tz_identifier = "America/New_York"
tz = ZoneInfo(tz_identifier)
now = datetime.datetime.now(tz)
return (
f"The current time in New York is "
f"{now.strftime('%Y-%m-%d %H:%M:%S %Z%z')}."
)
# モデル設定: ここでは Bedrock から Claude 系モデルを使用
model = BedrockModel(
model_id="us.amazon.nova-pro-v1:0", # 利用可能なモデルを指定
temperature=0.3,
streaming=False,
)
weather_time_agent = Agent(
model=model,
tools=[get_weather, get_current_time],
instructions=(
"You are a helpful assistant. "
"Use the tools `get_weather` and `get_current_time` to answer "
"questions about New York weather and time. "
"Always respond in Japanese."
),
)
実行例
実行は、Python の関数として呼び出す形です。
# run_strands_agent.py
from strands_agent import weather_time_agent
if __name__ == "__main__":
question = "ニューヨークの天気と、今の時刻を教えて。"
answer = weather_time_agent(question)
print(answer)
Microsoft Agent Framework での実装
Microsoft Agent Framework は前述の通り、Semantic Kernel / AutoGen の後継として設計された、.NET & Python 両対応のエージェント & ワークフロー・フレームワークです。
単一エージェントの ChatAgent と、グラフベースの Workflow によるマルチエージェント構成が特徴です。
今回は Workflow の実装は割愛しますが、Workflow による実装では、GroupChat と呼ばれる複数エージェントが協力して課題を解決する、AutoGen の思想を継承したようなエージェント実装が可能な点が特徴的です。
エージェント実装
Microsoft Agent Framework で今回のエージェントを実装すると、以下のようになります。
ツールは @ai_function で型付きに宣言するスタイルを推奨している点など、Strands に近い記法が採用されています。
ここでは OpenAIChatClient を使う Python バージョンで実装します。
import datetime
from zoneinfo import ZoneInfo
from typing import Annotated
from pydantic import Field
from agent_framework import ChatAgent, ai_function
from agent_framework.openai import OpenAIChatClient # OpenAI 用クライアント
# OpenAI 側のモデル ID は環境に合わせて変更
chat_client = OpenAIChatClient(
model_id="gpt-4.1-mini",
)
@ai_function
def get_weather(
city: Annotated[str, Field(description="City name in English, e.g. 'New York'")],
) -> str:
"""Return a natural language weather report for the given city.
Demo implementation that only supports New York.
"""
if city.lower() == "new york":
return (
"The weather in New York is sunny with a temperature of 25°C "
"(77°F)."
)
raise ValueError(f"Weather information for '{city}' is not available.")
@ai_function
def get_current_time(
city: Annotated[str, Field(description="City name in English, e.g. 'New York'")],
) -> str:
"""Return a natural language string of the current time in the city.
Demo implementation that only supports New York.
"""
if city.lower() != "new york":
raise ValueError(f"Sorry, I don't have timezone information for {city}.")
tz_identifier = "America/New_York"
tz = ZoneInfo(tz_identifier)
now = datetime.datetime.now(tz)
return (
f"The current time in New York is "
f"{now.strftime('%Y-%m-%d %H:%M:%S %Z%z')}."
)
# ChatAgent に tools として渡す(@ai_function により schema が自動生成される)
weather_time_agent = ChatAgent(
chat_client=chat_client,
name="weather_time_agent",
instructions=(
"You are a helpful assistant. "
"Use the tools `get_weather` and `get_current_time` to answer "
"questions about New York weather and time. "
"Always respond in Japanese."
),
tools=[get_weather, get_current_time],
)
ツールに Annotated を使うことで、各ツールの役割を明示的に記述できるため、LLM がどのツールをどのように実行すべきかを正確に判断できます。
実行例
実行は以下のように行います。
Microsoft Agent Framework では、agent.run() を非同期で実行する設計となっているため、async / await を使います。
import asyncio
from ms_agent import weather_time_agent
async def main():
question = "ニューヨークの天気と今の時刻を教えて。"
result = await weather_time_agent.run(question)
# AgentRunResponse.text に最終応答が入る
print(result.text)
if __name__ == "__main__":
asyncio.run(main())
記法・抽象化レベルの比較ポイント
ここまでのサンプルコードを踏まえると、ざっくり次の観点で比較すると違いが見えてきます。
ツール定義
-
Google ADK
- Python 関数をそのまま
tools=[funcs...]として渡す。 - 型や docstring はあくまで補助で、schema 生成は暗黙的。
- Python 関数をそのまま
-
Strands Agents
-
@toolデコレータでツールを宣言し、docstring を LLM 向け説明として積極的に使う。 - デコレータで軽くアノテーションを付けるくらいの抽象化レベル。
-
-
Microsoft Agent Framework
-
@ai_function+Annotated[str, Field(...)]による 型付き・スキーマ重視 のスタイル。 - ツール定義がそのまま function calling / tools 定義にマップされるイメージ。
-
今回は同じ get_weather をそれぞれのフレームワークで実装しましたが、
- ADK: 最低限の関数形式で実装し、エージェント側の instruction で緩くツール利用を誘導
- Strands:
@toolと docstring で、ツールの説明を明示 - MS:
@ai_function+Annotated+Fieldで機械可読な schema をきっちり定義
と、だんだん 型安全・明示的 になっていることがわかります。
このあたりは、開発時期によるエージェントのトレンド感や、それぞれの思想が垣間見える点であり、興味深いポイントだと思います。
エージェント構成の抽象度
また抽象度に注目すると、以下のような違いがあることがわかります。
-
Google ADK
-
Agent(...)を書くと、adk run/adk webで CLI / Web UI 両方からすぐ試せる。 - Google Cloud / Gemini / GKE / Cloud Run まで含めたGoogleエコシステム前提の抽象化。
-
-
Strands Agents
-
Agent(model=..., tools=[...])だけでローカル CLI 相当が完成し、モデルは Bedrock / OpenAI / Gemini / Ollama など自由に差し替え可能。 - ランタイムは薄め+モデルは自由の、軽量なSDK。
-
-
Microsoft Agent Framework
- 単一エージェント (
ChatAgent) だけでなく、型安全な Workflow によるマルチエージェントオーケストレーションまで含めたプラットフォーム指向。 - Agent Thread / Middleware / MCP Client などのコンポーネントが最初から整理されており、大規模なワークフロー前提の抽象化。
- 単一エージェント (
前提として記述した通り、どのクラウドベンダーを使うのかによってフレームワークを選ぶことは重要ですが、
それぞれのフレームワークで実装できるエージェントの挙動や抽象度にも差分があることがわかります。
似たフレームワーク群ではありますが、それぞれの思想に合わせて抽象化レイヤーや責務の切り方が異なっており、その違いを理解した上で選択することが重要だと感じます。
まとめ
今回は、シンプルなエージェントを Google ADK / Strands Agents / Microsoft Agent Framework で実装し、その記法・思想の観点から比較してみました。
一見あまり差がないエージェントフレームワークですが、細かい点に違いがあり、それぞれのクラウドベンダーがどのようなエージェント開発をイメージしているのかが垣間見えたように思います。
この記事ではシンプルなエージェントの記法にフォーカスしましたが、マルチエージェント・ワークフロー型エージェントまで視野を広げると、それぞれの個性はさらに際立ってきます。
そのあたりも今後テックブログとして発信できればと思います。
2025 年頭からエージェント開発が本格化し、それぞれのクラウドベンダーがフレームワークを整えてきました。
それぞれのフレームワークやクラウドベンダーのエージェント開発がさらに加熱するなかで、差別化が生まれてくるのか、はたまた差分が小さくなっていくのか。
今後が非常に楽しみな分野だと思いますので、引き続き注目していきたいと思います!
Discussion