ai-agents-for-beginners

Microsoft Agent Frameworkの探求

Agent Framework

はじめに

このレッスンでは以下について説明します:

学習目標

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

コードサンプル

Microsoft Agent Framework (MAF) のコードサンプルは、このリポジトリの xx-python-agent-frameworkxx-dotnet-agent-framework ファイルで見つけることができます。

Microsoft Agent Frameworkの理解

Framework Intro

Microsoft Agent Framework (MAF) は、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 の ResponsesChatCompletion 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.", )

または大きなコンテキストウィンドウ(最大204Kトークン)を備えたOpenAI互換APIを提供する MiniMax

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エージェントまたはカスタムロジックのいずれかです。

エッジ

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

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

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スタイルのエンドポイント、または非会話型処理が必要な場合。

Foundryにおけるエージェント開発の主なAPIはResponses 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. LangGraphエージェントをResponsesプロトコルで公開する:

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-frameworkxx-dotnet-agent-frameworkのファイルで見つけられます。

Microsoft Agent Frameworkについてさらに質問がありますか?

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

前のレッスン

AIエージェントのメモリ

次のレッスン

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


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