ワークフロー イベント システムは、ワークフローの実行に可観測性を提供します。 イベントは実行中の重要なポイントで生成され、ストリーミングを介してリアルタイムで使用できます。
組み込みのイベントの種類
// Workflow lifecycle events
WorkflowStartedEvent // Workflow execution begins
WorkflowOutputEvent // Workflow outputs data
WorkflowErrorEvent // Workflow encounters an error
WorkflowWarningEvent // Workflow encountered a warning
// Executor events
ExecutorInvokedEvent // Executor starts processing
ExecutorCompletedEvent // Executor finishes processing
ExecutorFailedEvent // Executor encounters an error
AgentResponseEvent // An agent run produces output
AgentResponseUpdateEvent // An agent run produces a streaming update
// Superstep events
SuperStepStartedEvent // Superstep begins
SuperStepCompletedEvent // Superstep completes
// Request events
RequestInfoEvent // A request is issued
Note
エージェントが承認が必要なツールを使用する場合、 RequestInfoEvent は通常、人間の承認を必要とするツール呼び出しに対して ToolApprovalRequestContent ペイロードを持ちます。 これらのイベントの処理の詳細については、 Human-in-the-Loop を参照してください。
# All events use the unified WorkflowEvent class with a type discriminator:
# Workflow lifecycle events
WorkflowEvent.type == "started" # Workflow execution begins
WorkflowEvent.type == "status" # Workflow state changed (use .state)
WorkflowEvent.type == "output" # Workflow produces a terminal (final) output
WorkflowEvent.type == "intermediate" # Workflow produces an intermediate (observational) output
WorkflowEvent.type == "failed" # Workflow terminated with error (use .details)
WorkflowEvent.type == "error" # Non-fatal error from user code
WorkflowEvent.type == "warning" # Workflow encountered a warning
# Executor events
WorkflowEvent.type == "executor_invoked" # Executor starts processing
WorkflowEvent.type == "executor_completed" # Executor finishes processing
WorkflowEvent.type == "executor_failed" # Executor encounters an error
WorkflowEvent.type == "data" # Deprecated alias for "intermediate"
# Superstep events
WorkflowEvent.type == "superstep_started" # Superstep begins
WorkflowEvent.type == "superstep_completed" # Superstep completes
# Request events
WorkflowEvent.type == "request_info" # A request is issued
Note
エージェントが承認が必要なツールを使用する場合、request_infoイベントは通常、人間の承認を必要とするツール呼び出しのContentを含むtype == "function_approval_request"ペイロードを伝達します。 これらのイベントの処理の詳細については、 Human-in-the-Loop を参照してください。
Note
"output" と "intermediate" は、2 つの出力識別子です。
ターミナル出力ソースとして指定された Executor は、("output" によって使用される) WorkflowRunResult.get_outputs()イベントを出力します。
中間出力ソースとして指定された 1 つは、("intermediate" によって使用される) WorkflowRunResult.get_intermediate_outputs()イベントを出力します。
"data"の種類は、"intermediate"の非推奨のエイリアスであり、今後のリリースで削除される予定です。新しいコードで"intermediate"をフィルター処理することをお勧めします。
Go イベントは workflow.Event を実装し、Data() を介してペイロードを公開します。 型スイッチを使用して、型指定されたフィールドを調べます。
| イベントの種類 | ペイロードと目的 |
|---|---|
workflow.StartedEvent |
入力処理サイクルを開始します。
Message には入力が含まれています。 |
workflow.OutputEvent |
指定された Executor は、 Outputで値を生成します。
Tags は中間出力を識別します。 |
workflow.ErrorEvent |
エラーを Error に表示します。
SubWorkflowID は、設定時に入れ子になったワークフローを識別します。 |
workflow.WorkflowWarningEvent |
Messageで警告を表示します。 |
workflow.ExecutorInvokedEvent |
Executor が処理を開始します。
ExecutorID によってそれが識別され、 Message にその入力が含まれます。 |
workflow.ExecutorCompletedEvent |
Executor は処理を完了します。
Result には結果が含まれます。 |
workflow.ExecutorFailedEvent |
Executor の実行に失敗しました。
ExecutorID と Error でエラーが特定されます。 |
workflow.SuperStepStartedEvent |
スーパーステップが開始されます。
StepNumber と StartInfo がそれを説明します。 |
workflow.SuperStepCompletedEvent |
スーパーステップが完了しました。
CompletionInfo は、保留中の作業、要求、チェックポイントについて記述します。 |
workflow.RequestInfoEvent |
Request には、ホストが応答できる外部要求が含まれています。 |
workflow.RequestHaltEvent |
Executer が停止を要求しました。
Result にはペイロード (存在する場合) が含まれます。 |
Go では、ターミナル出力と中間出力の両方に OutputEvent が使用されます。
IsIntermediate()を呼び出して区別します。Pythonの個別の"output"と"intermediate"判別子は使用しません。
また、ホストされるエージェントは、対応するイベントが有効な場合に、*agent.ResponseUpdate または *agent.Response のペイロードと共に OutputEvent を使用します。 Go では、個別の AgentResponseEvent 型と AgentResponseUpdateEvent 型は定義されません。 構成については エージェント実行プログラム を参照してください。
イベントの使用
using Microsoft.Agents.AI.Workflows;
await foreach (WorkflowEvent evt in run.WatchStreamAsync())
{
switch (evt)
{
case ExecutorInvokedEvent invoke:
Console.WriteLine($"Starting {invoke.ExecutorId}");
break;
case ExecutorCompletedEvent complete:
Console.WriteLine($"Completed {complete.ExecutorId}: {complete.Data}");
break;
case WorkflowOutputEvent output:
Console.WriteLine($"Workflow output: {output.Data}");
return;
case WorkflowErrorEvent error:
Console.WriteLine($"Workflow error: {error.Exception}");
return;
}
}
from agent_framework import WorkflowEvent
async for event in workflow.run(input_message, stream=True):
if event.type == "executor_invoked":
print(f"Starting {event.executor_id}")
elif event.type == "executor_completed":
print(f"Completed {event.executor_id}: {event.data}")
elif event.type == "intermediate":
print(f"Intermediate output from {event.executor_id}: {event.data}")
elif event.type == "output":
print(f"Terminal output: {event.data}")
return
elif event.type == "error":
print(f"Workflow error: {event.data}")
return
Go ワークフロー イベントには型スイッチを使用します。 反復子エラーとエラー イベントを個別に処理します: 出力を受信しても、ワークフローの残りの部分が成功するとは限りません。
イベントを観察する
inproc.Default.Run は次の停止位置に進み、イベントを蓄積します。 実行は外部入力に対して一時停止できます。停止したからといって完了とは限りません。
次の関数は、Executor アクティビティと出力を出力し、失敗を返し、実行を閉じます。
import (
"context"
"errors"
"fmt"
"github.com/microsoft/agent-framework-go/workflow"
"github.com/microsoft/agent-framework-go/workflow/inproc"
)
func observeEvents(
ctx context.Context, wf *workflow.Workflow, input any,
) (err error) {
run, err := inproc.Default.Run(ctx, wf, input)
if err != nil {
return err
}
defer func() {
err = errors.Join(err, run.Close(context.WithoutCancel(ctx)))
}()
for event := range run.NewEvents() {
switch event := event.(type) {
case workflow.ExecutorInvokedEvent:
fmt.Printf("Starting %s\n", event.ExecutorID)
case workflow.ExecutorCompletedEvent:
fmt.Printf("Completed %s: %v\n",
event.ExecutorID, event.Result)
case workflow.OutputEvent:
kind := "Terminal"
if event.IsIntermediate() {
kind = "Intermediate"
}
fmt.Printf("%s output from %s: %v\n",
kind, event.ExecutorID, event.Output)
case workflow.ErrorEvent:
return event.Error
case workflow.ExecutorFailedEvent:
return fmt.Errorf("executor %q failed: %w",
event.ExecutorID, event.Error)
}
}
return nil
}
NewEvents() は、前回の呼び出し以降に蓄積されたイベントを返します。 そのブックマークは、早い段階で反復処理を停止した場合でも、呼び出すと進みます。
OutgoingEvents()を使用して、NewEvents()を再度呼び出す代わりに、蓄積されたすべてのイベントを再生します。
ストリーミング イベント
RunStreamingを使用して、イベントが到着した時点で観察します。 この関数は、外部入力を必要としないワークフローを監視します。
import (
"context"
"errors"
"fmt"
"github.com/microsoft/agent-framework-go/workflow"
"github.com/microsoft/agent-framework-go/workflow/inproc"
)
func streamEvents(
ctx context.Context, wf *workflow.Workflow, input any,
) (err error) {
run, err := inproc.Default.RunStreaming(ctx, wf, input)
if err != nil {
return err
}
defer func() {
err = errors.Join(err, run.Close(context.WithoutCancel(ctx)))
}()
for event, streamErr := range run.WatchStream(ctx) {
if streamErr != nil {
return streamErr
}
switch event := event.(type) {
case workflow.OutputEvent:
kind := "Terminal"
if event.IsIntermediate() {
kind = "Intermediate"
}
fmt.Printf("%s output from %s: %v\n",
kind, event.ExecutorID, event.Output)
case workflow.ErrorEvent:
return event.Error
case workflow.ExecutorFailedEvent:
return fmt.Errorf("executor %q failed: %w",
event.ExecutorID, event.Error)
}
}
return nil
}
WatchStream は、ワークフローに保留中の外部要求がある場合に待機し続けます。
RequestInfoEvent を処理し、要求駆動型ワークフローに使用するときに、SendResponse を介して一致する応答を送信します。
コンシューマーが応答を待たずに一時停止時に戻る必要がある場合は、代わりに WatchUntilHalt を使用します。 ストリーミング実行を一度に処理できるイベント反復子は 1 つだけです。 要求の処理と再開については、 Human-in-the-loop ワークフロー を参照してください。
カスタム イベント
カスタム イベントを使用すると、Executor は、アプリケーションのニーズに合わせて調整されたワークフローの実行中にドメイン固有のシグナルを出力できます。 ユース ケースの例を次にいくつか示します。
- 進行状況を追跡 する - 発信者が状態の更新を表示できるように、中間ステップを報告します。
- 診断の出力 — ワークフロー出力を変更せずに、警告、メトリック、またはデバッグ情報を表示します。
- リレー ドメイン データ — 構造化ペイロード (データベースの書き込み、ツール呼び出しなど) をリスナーにリアルタイムでプッシュします。
カスタム イベントの定義
WorkflowEventサブクラス化してカスタム イベントを定義します。 基本コンストラクターは、object? data プロパティを介して公開される省略可能なDataペイロードを受け入れます。
using Microsoft.Agents.AI.Workflows;
// Simple event with a string payload
internal sealed class ProgressEvent(string step) : WorkflowEvent(step) { }
// Event with a structured payload
internal sealed class MetricsEvent(MetricsData metrics) : WorkflowEvent(metrics) { }
Python では、カスタム型識別子文字列を使用して、 WorkflowEvent クラスを直接使用してカスタム イベントを作成します。
typeパラメーターと data パラメーターには、すべての情報が含まれます。
from agent_framework import WorkflowEvent
# Create a custom event with a custom type string and payload
event = WorkflowEvent(type="progress", data="Step 1 complete")
# Custom event with a structured payload
event = WorkflowEvent(type="metrics", data={"latency_ms": 42, "tokens": 128})
Note
イベントの種類 "started"、 "status"、および "failed" は、フレームワークのライフサイクル通知用に予約されています。 Executor がこれらの型のいずれかを出力しようとすると、イベントは無視され、警告がログに記録されます。
workflow.Event インターフェイスを実装する型を作成して、カスタム イベントを定義します。
Data メソッドは、イベント ペイロードを返します。
import "github.com/microsoft/agent-framework-go/workflow"
type ProgressEvent struct {
Step string
}
func (e ProgressEvent) Data() any {
return e.Step
}
var _ workflow.Event = ProgressEvent{}
カスタム イベントの出力
AddEventAsyncでIWorkflowContextを呼び出して、Executor のメッセージ ハンドラーからカスタム イベントを生成します。
using Microsoft.Agents.AI.Workflows;
internal sealed class ProgressEvent(string step) : WorkflowEvent(step) { }
internal sealed partial class CustomExecutor() : Executor("CustomExecutor")
{
[MessageHandler]
private async ValueTask HandleAsync(string message, IWorkflowContext context)
{
await context.AddEventAsync(new ProgressEvent("Validating input"));
// Executor logic...
await context.AddEventAsync(new ProgressEvent("Processing complete"));
}
}
add_eventでWorkflowContextを呼び出して、ハンドラーからカスタム イベントを生成します。
from agent_framework import (
handler,
Executor,
WorkflowContext,
WorkflowEvent,
)
class CustomExecutor(Executor):
@handler
async def handle(self, message: str, ctx: WorkflowContext[str]) -> None:
await ctx.add_event(WorkflowEvent(type="progress", data="Validating input"))
# Executor logic...
await ctx.add_event(WorkflowEvent(type="progress", data="Processing complete"))
AddEventでworkflow.Contextを呼び出して、Executor ハンドラーからカスタム イベントを生成します。
import "github.com/microsoft/agent-framework-go/workflow"
customExecutor := workflow.NewExecutor("CustomExecutor", func(ctx *workflow.Context, message string) error {
if err := ctx.AddEvent(ProgressEvent{Step: "Validating input"}); err != nil {
return err
}
// Executor logic...
return ctx.AddEvent(ProgressEvent{Step: "Processing complete"})
}).Bind()
カスタム イベントは WithOutputFromを必要としません。AddEvent はそれらを直接発行します。 通常のワークフロー出力も必要な場合は、 YieldOutput を使用し、出力ソースを指定します。
カスタム イベントの処理
パターン マッチングを使用して、イベント ストリーム内のカスタム イベントの種類をフィルター処理します。
await foreach (WorkflowEvent evt in run.WatchStreamAsync())
{
switch (evt)
{
case ProgressEvent progress:
Console.WriteLine($"Progress: {progress.Data}");
break;
case WorkflowOutputEvent output:
Console.WriteLine($"Done: {output.Data}");
return;
}
}
カスタム型識別子文字列を用いてフィルターを実行します。
async for event in workflow.run(input_message, stream=True):
if event.type == "progress":
print(f"Progress: {event.data}")
elif event.type == "output":
print(f"Done: {event.data}")
return
型スイッチまたは型アサーションを使用して、イベント ストリーム内のカスタム イベントの種類をフィルター処理します。
for evt, err := range run.WatchStream(ctx) {
if err != nil {
return err
}
switch e := evt.(type) {
case ProgressEvent:
fmt.Printf("Progress: %v\n", e.Data())
case workflow.OutputEvent:
fmt.Printf("Done: %v\n", e.Output)
case workflow.ErrorEvent:
return e.Error
case workflow.ExecutorFailedEvent:
return fmt.Errorf("executor %q failed: %w", e.ExecutorID, e.Error)
}
}
次のステップ
関連トピック: