mcpField
W
working-with-ms-agent-framework

working-with-ms-agent-framework

github.com/mhagreliusエージェントワークフロー42 回インストール
リポジトリ

working-with-ms-agent-framework について

Microsoft Agent Framework でエージェントを構築するためのリファレンススキルです。状態管理、コンテキストプロバイダー、オーケストレーション、永続化、DevUI と、Semantic Kernel または AutoGen からの移行を扱います。

主な機能

  1. 01エージェントとスレッドの構成
  2. 02ポリシーに基づくコンテキストとメモリー
  3. 035 種類のオーケストレーションパターン
  4. 04スレッドのシリアライズとワークフローのチェックポイント
  5. 05DevUI の設定とトレース
  6. 06Semantic Kernel と AutoGen からの移行

活用シーン

  1. 01マルチエージェントワークフローの設計
  2. 02エージェントの会話の保存と再開
  3. 03ポリシーに基づくコンテキストの追加
  4. 04Semantic Kernel または AutoGen を使うプロジェクトの移行

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mhagrelius/dotfiles --skill working-with-ms-agent-framework

インストール後、Claude Code で/working-with-ms-agent-frameworkを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

context-providers.md
design-patterns.md
orchestration-patterns.md

詳細

Microsoft Agent Framework の使用

Microsoft Agent Framework(2025 年 10 月)は、Semantic Kernel と AutoGen を 1 つの SDK に統合します。どちらのレガシーフレームワークもメンテナンスモードです。

基本原則: エージェントはステートレスです。すべての状態はスレッドに保存されます。コンテキストプロバイダーは、何を、どのように、いつプロンプトに含めるか、またそれがどのように減衰するかについてのポリシーを適用します。

このスキルに含まれる追加の参考ファイル:

  • context-providers.md - ポリシーベースのメモリ、カプセルパターン、Mem0 統合
  • orchestration-patterns.md - 5 つのオーケストレーションパターンと使用場面のガイダンス
  • design-patterns.md - 本番環境向けパターン、テスト、移行

使用する場面

  • Microsoft の統合フレームワークで AI エージェントを構築する場合
  • Context Providers でカスタムメモリを実装する場合
  • チェックポイント機能を備えたマルチエージェントのワークフローを作成する場合
  • Semantic Kernel または AutoGen から移行する場合

使用しない場面

  • 単純な単一ターンの LLM 呼び出し(チャットクライアントを直接使用してください)
  • レガシーの SK/AutoGen を使い続けるプロジェクト
  • Microsoft 以外のフレームワーク(LangChain、CrewAI)

テクノロジースタックの階層

公式ガイダンス(PM、Jeremy Licknes): ME AI から始め、必要な場合にのみ上位へ移行します。

レイヤー用途上位へ移行するタイミング
ME AI(Microsoft.Extensions.AI)チャットクライアント、構造化出力、埋め込み、ミドルウェアエージェント、ワークフロー、メモリが必要な場合
Agent Frameworkエージェント、スレッド、オーケストレーション、コンテキストプロバイダー特定の SK アダプターが必要な場合
Semantic KernelME AI にない特定のアダプター、ユーティリティここから始めないでください
ME AI (foundation) → Agent Framework (agents/workflows) → SK (specific utilities only)

重要なポイント: ME AI は、OpenAI、Ollama、Foundry Local などで動作する汎用 API を提供します。Agent Framework は ME AI を基盤として、エージェントパターンを構築します。SK のプリミティブは ME AI に移行済みです。SK は、まだ ME AI にない特定のアダプターに限って使用してください。

ME AI で自動的に利用できる機能:

  • 構造化出力(拡張メソッドによる型付き応答)
  • ミドルウェア(OpenTelemetry、チャットの削減)
  • 汎用チャットクライアントの抽象化
  • 埋め込みの生成

アーキテクチャのクイックリファレンス

概念C# の型目的
エージェントAIAgentステートレスな LLM ラッパー
スレッドAgentThread状態を保持する会話コンテナー
コンテキストプロバイダーAIContextBehaviorポリシーベースのメモリ/コンテキスト注入
オーケストレーションSequentialOrchestration などマルチエージェントの調整

インストール

dotnet add package Microsoft.Agents.AI.OpenAI --prerelease
dotnet add package Azure.AI.OpenAI --version 2.1.0

エージェントの作成

using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;

// Azure OpenAI
AIAgent agent = new AzureOpenAIClient(
    new Uri("https://<resource>.openai.azure.com"),
    new AzureCliCredential())
        .GetChatClient("gpt-4o-mini")
        .CreateAIAgent(
            instructions: "You are a helpful assistant.",
            name: "Assistant");

// Direct OpenAI
var agent = new OpenAIClient("api-key")
    .GetChatClient("gpt-4o-mini")
    .AsIChatClient()
    .CreateAIAgent(instructions: "...", name: "Assistant");

// With tools
[Description("Gets weather for a location")]
static string GetWeather(string location) => $"Sunny in {location}";

AIAgent agent = chatClient.CreateAIAgent(
    instructions: "You help with weather queries.",
    tools: [AIFunctionFactory.Create(GetWeather)]
);

実行

// Simple
Console.WriteLine(await agent.RunAsync("Hello!"));

// With thread for multi-turn
AgentThread thread = agent.GetNewThread();
await agent.RunAsync("My name is Alice.", thread);
await agent.RunAsync("What's my name?", thread); // Remembers "Alice"

// Streaming
await foreach (var update in agent.RunStreamingAsync("Tell me a story.", thread))
{
    Console.Write(update.Text);
}

回復性を備えたストリーミング

本番環境のストリーミングでは、キャンセルのサポートと回復性を追加してください。

// Basic streaming with cancellation
await foreach (var update in agent.RunStreamingAsync("Tell me a story.", thread)
    .WithCancellation(cancellationToken))
{
    Console.Write(update.Text);
}

// With Polly resilience pipeline
var pipeline = new ResiliencePipelineBuilder()
    .AddRetry(new RetryStrategyOptions { MaxRetryAttempts = 3 })
    .AddTimeout(TimeSpan.FromMinutes(2))
    .Build();

await pipeline.ExecuteAsync(async token =>
{
    await foreach (var chunk in agent.RunStreamingAsync(userMessage, thread)
        .WithCancellation(token))
    {
        Console.Write(chunk.Text);
    }
}, cancellationToken);

エラーの区別:

  • OperationCanceledException:ユーザーによるキャンセル
  • TimeoutRejectedException:Polly のタイムアウト
  • HttpRequestException:ネットワークの問題

開発用 UI(DevUI)

エージェントとワークフローのテスト用の軽量なウェブインターフェイスです。開発専用であり、本番環境では使用しないでください。

Python のセットアップ

インストール:

pip install agent-framework-devui --pre

方法 1:プログラムによる登録

from agent_framework import ChatAgent
from agent_framework.openai import OpenAIChatClient
from agent_framework.devui import serve

agent = ChatAgent(
    name="WeatherAgent",
    chat_client=OpenAIChatClient(),
    tools=[get_weather]
)

# Launch DevUI with tracing
serve(entities=[agent], auto_open=True, tracing_enabled=True)
# Opens browser to http://localhost:8080

方法 2:ディレクトリの検出(CLI)

devui ./entities --port 8080 --tracing

検出用のディレクトリ構造:

entities/
    weather_agent/
        __init__.py      # Must export: agent = ChatAgent(...)
        .env             # Optional: API keys
    my_workflow/
        __init__.py      # Must export: workflow = WorkflowBuilder()...
C# のセットアップ

C# では、DevUI を SDK コンポーネントとして組み込みます(ドキュメントは作成中です)。

var app = builder.Build();

app.MapOpenAIResponses();
app.MapConversation();

if (app.Environment.IsDevelopment())
{
    app.MapAgentUI(); // Accessible at /ui
}
機能
機能説明
ウェブインターフェイスエージェント/ワークフローの対話型テスト
OpenAI 互換 APIローカルエージェントに対して OpenAI SDK を使用
トレースデバッグパネル内の OpenTelemetry スパン
ファイルのアップロードマルチモーダル入力(画像、ドキュメント)
入力の自動生成最初のエグゼキューターの型に基づくワークフロー入力
DevUI でのトレース

--tracing フラグまたは tracing_enabled=True で有効にします。デバッグパネルで確認できます。

Agent Execution
├── LLM Call (prompt → response)
├── Tool Call
│   ├── Tool Execution
│   └── Tool Result
└── LLM Call (prompt → response)

外部ツール(Jaeger、Azure Monitor)にエクスポートします。

export OTLP_ENDPOINT="http://localhost:4317"
devui ./entities --tracing
OpenAI SDK との統合

OpenAI Python SDK を介して DevUI のエージェントとやり取りします。

from openai import OpenAI

client = OpenAI(base_url="http://localhost:8080/v1", api_key="not-needed")
response = client.responses.create(
    metadata={"entity_id": "weather_agent"},
    input="What's the weather in Seattle?"
)
CLI オプション
devui [directory] [options]
  --port, -p      Port (default: 8080)
  --tracing       Enable OpenTelemetry tracing
  --reload        Auto-reload on file changes
  --headless      API only, no UI
  --mode          developer|user (default: developer)

スレッドのシリアル化(重要なパターン)

// Serialize for persistence
JsonElement serialized = await thread.SerializeAsync();
await File.WriteAllTextAsync("thread.json", serialized.GetRawText());

// Later: restore and resume
string json = await File.ReadAllTextAsync("thread.json");
JsonElement element = JsonSerializer.Deserialize<JsonElement>(json);
AgentThread restored = agent.DeserializeThread(element, JsonSerializerOptions.Web);
await agent.RunAsync("Continue...", restored);

主な動作:

  • サービス管理のスレッド:シリアル化されるのはスレッド ID のみです
  • メモリ内のスレッド:すべてのメッセージがシリアル化されます
  • 警告:異なるエージェント構成でデシリアル化するとエラーが発生する場合があります

コンテキストプロバイダー(ポリシーベースのメモリ)

コンテキストプロバイダーは「メモリの注入」ではなく、ポリシーの適用です。

ポリシー決定する内容
選択何をメモリにするか
ゲーティングいつ取得するか
減衰いつ期限切れにするか
ノイズ回避いつ使用しないか
ChatHistoryAgentThread thread = new();

// Long-term user memory
thread.AIContextProviders.Add(new Mem0Provider(httpClient, new() { UserId = "user123" }));

// Short-term conversation context
thread.AIContextProviders.Add(new WhiteboardProvider(chatClient));

// RAG integration
thread.AIContextProviders.Add(new TextSearchProvider(textSearch, new()
{
    SearchTime = TextSearchProviderOptions.RagBehavior.OnDemandFunctionCalling
}));

カスタム実装パターンについては、context-providers.md を参照してください。

オーケストレーションパターン

パターン使用する状況
順次明確な依存関係がある場合(下書き → レビュー → 推敲)
並行独立した視点、アンサンブル推論
ハンドオフ最適なエージェントが事前に不明な場合、動的な専門知識が必要な場合
GroupChat協調的なアイデア出し、ヒューマン・イン・ザ・ループ
Magentic複雑で自由度の高い問題
// Sequential
SequentialOrchestration orchestration = new(analystAgent, writerAgent);

// Handoff - CRITICAL: Always set termination conditions!
var workflow = AgentWorkflowBuilder.StartHandoffWith(triageAgent)
    .WithHandoffs(triageAgent, [mathTutor, historyTutor])
    .WithHandoff(mathTutor, triageAgent)      // Allows routing back
    .WithHandoff(historyTutor, triageAgent)
    .WithMaxHandoffs(10)                      // REQUIRED: Prevent infinite loops
    .Build();

// Execute
InProcessRuntime runtime = new();
await runtime.StartAsync();
var result = await orchestration.InvokeAsync(task, runtime);

ハンドオフで重要な点:.WithMaxHandoffs() がないと、無限ループが発生します。必ず終了条件を設定してください。

詳細なパターンと用途のガイダンスについては、orchestration-patterns.md を参照してください。

ワークフローのチェックポイントと耐久性

プロセスの再起動後も継続する必要があるワークフローの場合:

// Basic checkpointing with CheckpointManager
var checkpointManager = CheckpointManager.Default;

await using Checkpointed<StreamingRun> checkpointedRun =
    await InProcessExecution.StreamAsync(workflow, input, checkpointManager);

// Resume from checkpoint
await InProcessExecution.ResumeStreamAsync(savedCheckpoint, checkpointManager);
スレッドベースの永続化パターン

長時間実行されるワークフローでは、各ステップの後にスレッドの状態をチェックポイントとして保存します。

// Save thread state after each workflow step
var serialized = await thread.SerializeAsync();
await checkpointStore.SaveAsync(workflowId, currentStep, serialized.GetRawText());

// Resume after restart
var json = await checkpointStore.GetAsync(workflowId);
var element = JsonSerializer.Deserialize<JsonElement>(json);
var restored = agent.DeserializeThread(element, JsonSerializerOptions.Web);
await agent.RunAsync(nextStep, restored);
起動時の復旧
public class WorkflowRecoveryService : BackgroundService
{
    private readonly ICheckpointStore _store;
    private readonly AIAgent _agent;

    protected override async Task ExecuteAsync(CancellationToken ct)
    {
        var pending = await _store.GetPendingWorkflowsAsync();
        foreach (var workflow in pending)
        {
            var thread = _agent.DeserializeThread(workflow.State, JsonSerializerOptions.Web);
            await _agent.RunAsync(workflow.NextStep, thread, cancellationToken: ct);
        }
    }
}

重要な原則:各ステップの完了後にチェックポイントを保存し、完了前には保存しません。これにより、最後に成功したステップから再開できます。

移行のクイックリファレンス

Semantic Kernel からの移行
SKAgent Framework
KernelAIAgent
ChatHistoryAgentThread
[KernelFunction]メソッドに付ける [Description]
IPromptFilterAIContextBehavior
KernelFunctionFactory.CreateFromMethodAIFunctionFactory.Create
AutoGen からの移行
AutoGenAgent Framework
AssistantAgentCreateAIAgent() を介した AIAgent
FunctionToolAIFunctionFactory.Create()
GroupChat/TeamsWorkflowBuilder パターン
TopicSubscriptionAgentWorkflowBuilder.WithHandoffs()
BaseAgent, IHandle<>ツールを備えた AIAgent

トピックベースからハンドオフへの移行:

// ❌ OLD AutoGen pattern (deprecated)
[TopicSubscription("queries")]
public class MyAgent : BaseAgent, IHandle<Query>
{
    public async Task Handle(Query msg, CancellationToken ct)
    {
        // Process and publish to another topic
        await PublishMessageAsync(new Response(...), "responses");
    }
}

// ✅ NEW Agent Framework pattern
var triageAgent = chatClient.CreateAIAgent(
    instructions: "Route queries to appropriate specialist.",
    name: "Triage");

var mathAgent = chatClient.CreateAIAgent(
    instructions: "Handle math queries.",
    name: "Math");

var workflow = AgentWorkflowBuilder.StartHandoffWith(triageAgent)
    .WithHandoffs(triageAgent, [mathAgent, otherAgent])
    .WithMaxHandoffs(10)  // REQUIRED
    .Build();

await workflow.InvokeStreamingAsync(input, runtime);

アンチパターン

しないことすること
エージェントインスタンスに状態を保存するすべての状態に AgentThread を使用する
メッセージのみをシリアル化するスレッド全体をシリアル化する
ワークフロー内でエージェントインスタンスを共有するファクトリーパターンを使用する
サービス間で異なる種類のスレッドを混在させるスレッドはサービス固有です
順次パターンで十分な場合に Magentic を使用する機能する最もシンプルなパターンを使用する
ContextualFunctionProvider で UseImmutableKernel を省略する常に UseImmutableKernel = true を設定する
新規プロジェクトで Semantic Kernel から始めるME AI から始め、必要に応じて Agent Framework に移行する

危険信号 — 中止してください

  • AIAgent の代わりに Kernel を使用している(旧 SK)
  • AIAgent の代わりに AssistantAgent を使用している(旧 AutoGen)
  • スレッドのデシリアル化に失敗する(コンテキストプロバイダーにシリアル化コンストラクターがない)
  • セッション間でメモリが失われる(スレッドではなくメッセージをシリアル化している)
  • ハンドオフが無限ループする(終了条件が必要)

既知の制限事項

  • 分散ランタイム:プロセス内のみ。分散実行は予定されています
  • C# Magentic:ほとんどの例は Python です
  • C# メッセージストア:Redis/データベースにはカスタム実装が必要です
  • トークン数のカウント:プロバイダーでの予算計算は文書化されていません
  • DevUI の C# ドキュメント:Python には完全なドキュメントがあります。C# DevUI のドキュメントは「近日公開予定」です(組み込み SDK のアプローチは異なります)
  • GA の時期:Agent Framework の安定版リリースは「近日公開予定」です(2025 年 1 月時点)

リソース

  • GitHub:github.com/microsoft/agent-framework
  • ドキュメント:learn.microsoft.com/en-us/agent-framework/
  • 移行ガイド:learn.microsoft.com/en-us/agent-framework/migration-guide/

コメント