Microsoft 에이전트 프레임워크 워크플로 - 워크플로를 에이전트로 사용

이 문서에서는 Microsoft Agent Framework에서 워크플로를 에이전트로 사용하는 방법에 대한 개요를 제공합니다.

개요

경우에 따라 여러 에이전트, 사용자 지정 실행기 및 복잡한 논리를 사용하여 정교한 워크플로를 빌드했지만 다른 에이전트와 마찬가지로 사용하려고 합니다. 이것이 바로 워크플로 에이전트가 수행할 수 있는 작업입니다. 워크플로를 Agent로 래핑하면 간단한 채팅 에이전트에서 사용하는 익숙한 API를 통해 상호작용할 수 있습니다.

주요 이점

  • 통합 인터페이스: 단순 에이전트와 동일한 API를 사용하여 복잡한 워크플로와 상호 작용
  • API 호환성: 에이전트 인터페이스를 지원하는 기존 시스템과 워크플로 통합
  • 구성성: 더 큰 에이전트 시스템 또는 기타 워크플로에서 워크플로 에이전트를 구성 요소로 사용
  • 세션 관리: 대화 상태 및 재개에 에이전트 세션 활용
  • 스트리밍 지원: 워크플로가 실행됨에 따라 실시간 업데이트 가져오기

작동 방식

워크플로를 에이전트로 변환하는 경우:

  1. 워크플로의 유효성을 검사하여 시작 실행기가 필요한 입력 형식을 수락할 수 있는지 확인합니다.
  2. 대화 상태를 관리하기 위한 세션이 만들어집니다.
  3. 입력 메시지는 워크플로의 시작 실행기로 라우팅됩니다.
  4. 워크플로 이벤트가 에이전트 응답 업데이트로 변환됩니다.
  5. 외부 입력 요청(원본 RequestInfoExecutor)이 함수 호출로 표시됩니다.

요구 사항

워크플로를 에이전트로 사용하려면 워크플로의 시작 실행기가 입력으로 처리 IEnumerable<ChatMessage> 할 수 있어야 합니다. 로 만든 AsAIAgent에이전트 기반 실행기를 사용할 때 자동으로 충족됩니다.

워크플로 에이전트 만들기

확장 메서드를 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);
}

요구 사항

워크플로를 에이전트로 사용하려면 워크플로의 시작 실행기가 메시지 입력을 처리할 수 있어야 합니다. Agent 또는 에이전트 기반 실행기를 사용할 때 자동으로 충족됩니다.

워크플로 에이전트 만들기

호환되는 워크플로를 호출 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()

비고

세션은 선택 사항입니다. sessionrun()에 전달하지 않으면, 에이전트가 내부적으로 상태를 처리합니다. workflow.as_agent()context_providers 없이 생성될 경우, 프레임워크는 기본적으로 InMemoryHistoryProvider()를 추가하여 멀티턴 기록이 자동으로 작동합니다. 명시적으로 context_providers를 전달하면 해당 목록이 그대로 사용됩니다.

스트리밍이 아닌 실행

전체 응답을 원하는 간단한 사용 사례의 경우:

# 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를 통해 복잡한 워크플로를 노출하고, 이를 활용할 수 있도록 합니다.

  • 정교한 백 엔드 워크플로를 사용하는 채팅 인터페이스
  • 기존 에이전트 기반 시스템과 통합
  • 간단한 에이전트에서 복잡한 워크플로로 점진적 마이그레이션

다음 단계