Microsoft Agent Framework (C#) 入門 その1「雑感」とハローワールド

に公開

はじめに

入門といいつつ第一回は実は雑感です。
というのも概要や公式的な立ち位置については既に公式 Blog や、日本語でも記事があります。

そのため、ここでは初期のころから Semantic Kernel を追いかけてきている自分の視点で新しいフレームワークがあったほうが良かったんだなということを中心に書いていこうと思います。

Semantic Kernel の今

開発チームは非常に注意深く破壊的変更を起こさないように開発を続けていると思います。
Semantic Kernel は Function calling や Structured output などの LLM の機能がないころから、似たような機能を実現するための仕組みを実装していました。
本当に初期のころは LangChain に影響されたのか関数をチェインするような機能とかもあったりしました(いつの間にか消えたけど)。

そんな機能を実装するために、色々な機能の中心となる Kernel というクラスがあり、昔はそこにかなりの機能を持っていたと思います。
しかし、LLM の機能が充実していくにつれ、現在は DI コンテナの薄いラッパーみたいな感じになっていました。関数の集合のプラグインという概念を持っていたり完全に無駄ではないのですが、ぶっちゃけていうと、それって無くてもどうにかなるよねっていう機能でした。

また、Semantic Kernel は多くの LLM に対応するために LLM のチャットやベクトル化などの抽象化を行うインターフェースを持っていて、それを実装する形で各種 LLM に対応していました。さらには LLM を使ったアプリではよくあるベクトル DB の抽象化も行っていました。この設計は多くのモデルに対応しようとするときには非常によくて、実際に機能をしていました。しかし、.NET では、この Semantic Kernel で得た知見をもとに Microsoft.Extensions.AI という名前で .NET の公式として抽象化レイヤーが提供されました。さらに、Semantic Kernel 自体も Microsoft.Extensions.AI を使うように変更が行われました。

この変更は、破壊的変更を起こさないように行われたため、涙ぐましい努力がコードから垣間見えます。
例えば Chat Completion をベースとした Agent の実装クラスである ChatCompletionAgent では Semantic Kernel に元々ある抽象化レイヤーの IChaCompletionServiceMicrosoft.Extensions.AI の抽象化レイヤーの IChatClient の両方に対応するために IChatCompletionService が DI コンテナに登録されているか確認を行い、されていない場合は IChatClient の取得を試みて IChatClientIChatCOmpletionService に変換して使用するといったことが行われています。

https://github.com/microsoft/semantic-kernel/blob/main/dotnet/src/Agents/Core/ChatCompletionAgent.cs#L266-L277

その他に IChatCompletionService にある関数を自動的に呼び出す機能との互換機能を提供するために IChatClient が元々もっている関数の自動呼出し機能を自前で拡張して KernelFunctionInvokingChatClient というクラスを作成しています。このクラスにも Semantic Kernel 由来の呼出しかどうかを判定して Semantic Kernel 独自のルートに進むのか、元々ある Microsoft.Extensions.AI のルートに進むのかを判定するコードが入っています。

https://github.com/microsoft/semantic-kernel/blob/main/dotnet/src/SemanticKernel.Abstractions/AI/ChatClient/KernelFunctionInvokingChatClient.cs

この機能があるため、何も知らずに普通に IChatClient を DI コンテナに登録して標準の関数の自動呼出し機能を有効化すると Semantic Kernel で使うとちゃんと動かないといった罠もあったりしました。正しく動かすには Semantic Kernel が提供する拡張メソッドを使って DI コンテナに登録する必要があります。

割と所見殺しだと思います。

とまぁ、進化の早い AI の世界で破壊的変更を起こさないように最新の技術を取り入れつつ、さらには Semantic Kernel で提供していた機能も一部 .NET の公式に取り込まれたりと、非常に苦労しているのがコードから垣間見えます。そのため、そろそろ外側は綺麗に見えるけど無理なリフォームを重ねてきた建物のような印象を受けていました。
なので、ここら辺で本当に必要な機能だけを抽出して整理しなおすというのは必要だったんじゃないかなと思います。思いますが、そこら辺の複雑さをなるべく解説しようと個人的に頑張ったりもしていました。

https://zenn.dev/microsoft/articles/semantickernel-edu-009

そうはいっても Semantic Kernel から乗り換えるためのコストもゼロじゃないので、そこはどうなんだろうという気もしています。でも新しいフレームワークが出るとワクワクしますよね!楽しみ!

Agent Framework から受けるイメージ

Semantic Kernel で開発されていた新しめの Agent 機能と Process Framework と呼ばれるワークフローの機能を切り出して整理しなおしたのが Agent Framework というイメージを受けました。もう AI を単に呼ぶだけの機能は Microsoft.Extensions.AI に任せて、Agent としての機能に特化したフレームワークという感じです。

触ってみよう

ということで軽く触ってみましょう。Semantic Kernel を最初に触ってみるときは LLM にプロンプト渡して結果を受け取るといったものが定番だったと思うのですが そこらへんは既に Microsoft.Extensions.AI の領域になっています。さらに Agent Framework は Microsoft.Extensions.AI を使うことを前提にしているので、まずは Microsoft.Extensions.AI を使って LLM にプロンプトを渡してみましょう。コンソールアプリを新規作成して以下のライブラリを追加します。

今回は Azure OpenAI を使うので Azure OpenAI 用のライブラリも追加します。

  • Microsoft.Extensions.AI
  • Microsoft.Extensions.AI.OpenAI (preview)
  • Azure.AI.OpenAI (preview)
  • Azure.Identity

そして以下のコードを実行してみます。非常にシンプルに gpt-5 のモデルを呼ぶものと、ツールの呼出し機能を使うものの 2 つを試してみます。

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

var aoaiClient = new AzureOpenAIClient(
    new("https://<<AOAI のリソース名>>.openai.azure.com/"),
    new DefaultAzureCredential());

var chatClient = aoaiClient.GetChatClient("gpt-5")
    // Microsot.Extnensions.AI の IChatClient に変換
    .AsIChatClient();

// 単純な呼び出し
var response = await chatClient.GetResponseAsync("やっほー!");
Console.WriteLine(response.Text);

Console.WriteLine("===========");

// ツール呼び出しを伴う呼び出し
var functionClient = chatClient.AsBuilder()
    // ツール呼び出しのレスポンスを自動で処理するように設定
    .UseFunctionInvocation()
    .Build();
var response2 = await functionClient.GetResponseAsync("今何時?",
    new()
    {
        ToolMode = ChatToolMode.Auto,
        Tools = [
            AIFunctionFactory.Create(TimeProvider.System.GetUtcNow, description: "現在の UTC の時間を取得します")
        ],
    });
Console.WriteLine(response2.Text);

実行すると以下のような結果になります。

やっほー!元気?何か手伝えることある?
===========
現在のUTC時刻は 2025-10-02 12:25:50 です。
日本時間(JST, UTC+9)では 2025-10-02 21:25:50 です。

別のタイムゾーンの時刻が必要なら教えてください。

ちょっとびっくりしたのですが日本時間を返してくれました。たぶん日本語を使ったので日本だろうと推測してくれたんですかね?賢い。今回はツールの自動呼出し機能くらいしか使っていませんが、他にも OpenTelemetry に対応していたり、プロンプトにキャッシュしていたりといった様々な機能があります。この機能は Agent Framework でも使えます。

IChatClient の動作確認ができたので Agent Framework を使ってみましょう。使うためには以下のパッケージを追加します。

  • Microsoft.Agents.AI (preview)

IChatClient ベースのエージェントを作るには ChatClientAgent クラスを使います。
Agent の定義に必要な指示や必要なツールを与えてエージェントを作成します。以下のコードは猫型アシスタントを作成して、現在の時間を聞くものです。
初回は 1 ターンだけの会話を行い、次にチャット履歴を使った会話を行います。チャット履歴は Agent に定義されている GetNewThread メソッドで取得します。あとは、そのスレッドを持ちまわることで履歴が使われます。

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

var aoaiClient = new AzureOpenAIClient(
    new("https://<<AOAI リソース名>>.openai.azure.com/"),
    new DefaultAzureCredential());

var chatClient = aoaiClient.GetChatClient("gpt-5")
    // Microsot.Extnensions.AI の IChatClient に変換
    .AsIChatClient()
    .AsBuilder()
    // ツール呼び出しを使う
    .UseFunctionInvocation()
    .Build();

// ツールと指示を与えてエージェントを作成
var agent = new ChatClientAgent(
    chatClient,
    instructions: """
        あなたはネコ型アシスタントです。
        猫らしく振舞うために語尾はにゃんにしてください。
        """,
    tools: [
        AIFunctionFactory.Create(TimeProvider.System.GetUtcNow, description: "現在の UTC の時間を取得します"),
    ]);

// Agent を実行して結果を表示
var response = await agent.RunAsync("今何時?");
Console.WriteLine(response.Text);

Console.WriteLine("============");
// チャット履歴を使った会話
var thread = agent.GetNewThread();
var response1 = await agent.RunAsync("私は今シアトルにいます。", thread);
Console.WriteLine(response1.Text);
Console.WriteLine("============");
var response2 = await agent.RunAsync("今何時?", thread);
Console.WriteLine(response2.Text);

実行結果は以下のようになりました。ちゃんと2回目の方ではシアトルの時間を返してくれています。

今のUTC時刻は 2025-10-02 12:48:43 にゃん
参考: 日本時間(JST, UTC+9)だと 2025-10-02 21:48:43 にゃん
お住まいのタイムゾーンを教えてくれたら、その地域の現在時刻もお伝えするにゃん
============
シアトルへようこそにゃん。どんな過ごし方をしたいか教えてほしいにゃん。興味に合わせておすすめを絞るにゃん。

- コーヒー巡りならスターバックス・リザーブ・ロースタリーやElm、Victrola、Caffe Vitaがおすすめにゃん
- パイクプレイス・マーケットで魚の投げ売り、Beecher’sのマック&チーズ、Piroshky Piroshkyを楽しむにゃん
- スペースニードルと隣のチフリー・ガーデン&ガラスで定番観光にゃん
- 眺め重視ならケリーパークやガスワークスパークで写真映えにゃん
- ミュージアムならMoPOP、シアトル美術館、航空好きはミュージアム・オブ・フライトにゃん
- 近場の自然はディスカバリーパークのループトレイルやワシントンパーク樹木園がお手軽にゃん
- フェリーでベインブリッジ島に渡る小旅行も気持ちいいにゃん
- シーフードは生ガキやサーモン、クラムチャウダーが鉄板にゃん(Pike Place ChowderやElliott’sなどにゃん)
- 街歩きはキャピトルヒル、フリーモントのトロール、ボールダードの運河とロックスが楽しいにゃん
- 服装はレイヤーと薄手のレインジャケットが便利にゃん
- 交通はORCAカードでバスやライトレールが楽にゃん(空港からはLinkでダウンタウン直行にゃん)

何日滞在で、コーヒー・自然・美術・グルメ・家族向け・ナイトライフのどれに惹かれるか教えてにゃん。半日や1日のモデルコースも作るにゃん。いまの現地時刻が知りたければ伝えるにゃん。天気や混雑を避けたい時間帯のコツも案内するにゃん。
============
シアトルの現在時刻は午前5時49分ごろ(PDT/UTC-7)にゃん
24時間表記だと05:49にゃん

マルチエージェント機能

Agent Framework にはマルチエージェントの機能があります。
シーケンシャルやハンドオフやグループチャットなどの代表的なパターンが用意されています。面白いのは Agent が複数はいった箱を Agent として扱うことができるということです。これでマルチエージェントの入れ子が簡単にできます。シーケンシャルに動くグループチャットとかが簡単に作れます。これはいいですね。
このワークフロー機能を使うには以下のパッケージを追加します。

  • Microsoft.Agents.AI.Workflows (preview)

そうすると AgentWorkflowBuilder クラスが使えるようになります。これを使って Workflow を定義して実行できます。
実行は現在は InProcessExecution クラスを使った実行ができるみたいですが、その後いろいろな実行方法が提供されるんじゃないかなと思います。


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

var aoaiClient = new AzureOpenAIClient(
    new("https://<<AOAI リソース名>>.openai.azure.com/"),
    new DefaultAzureCredential());

var chatClient = aoaiClient.GetChatClient("gpt-4.1")
    // Microsot.Extnensions.AI の IChatClient に変換
    .AsIChatClient()
    .AsBuilder()
    // ツール呼び出しを使う
    .UseFunctionInvocation()
    .Build();

// 小説のタイトルを考えるエージェント
var titleGeneratorAgent = new ChatClientAgent(
    chatClient,
    instructions: """
        あなたは小説のタイトルを考えるのが得意なAIです。
        ユーザーが小説のジャンルを指定するので、そのジャンルに合った小説のタイトルを1つ考えてください。
        """);
// 小説の最初の一文を考えるエージェント
var firstSentenceGeneratorAgent = new ChatClientAgent(
    chatClient,
    instructions: """
        あなたは小説の最初の一文を考えるのが得意なAIです。
        与えられた小説のタイトルを見て、そのタイトルに合った小説の最初の一文を1つ考えてください。
        """);
// タイトルと最初の一文を markdown 形式にまとめる
var aggregatorAgent = new ChatClientAgent(
    chatClient,
    instructions: """
        あなたは小説のタイトルと最初の一文を markdown 形式にまとめます。

        <出力例>
        # タイトル
        最初の1文。
        <\出力例>
        """);

// 3つのエージェントを順番に実行するワークフローを作成
var sequentialAgent = AgentWorkflowBuilder.BuildSequential(
    titleGeneratorAgent,
    firstSentenceGeneratorAgent,
    aggregatorAgent);

// ワークフローを実行
var streamingRun = await InProcessExecution.StreamAsync(sequentialAgent, "猫が散歩をする日常系");
// TurnToken を送ると Agent が動き始めるらしい
await streamingRun.TrySendMessageAsync(new TurnToken(true));

// 実行結果をストリーミングで受け取る
// WorkflowOutputEvent が最終出力のイベントみたいなので来たら最終結果
WorkflowOutputEvent? outputEvent = null;
await foreach (var evt in streamingRun.WatchStreamAsync())
{
    Console.WriteLine(evt);
    if (evt is WorkflowOutputEvent o)
    {
        outputEvent = o;
    }
}

// 最終結果を表示
if (outputEvent is not null)
{
    Console.WriteLine("=================");
    Console.WriteLine(outputEvent.As<IEnumerable<ChatMessage>>()?.Last().Text);
}

AgentWorkflowBuilder.BuildSequential メソッドでシーケンシャルなワークフローを作成しています。
このワークフローを作るメソッドですが結構高レベルな API です。もうちょっとワークフローのノードを繋げていくような低レベルな API もあるので、別記事とかでやってみようと思います。

実行すると以下のようになります。すごく長いですが、細かくイベントが飛んできている様子が見て取れます。

SuperStepStartedEvent(Step = 0, Data: Microsoft.Agents.AI.Workflows.SuperStepStartInfo = Microsoft.Agents.AI.Workflows.SuperStepStartInfo)
ExecutorInvokedEvent(Executor = 9ac70515551a4c9e94844e5154a765d0, Data: System.String = 猫が散歩をする日常系)
ExecutorCompletedEvent(Executor = 9ac70515551a4c9e94844e5154a765d0)
ExecutorInvokedEvent(Executor = 9ac70515551a4c9e94844e5154a765d0, Data: Microsoft.Agents.AI.Workflows.TurnToken = Microsoft.Agents.AI.Workflows.TurnToken)
AgentRunUpdateEvent(Executor = 9ac70515551a4c9e94844e5154a765d0, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = )
AgentRunUpdateEvent(Executor = 9ac70515551a4c9e94844e5154a765d0, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = )
AgentRunUpdateEvent(Executor = 9ac70515551a4c9e94844e5154a765d0, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 「)
AgentRunUpdateEvent(Executor = 9ac70515551a4c9e94844e5154a765d0, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = ま)
AgentRunUpdateEvent(Executor = 9ac70515551a4c9e94844e5154a765d0, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = い)
AgentRunUpdateEvent(Executor = 9ac70515551a4c9e94844e5154a765d0, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = に)
AgentRunUpdateEvent(Executor = 9ac70515551a4c9e94844e5154a765d0, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = ち)
AgentRunUpdateEvent(Executor = 9ac70515551a4c9e94844e5154a765d0, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 、)
AgentRunUpdateEvent(Executor = 9ac70515551a4c9e94844e5154a765d0, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = ね)
AgentRunUpdateEvent(Executor = 9ac70515551a4c9e94844e5154a765d0, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = こと)
AgentRunUpdateEvent(Executor = 9ac70515551a4c9e94844e5154a765d0, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = お)
AgentRunUpdateEvent(Executor = 9ac70515551a4c9e94844e5154a765d0, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = さん)
AgentRunUpdateEvent(Executor = 9ac70515551a4c9e94844e5154a765d0, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = ぽ)
AgentRunUpdateEvent(Executor = 9ac70515551a4c9e94844e5154a765d0, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 道)
AgentRunUpdateEvent(Executor = 9ac70515551a4c9e94844e5154a765d0, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 」)
AgentRunUpdateEvent(Executor = 9ac70515551a4c9e94844e5154a765d0, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = )
AgentRunUpdateEvent(Executor = 9ac70515551a4c9e94844e5154a765d0, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = )
ExecutorCompletedEvent(Executor = 9ac70515551a4c9e94844e5154a765d0)
SuperStepCompletedEvent(Step = 0, Data: Microsoft.Agents.AI.Workflows.SuperStepCompletionInfo = Microsoft.Agents.AI.Workflows.SuperStepCompletionInfo)
SuperStepStartedEvent(Step = 1, Data: Microsoft.Agents.AI.Workflows.SuperStepStartInfo = Microsoft.Agents.AI.Workflows.SuperStepStartInfo)
ExecutorInvokedEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: System.Collections.Generic.List`1[Microsoft.Extensions.AI.ChatMessage] = System.Collections.Generic.List`1[Microsoft.Extensions.AI.ChatMessage])
ExecutorCompletedEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a)
ExecutorInvokedEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.Workflows.TurnToken = Microsoft.Agents.AI.Workflows.TurnToken)
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = )
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = )
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = ま)
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = っ)
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = す)
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = ぐ)
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = な)
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 朝)
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = の)
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 光)
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = の)
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 中)
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 、)
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 今日)
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = も)
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 小)
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = さ)
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = な)
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 肉)
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 球)
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = の)
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 音)
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = が)
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 僕)
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = の)
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 隣)
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = に)
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 並)
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = ぶ)
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 。)
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = )
AgentRunUpdateEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = )
ExecutorCompletedEvent(Executor = 25f59c5ac49e4a2197d2943a9e84713a)
SuperStepCompletedEvent(Step = 1, Data: Microsoft.Agents.AI.Workflows.SuperStepCompletionInfo = Microsoft.Agents.AI.Workflows.SuperStepCompletionInfo)
SuperStepStartedEvent(Step = 2, Data: Microsoft.Agents.AI.Workflows.SuperStepStartInfo = Microsoft.Agents.AI.Workflows.SuperStepStartInfo)
ExecutorInvokedEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: System.Collections.Generic.List`1[Microsoft.Extensions.AI.ChatMessage] = System.Collections.Generic.List`1[Microsoft.Extensions.AI.ChatMessage])
ExecutorCompletedEvent(Executor = b43b390b3caa49f0a3d40b5feed41440)
ExecutorInvokedEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.Workflows.TurnToken = Microsoft.Agents.AI.Workflows.TurnToken)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = )
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = )
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = #)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate =  )
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = ま)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = い)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = に)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = ち)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 、)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = ね)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = こと)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = お)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = さん)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = ぽ)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 道)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate =
)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = ま)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = っ)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = す)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = ぐ)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = な)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 朝)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = の)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 光)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = の)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 中)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 、)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 今日)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = も)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 小)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = さ)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = な)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 肉)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 球)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = の)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 音)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = が)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 僕)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = の)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 隣)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = に)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 並)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = ぶ)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = 。)
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = )
AgentRunUpdateEvent(Executor = b43b390b3caa49f0a3d40b5feed41440, Data: Microsoft.Agents.AI.AgentRunResponseUpdate = )
ExecutorCompletedEvent(Executor = b43b390b3caa49f0a3d40b5feed41440)
SuperStepCompletedEvent(Step = 2, Data: Microsoft.Agents.AI.Workflows.SuperStepCompletionInfo = Microsoft.Agents.AI.Workflows.SuperStepCompletionInfo)
SuperStepStartedEvent(Step = 3, Data: Microsoft.Agents.AI.Workflows.SuperStepStartInfo = Microsoft.Agents.AI.Workflows.SuperStepStartInfo)
ExecutorInvokedEvent(Executor = OutputMessages, Data: System.Collections.Generic.List`1[Microsoft.Extensions.AI.ChatMessage] = System.Collections.Generic.List`1[Microsoft.Extensions.AI.ChatMessage])
ExecutorCompletedEvent(Executor = OutputMessages)
ExecutorInvokedEvent(Executor = OutputMessages, Data: Microsoft.Agents.AI.Workflows.TurnToken = Microsoft.Agents.AI.Workflows.TurnToken)
WorkflowOutputEvent(Data: System.Collections.Generic.List`1[Microsoft.Extensions.AI.ChatMessage] = System.Collections.Generic.List`1[Microsoft.Extensions.AI.ChatMessage])
ExecutorCompletedEvent(Executor = OutputMessages)
SuperStepCompletedEvent(Step = 3, Data: Microsoft.Agents.AI.Workflows.SuperStepCompletionInfo = Microsoft.Agents.AI.Workflows.SuperStepCompletionInfo)
=================
# まいにち、ねことおさんぽ道
まっすぐな朝の光の中、今日も小さな肉球の音が僕の隣に並ぶ。

最後でちゃんと markdown 形式で出力されていますね。ばっちり。
この他にもワークフローを途中で止めて再開したりといった高度な機能も提供されています。

まとめ

ということで軽く Agent Framework を試してみました。
新規に設計されただけあって、現在の最新の .NET の AI の API っぽく綺麗にまとまっている印象です。
Semantic Kernel は恐らくこれから縮小していって、いずれメンテナンスモードになると思います。(公式発表ではないです)
恐らく今後は Agent Framework を中心として様々な機能が追加されていくんじゃないかなと思います。

ということで、Agent Framework を使ってみました。
次からは、細かい機能をちょっとずつ試してみようと思います。

あ、あと Python も対応しています。私は C# しか書かないので、誰か気になった人で試した人は記事書いて教えてください!

Microsoft (有志)

Discussion