このドキュメントでは、Microsoft Agent Framework で ワークフローをエージェントとして 使用する方法の概要について説明します。
概要
複数のエージェント、カスタム Executor、複雑なロジックを使用して高度なワークフローを構築したが、他のエージェントと同じように使用したい場合があります。 ワークフロー エージェントがまさにそれを可能にします。 ワークフローを Agentとしてラップすることで、単純なチャット エージェントに使用するのと同じ使い慣れた API を使用してワークフローを操作できます。
主な利点
- 統合インターフェイス: 単純なエージェントと同じ API を使用して複雑なワークフローと対話する
- API の互換性: エージェント インターフェイスをサポートする既存のシステムとワークフローを統合する
- コンポーザビリティ: 大規模なエージェント システムまたはその他のワークフローの構成要素としてワークフロー エージェントを使用する
- セッション管理: 会話の状態と再開にエージェント セッションを活用する
- ストリーミング サポート: ワークフローの実行時にリアルタイムの更新プログラムを取得する
しくみ
ワークフローをエージェントに変換する場合:
- ワークフローは、起動エグゼキューターが必要な入力の種類を受け入れることを確実にするために検証されます。
- 会話の状態を管理するためのセッションが作成されます
- 入力メッセージはワークフローの開始 Executor にルーティングされます
- ワークフロー イベントがエージェント応答の更新に変換される
- (
RequestInfoExecutorからの) 外部入力要求は、関数呼び出しとして表示されます
Requirements
ワークフローをエージェントとして使用するには、ワークフローの開始 Executor が入力として IEnumerable<ChatMessage> を処理できる必要があります。 これは、 AsAIAgentで作成されたエージェント ベースの Executor を使用する場合に自動的に満たされます。
ワークフロー エージェントを作成する
AsAIAgent()拡張メソッドを使用して、互換性のあるワークフローをエージェントに変換します。
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Workflows;
using Microsoft.Extensions.AI;
// Create agents
AIAgent researchAgent = chatClient.AsAIAgent("You are a researcher. Research and gather information on the given topic.");
AIAgent writerAgent = chatClient.AsAIAgent("You are a writer. Write clear, engaging content based on research.");
AIAgent reviewerAgent = chatClient.AsAIAgent("You are a reviewer. Review the content and provide a final polished version.");
// Build a sequential workflow
var workflow = new WorkflowBuilder(researchAgent)
.AddEdge(researchAgent, writerAgent)
.AddEdge(writerAgent, reviewerAgent)
.Build();
// Convert the workflow to an agent
AIAgent workflowAgent = workflow.AsAIAgent(
id: "content-pipeline",
name: "Content Pipeline Agent",
description: "A multi-agent workflow that researches, writes, and reviews content"
);
AsAIAgent パラメーター
| パラメーター | タイプ | Description |
|---|---|---|
id |
string? |
省略可能なエージェントの一意識別子。 指定されていない場合は自動生成されます。 |
name |
string? |
エージェントの表示名(任意) |
description |
string? |
エージェントの目的の説明 (省略可能)。 |
executionEnvironment |
IWorkflowExecutionEnvironment? |
オプションの実行環境。 既定では、ワークフロー設定によって InProcessExecution.OffThread または InProcessExecution.Concurrent に設定されます。 |
includeExceptionDetails |
bool |
true場合は、エラー コンテンツに例外メッセージを含みます。 既定値は false です。 |
includeWorkflowOutputsInResponse |
bool |
true場合は、送信ワークフロー出力をエージェント応答のコンテンツに変換します。 既定値は false です。 |
ワークフロー エージェントの使用
セッションの作成
ワークフロー エージェントとの各会話には、状態を管理するためのセッションが必要です。
// Create a new session for the conversation
AgentSession session = await workflowAgent.CreateSessionAsync();
非ストリーミング実行
完全な応答が必要な単純なユース ケースの場合:
var messages = new List<ChatMessage>
{
new(ChatRole.User, "Write an article about renewable energy trends in 2025")
};
AgentResponse response = await workflowAgent.RunAsync(messages, session);
foreach (ChatMessage message in response.Messages)
{
Console.WriteLine($"{message.AuthorName}: {message.Text}");
}
ストリーミング実行
ワークフローの実行時にリアルタイムで更新する場合:
var messages = new List<ChatMessage>
{
new(ChatRole.User, "Write an article about renewable energy trends in 2025")
};
await foreach (AgentResponseUpdate update in workflowAgent.RunStreamingAsync(messages, session))
{
// Process streaming updates from each agent in the workflow
if (!string.IsNullOrEmpty(update.Text))
{
Console.Write(update.Text);
}
}
外部入力要求の処理
( RequestInfoExecutorを使用して) 外部入力を要求する実行プログラムがワークフローに含まれている場合、これらの要求はエージェント応答の関数呼び出しとして表示されます。
await foreach (AgentResponseUpdate update in workflowAgent.RunStreamingAsync(messages, session))
{
// Check for function call requests
foreach (AIContent content in update.Contents)
{
if (content is FunctionCallContent functionCall)
{
// Handle the external input request
Console.WriteLine($"Workflow requests input: {functionCall.Name}");
Console.WriteLine($"Request data: {functionCall.Arguments}");
// Provide the response in the next message
}
}
}
セッションのシリアル化と再開
永続化のためにワークフロー エージェント セッションをシリアル化し、後で再開できます。
// Serialize the session state
JsonElement serializedSession = await workflowAgent.SerializeSessionAsync(session);
// Store serializedSession to your persistence layer...
// Later, resume the session
AgentSession resumedSession = await workflowAgent.DeserializeSessionAsync(serializedSession);
// Continue the conversation
await foreach (var update in workflowAgent.RunStreamingAsync(newMessages, resumedSession))
{
Console.Write(update.Text);
}
Requirements
ワークフローをエージェントとして使用するには、ワークフローの開始 Executor がメッセージ入力を処理できる必要があります。 これは、 Agent またはエージェント ベースの Executor を使用する場合に自動的に満たされます。
ワークフロー エージェントの作成
互換性のあるワークフローの as_agent() を呼び出して、エージェントに変換します。
from agent_framework.foundry import FoundryChatClient
from agent_framework.orchestrations import SequentialBuilder
from azure.identity import AzureCliCredential
# Create your chat client and agents
client = FoundryChatClient(
project_endpoint="<your-endpoint>",
model="<your-deployment>",
credential=AzureCliCredential(),
)
researcher = client.as_agent(
name="Researcher",
instructions="Research and gather information on the given topic.",
)
writer = client.as_agent(
name="Writer",
instructions="Write clear, engaging content based on research.",
)
# Build a sequential workflow
workflow = SequentialBuilder(participants=[researcher, writer]).build()
# Convert the workflow to an agent
workflow_agent = workflow.as_agent(name="Content Pipeline Agent")
as_agent パラメーター
| パラメーター | タイプ | Description |
|---|---|---|
name |
str | None |
エージェントの表示名(任意) 指定されていない場合は自動生成されます。 |
ワークフロー エージェントの使用
セッションの作成
必要に応じて、複数のターンで会話の状態を管理するセッションを作成できます。
# Create a new session for the conversation
session = await workflow_agent.create_session()
注
セッションは省略可能です。
sessionにrun()を渡さない場合、エージェントは内部的に状態を処理します。
workflow.as_agent()なしでcontext_providersが作成された場合、フレームワークは既定でInMemoryHistoryProvider()を追加するため、複数ターン履歴は既定で機能します。
context_providers明示的に渡した場合、そのリストは as-is使用されます。
非ストリーミング実行
完全な応答が必要な単純なユース ケースの場合:
# You can pass a plain string as input
response = await workflow_agent.run("Write an article about AI trends")
for message in response.messages:
print(f"{message.author_name}: {message.text}")
ストリーミング実行
ワークフローの実行時にリアルタイムで更新する場合:
async for update in workflow_agent.run(
"Write an article about AI trends",
stream=True,
):
if update.text:
print(update.text, end="", flush=True)
外部入力要求の処理
( request_infoを使用して) 外部入力を要求する実行プログラムがワークフローに含まれている場合、これらの要求はエージェント応答の関数呼び出しとして表示されます。 関数呼び出しでは、 WorkflowAgent.REQUEST_INFO_FUNCTION_NAME名前が使用されます。
from agent_framework import Content, Message, WorkflowAgent
response = await workflow_agent.run("Process my request")
# Look for function calls in the response
human_review_function_call = None
for message in response.messages:
for content in message.contents:
if content.name == WorkflowAgent.REQUEST_INFO_FUNCTION_NAME:
human_review_function_call = content
保留中の要求への応答の提供
外部入力要求の後にワークフローの実行を続行するには、関数の結果を作成して返します。
if human_review_function_call:
# Parse the request arguments
request = WorkflowAgent.RequestInfoFunctionArgs.from_json(
human_review_function_call.arguments
)
# Create a response (your custom response type)
result_data = MyResponseType(approved=True, feedback="Looks good")
# Create the function call result
function_result = Content.from_function_result(
call_id=human_review_function_call.call_id,
result=result_data,
)
# Send the response back to continue the workflow
response = await workflow_agent.run(Message("tool", [function_result]))
完全な例
ストリーミング出力を含むワークフロー エージェントを示す完全な例を次に示します。
import asyncio
import os
from agent_framework.foundry import FoundryChatClient
from agent_framework.orchestrations import SequentialBuilder
from azure.identity import AzureCliCredential
async def main():
# Set up the chat client
client = FoundryChatClient(
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
model=os.environ["FOUNDRY_MODEL"],
credential=AzureCliCredential(),
)
# Create specialized agents
researcher = client.as_agent(
name="Researcher",
instructions="Research the given topic and provide key facts.",
)
writer = client.as_agent(
name="Writer",
instructions="Write engaging content based on the research provided.",
)
reviewer = client.as_agent(
name="Reviewer",
instructions="Review the content and provide a final polished version.",
)
# Build a sequential workflow
workflow = SequentialBuilder(participants=[researcher, writer, reviewer]).build()
# Convert to a workflow agent
workflow_agent = workflow.as_agent(name="Content Creation Pipeline")
# Run the workflow
print("Starting workflow...")
print("=" * 60)
current_author = None
async for update in workflow_agent.run(
"Write about quantum computing",
stream=True,
):
# Show when different agents are responding
if update.author_name and update.author_name != current_author:
if current_author:
print("\n" + "-" * 40)
print(f"\n[{update.author_name}]:")
current_author = update.author_name
if update.text:
print(update.text, end="", flush=True)
print("\n" + "=" * 60)
print("Workflow completed!")
if __name__ == "__main__":
asyncio.run(main())
イベント変換について
ワークフローがエージェントとして実行されると、ワークフロー イベントはエージェントの応答に変換されます。 応答の種類は、 run()の呼び出し方法によって異なります。
-
run(): ワークフローの完了後の完全な結果を含むAgentResponseを返します。 -
run(..., stream=True): ワークフローの実行時にAgentResponseUpdateオブジェクトの非同期反復処理を返し、リアルタイムの更新を提供します。
実行中、内部ワークフロー イベントは次のようにエージェントの応答にマップされます。
| ワークフロー イベント | エージェントの応答 |
|---|---|
event.type == "output" |
AgentResponseUpdate (ストリーミング) として渡されるか、AgentResponse (非ストリーミング) に集約される |
event.type == "request_info" |
WorkflowAgent.REQUEST_INFO_FUNCTION_NAME を使用して関数呼び出しコンテンツに変換されました |
| その他のイベント | 無視 (ワークフロー内部のみ) |
この変換により、必要に応じ、詳細なワークフロー情報に引き続きアクセスしながら、標準エージェント インターフェイスを使用できます。
使用例
1. 複雑なエージェントパイプライン
アプリケーションで使用するために、マルチエージェント ワークフローを単一のエージェントとしてラップします。
User Request --> [Workflow Agent] --> Final Response
|
+-- Researcher Agent
+-- Writer Agent
+-- Reviewer Agent
2. エージェント組成物
大規模なシステムでワークフロー エージェントをコンポーネントとして使用する:
- ワークフロー エージェントは、別のエージェントによってツールとして使用できます
- 複数のワークフロー エージェントを一緒に調整できる
- ワークフロー エージェントは、他のワークフロー内で入れ子にすることができます
3. API 統合
標準のエージェント インターフェイスを必要とする API を介して複雑なワークフローを公開し、次のことが可能になります。
- 高度なバックエンド ワークフローを使用するチャット インターフェイス
- 既存のエージェント ベースシステムとの統合
- 単純なエージェントから複雑なワークフローへの段階的な移行