ai-agents-for-beginners

Microsoft Agent Framework を探る

Agent Framework

はじめに

このレッスンで扱う内容:

学習目標

このレッスンを終えると、次のことができるようになります:

コードサンプル

Microsoft Agent Framework (MAF) のコードサンプルは、このリポジトリ内の xx-python-agent-framework および xx-dotnet-agent-framework ファイルにあります。

Microsoft Agent Framework の理解

Framework Intro

Microsoft Agent Framework (MAF) は、Microsoft の統一された AI エージェント構築フレームワークです。これは、製品および研究環境で見られる多様なエージェントユースケースに対応する柔軟性を提供します。例えば:

本番環境で AI エージェントを提供するために、MAF には以下の機能も含まれています:

Microsoft Agent Framework はまた、相互運用性に注力しています:

これらの機能が Microsoft Agent Framework のコア概念のいくつかにどのように適用されているか見てみましょう。

Microsoft Agent Framework の主要な概念

エージェント

Agent Framework

エージェントの作成

エージェントの作成は、推論サービス(LLM プロバイダー)、AI エージェントが従う指示セット、および割り当てられた name を定義して行います:

agent = AzureOpenAIChatClient(credential=AzureCliCredential()).create_agent( instructions="You are good at recommending trips to customers based on their preferences.", name="TripRecommender" )

上記は Azure OpenAI を使用していますが、エージェントは Microsoft Foundry Agent Service を含む様々なサービスを用いて作成可能です:

AzureAIAgentClient(async_credential=credential).create_agent( name="HelperAgent", instructions="You are a helpful assistant." ) as agent

OpenAI の Responses、ChatCompletion API

agent = OpenAIResponsesClient().create_agent( name="WeatherBot", instructions="You are a helpful weather assistant.", )
agent = OpenAIChatClient().create_agent( name="HelpfulAssistant", instructions="You are a helpful assistant.", )

また、MiniMax のように大きなコンテキストウィンドウ(最大204Kトークン)を備えた OpenAI 互換 API もあります:

agent = OpenAIChatClient(base_url="https://api.minimax.io/v1", api_key=os.environ["MINIMAX_API_KEY"], model_id="MiniMax-M3").create_agent( name="HelpfulAssistant", instructions="You are a helpful assistant.", )

また、A2A プロトコルを使ったリモートエージェントもあります:

agent = A2AAgent( name=agent_card.name, description=agent_card.description, agent_card=agent_card, url="https://your-a2a-agent-host" )

エージェントの実行

エージェントは、非ストリーミング応答用に .run、ストリーミング応答用に .run_stream メソッドを使って実行されます。

result = await agent.run("What are good places to visit in Amsterdam?")
print(result.text)
async for update in agent.run_stream("What are the good places to visit in Amsterdam?"):
    if update.text:
        print(update.text, end="", flush=True)

各エージェント実行には、エージェントが使用する max_tokens、呼び出せる tools、および使用する model などのカスタムパラメーターをオプションで指定できます。

これは、ユーザーのタスクを完遂するために特定のモデルやツールが必要な場合に便利です。

ツール

ツールは、エージェントの定義時に:

def get_attractions( location: Annotated[str, Field(description="The location to get the top tourist attractions for")], ) -> str: """Get the top tourist attractions for a given location.""" return f"The top attractions for {location} are." 


# ChatAgentを直接作成する場合

agent = ChatAgent( chat_client=OpenAIChatClient(), instructions="You are a helpful assistant", tools=[get_attractions]

また、エージェント実行時にも定義できます:


result1 = await agent.run( "What's the best place to visit in Seattle?", tools=[get_attractions] # この実行のためだけに提供されたツール)

エージェントスレッド

エージェントスレッドはマルチターン対話を扱うために使われます。スレッドは以下のいずれかで作成可能です:

スレッドを作成するコードは次の通りです:

# 新しいスレッドを作成します。
thread = agent.get_new_thread() # スレッドでエージェントを実行します。
response = await agent.run("Hello, I am here to help you book travel. Where would you like to go?", thread=thread)

その後、スレッドを保存用にシリアライズできます:

# 新しいスレッドを作成します。
thread = agent.get_new_thread() 

# スレッドでエージェントを実行します。

response = await agent.run("Hello, how are you?", thread=thread) 

# ストレージ用にスレッドをシリアライズします。

serialized_thread = await thread.serialize() 

# ストレージから読み込んだ後、スレッドの状態をデシリアライズします。

resumed_thread = await agent.deserialize_thread(serialized_thread)

エージェントミドルウェア

エージェントは、ユーザーのタスクを完了するためにツールや LLM と連携します。特定のシナリオでは、これらのインタラクションの間に処理や追跡を実行したい場合があります。エージェントミドルウェアはこれを可能にします:

関数ミドルウェア

このミドルウェアは、エージェントと呼び出す関数/ツールの間でアクションを実行できるようにします。例としては、関数呼び出し時のログ記録があります。

以下のコードで next は次のミドルウェアか実際の関数を呼ぶかを定義します。

async def logging_function_middleware(
    context: FunctionInvocationContext,
    next: Callable[[FunctionInvocationContext], Awaitable[None]],
) -> None:
    """Function middleware that logs function execution."""
    # 前処理:関数実行前のログ
    print(f"[Function] Calling {context.function.name}")

    # 次のミドルウェアまたは関数の実行へ続行
    await next(context)

    # 後処理:関数実行後のログ
    print(f"[Function] {context.function.name} completed")

チャットミドルウェア

このミドルウェアは、エージェントと LLM の間のリクエストでアクションを実行またはログ記録します。

ここには AI サービスに送られる messages のような重要な情報が含まれます。

async def logging_chat_middleware(
    context: ChatContext,
    next: Callable[[ChatContext], Awaitable[None]],
) -> None:
    """Chat middleware that logs AI interactions."""
    # 前処理: AI呼び出し前のログ
    print(f"[Chat] Sending {len(context.messages)} messages to AI")

    # 次のミドルウェアまたはAIサービスへ継続
    await next(context)

    # 後処理: AI応答後のログ
    print("[Chat] AI response received")

エージェントメモリ

Agentic Memory レッスンで扱ったように、メモリはエージェントが異なるコンテキストで動作するための重要な要素です。MAF はいくつかの異なるメモリタイプを提供します:

インメモリストレージ

これは、アプリケーション実行時のスレッド内に保存されるメモリです。

# 新しいスレッドを作成します。
thread = agent.get_new_thread() # スレッドでエージェントを実行します。
response = await agent.run("Hello, I am here to help you book travel. Where would you like to go?", thread=thread)

永続メッセージ

これは異なるセッション間の会話履歴保存に使われます。chat_message_store_factory を使用して定義します:

from agent_framework import ChatMessageStore

# カスタムメッセージストアを作成する
def create_message_store():
    return ChatMessageStore()

agent = ChatAgent(
    chat_client=OpenAIChatClient(),
    instructions="You are a Travel assistant.",
    chat_message_store_factory=create_message_store
)

動的メモリ

このメモリはエージェントが実行される前にコンテキストに追加されます。これらのメモリは mem0 のような外部サービスに保存できます。

from agent_framework.mem0 import Mem0Provider

# 高度なメモリ機能のためにMem0を使用する
memory_provider = Mem0Provider(
    api_key="your-mem0-api-key",
    user_id="user_123",
    application_id="my_app"
)

agent = ChatAgent(
    chat_client=OpenAIChatClient(),
    instructions="You are a helpful assistant with memory.",
    context_providers=memory_provider
)

エージェントの可観測性

可観測性は信頼性が高く維持可能なエージェントシステムを構築する上で重要です。MAF は OpenTelemetry と統合し、より良い可観測性のためにトレースやメーターを提供します。

from agent_framework.observability import get_tracer, get_meter

tracer = get_tracer()
meter = get_meter()
with tracer.start_as_current_span("my_custom_span"):
    # 何かをする
    pass
counter = meter.create_counter("my_custom_counter")
counter.add(1, {"key": "value"})

ワークフロー

MAF はタスク完了のための事前定義済みステップであるワークフローを提供し、これらのステップのコンポーネントとして AI エージェントを含みます。

ワークフローはより良い制御フローを可能にする異なるコンポーネントで構成されています。ワークフローは マルチエージェントのオーケストレーション と チェックポイント を可能にしてワークフローの状態を保存します。

ワークフローのコアコンポーネントは以下の通りです:

エグゼキュータ

エグゼキュータは入力メッセージを受け取り、割り当てられたタスクを実行し、その後出力メッセージを生成します。これによりワークフローが前進し、より大きなタスクの完了に向かいます。エグゼキュータは AI エージェントまたはカスタムロジックのいずれかです。

エッジ

エッジはワークフロー内のメッセージの流れを定義するために使われます。これらは以下のようなものがあります:

ダイレクトエッジ - エグゼキュータ間の単純な1対1の接続:

from agent_framework import WorkflowBuilder

builder = WorkflowBuilder()
builder.add_edge(source_executor, target_executor)
builder.set_start_executor(source_executor)
workflow = builder.build()

条件付きエッジ - ある条件が満たされた後に起動される。例えば、ホテルの部屋が利用できない場合、エグゼキュータは他の選択肢を提案できます。

スイッチケースエッジ - 定義済みの条件に基づいてメッセージを異なるエグゼキュータにルーティングします。例えば、旅行者が優先アクセスを持っている場合、そのタスクは別のワークフローを通じて処理されます。

ファンアウトエッジ - 1つのメッセージを複数のターゲットに送信します。

ファンインエッジ - 複数のエグゼキュータからのメッセージを収集し、1つのターゲットに送信します。

イベント

ワークフローの可観測性を高めるために、MAF は以下のような実行イベントを組み込みで提供します:

高度な MAF パターン

上記のセクションでは Microsoft Agent Framework の主要な概念をカバーしています。より複雑なエージェントを構築する際に検討すべき高度なパターンをいくつか紹介します:

Microsoft Foundryでの LangChain / LangGraph エージェントのホスティング

Microsoft Agent Framework は フレームワーク互換性があり、MAF で書かれたエージェントに限定されません。既に LangChain または LangGraph で構築されたエージェントがあれば、それを Microsoft Foundry ホストエージェント として実行可能で、Foundry がランタイム、セッション、スケーリング、ID、およびプロトコルエンドポイントを管理し、エージェントロジックは LangGraph に保持されます。

これは langchain_azure_ai.agents.hosting パッケージを使って実現されており、Foundry ホストエージェントが使用する同じプロトコル上でコンパイルされた LangGraph グラフを公開します。

1. ホスティングの追加インストール:

pip install -U "langchain-azure-ai[hosting]>=1.2.4" azure-identity

hosting エクストラは Foundry のプロトコルライブラリをインストールします:azure-ai-agentserver-responses(OpenAI 互換の /responses エンドポイント)と azure-ai-agentserver-invocations(汎用の /invocations エンドポイント)。

2. ホスティングプロトコルを選択:

プロトコル ホストクラス エンドポイント 使用シーン
Responses ResponsesHostServer /responses OpenAI 互換のチャット、ストリーミング、レスポンス履歴、会話スレッドを使いたい場合 — 会話型エージェントの推奨デフォルト。
Invocations InvocationsHostServer /invocations 独自の JSON 形式、Webhook スタイルのエンドポイント、非会話型処理が必要な場合。

Responses API は Foundry でのエージェント開発の主要 API なので、ほとんどのエージェントは ResponsesHostServer から始めることを推奨します。

3. 環境変数を設定(事前に az login を行い DefaultAzureCredential の認証を可能にします):

export FOUNDRY_PROJECT_ENDPOINT="https://<resource>.services.ai.azure.com/api/projects/<project>"
export FOUNDRY_MODEL_NAME="gpt-5-mini"

エージェントが後で Foundry のホストエージェントとして実行される際は、プラットフォームが自動的に FOUNDRY_PROJECT_ENDPOINT を注入します。

4. Responses プロトコルで LangGraph エージェントを公開:

import os

from azure.ai.projects import AIProjectClient
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
from langchain.agents import create_agent
from langchain_openai import ChatOpenAI
from langchain_azure_ai.agents.hosting import ResponsesHostServer

_AZURE_AI_SCOPE = "https://ai.azure.com/.default"


def build_chat_model() -> ChatOpenAI:
    project_endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"].rstrip("/")
    deployment = os.environ.get("FOUNDRY_MODEL_NAME", "gpt-5-mini")
    credential = DefaultAzureCredential()
    project = AIProjectClient(endpoint=project_endpoint, credential=credential)
    openai_client = project.get_openai_client()
    token_provider = get_bearer_token_provider(credential, _AZURE_AI_SCOPE)

    # ChatOpenAIはFoundryプロジェクトのOpenAI互換(Responses)エンドポイントを対象としています。
    return ChatOpenAI(
        model=deployment,
        base_url=str(openai_client.base_url),
        api_key=token_provider,
    )


def main() -> None:
    graph = create_agent(build_chat_model(), tools=[])
    port = int(os.environ.get("PORT", "8088"))
    ResponsesHostServer(graph).run(port=port)


if __name__ == "__main__":
    main()

ローカルで python main.py を実行し、http://localhost:8088/responses に Responses リクエストを送信します。

主な挙動:

この例の実行可能なバージョンは code-samples/14-langchain-hosted-agent.py にあります。完全なチュートリアル(Invocations プロトコル、カスタムリクエストスキーマ、トラブルシューティング)は Host LangGraph agents as Foundry hosted agents を参照してください。

コードサンプル

Microsoft Agent Framework のコードサンプルはこのリポジトリの xx-python-agent-framework と xx-dotnet-agent-framework ファイルにあります。

Microsoft Agent Framework に関する質問は?

他の学習者と会い、オフィスアワーに参加し、AI エージェントの質問に答えてもらうには Microsoft Foundry Discord に参加しましょう。

前のレッスン

AI エージェントのメモリ

次のレッスン

コンピューター使用エージェント (CUA) の構築


免責事項: 本書類は AI 翻訳サービス Co-op Translator を使用して翻訳されています。正確性を期していますが、自動翻訳には誤りや不正確な部分が含まれる可能性があることをご承知おきください。原文の原語版が正式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。本翻訳の利用により生じたいかなる誤解や解釈違いについても、当方は責任を負いかねます。