Sdílet prostřednictvím


Exekutoři

Exekutory jsou základní stavební bloky, které zpracovávají zprávy v pracovním postupu. Jedná se o autonomní jednotky zpracování, které přijímají typové zprávy, provádějí operace a můžou vytvářet výstupní zprávy nebo události.

Přehled

Každý exekutor má jedinečný identifikátor a může zpracovávat konkrétní typy zpráv. Exekutory můžou být:

  • Vlastní komponenty logiky – zpracování dat, volání rozhraní API nebo transformace zpráv
  • Agenti AI – použití LLM k vygenerování odpovědí (viz Agenti v pracovních postupech)

Důležité

Doporučeným způsobem definování obslužných rutin zpráv exekutoru v jazyce C# je použití atributu [MessageHandler] u metod v rámci partial třídy, která je odvozena z Executor. To využívá generování zdrojového kódu během kompilace pro registraci obslužné rutiny, což poskytuje lepší výkon, validace při kompilaci a kompatibilitu s Native AOT.

Základní struktura vykonavatele

Exekutory jsou odvozeny ze Executor základní třídy a používají [MessageHandler] atribut k deklaraci metod obslužné rutiny. Aby bylo možné povolit generování zdroje, musí být třída označena partial .

using Microsoft.Agents.AI.Workflows;

internal sealed partial class UppercaseExecutor() : Executor("UppercaseExecutor")
{
    [MessageHandler]
    private ValueTask<string> HandleAsync(string message, IWorkflowContext context)
    {
        string result = message.ToUpperInvariant();
        return ValueTask.FromResult(result); // Return value is automatically sent to connected executors
    }
}

Zprávy můžete odesílat také ručně bez vrácení hodnoty:

internal sealed partial class UppercaseExecutor() : Executor("UppercaseExecutor")
{
    [MessageHandler]
    private async ValueTask HandleAsync(string message, IWorkflowContext context)
    {
        string result = message.ToUpperInvariant();
        await context.SendMessageAsync(result); // Manually send messages to connected executors
    }
}

Více vstupních typů

Zpracování více vstupních typů definováním více [MessageHandler] metod:

internal sealed partial class SampleExecutor() : Executor("SampleExecutor")
{
    [MessageHandler]
    private ValueTask<string> HandleStringAsync(string message, IWorkflowContext context)
    {
        return ValueTask.FromResult(message.ToUpperInvariant());
    }

    [MessageHandler]
    private ValueTask<int> HandleIntAsync(int message, IWorkflowContext context)
    {
        return ValueTask.FromResult(message * 2);
    }
}

Vykonavatelé založené na funkcích

Vytvořte spouštěč z funkce pomocí metody rozšíření BindExecutor.

Func<string, string> uppercaseFunc = s => s.ToUpperInvariant();
var uppercase = uppercaseFunc.BindExecutor("UppercaseExecutor");

Základní struktura vykonavatele

Exekutoři dědí z Executor základní třídy. Každý executor používá metody, které jsou dekorovány dekorátorem @handler. Obslužné rutiny musí mít správné anotace typu, aby určily typy zpráv, které zpracovávají.

from agent_framework import (
    Executor,
    WorkflowContext,
    handler,
)

class UpperCase(Executor):

    @handler
    async def to_upper_case(self, text: str, ctx: WorkflowContext[str]) -> None:
        """Convert the input to uppercase and forward it to the next node."""
        await ctx.send_message(text.upper())

Exekutory na bázi funkcí

Vytvořte vykonavatele z funkce pomocí dekorátoru @executor.

from agent_framework import (
    WorkflowContext,
    executor,
)

@executor(id="upper_case_executor")
async def upper_case(text: str, ctx: WorkflowContext[str]) -> None:
    """Convert the input to uppercase and forward it to the next node."""
    await ctx.send_message(text.upper())

Více vstupních typů

Zpracování více vstupních typů definováním více obslužných rutin:

class SampleExecutor(Executor):

    @handler
    async def to_upper_case(self, text: str, ctx: WorkflowContext[str]) -> None:
        await ctx.send_message(text.upper())

    @handler
    async def double_integer(self, number: int, ctx: WorkflowContext[int]) -> None:
        await ctx.send_message(number * 2)

Explicitní parametry typu

Jako alternativu k psaní poznámek můžete zadat typy explicitně prostřednictvím parametrů dekorátoru:

Důležité

Při použití explicitních parametrů typu je nutné zadat všechny typy prostřednictvím dekorátoru – nelze kombinovat explicitní parametry s poznámkami typu. Parametr input je povinný output a workflow_output je volitelný.

class ExplicitTypesExecutor(Executor):

    @handler(input=str, output=str)
    async def to_upper_case(self, text, ctx) -> None:
        await ctx.send_message(text.upper())

    @handler(input=str | int, output=str)
    async def handle_mixed(self, message, ctx) -> None:
        await ctx.send_message(str(message).upper())

    @handler(input=str, output=int, workflow_output=bool)
    async def process_with_workflow_output(self, message, ctx) -> None:
        await ctx.send_message(len(message))
        await ctx.yield_output(True)

Objekt WorkflowContext

Tento WorkflowContext poskytuje metody, které umožňují interakci s pracovním postupem během jeho provádění:

  • send_message — odesílání zpráv připojeným exekutorům
  • yield_output — vytváří výstupy pracovního postupu vrácené nebo streamované volajícímu.
class OutputExecutor(Executor):

    @handler
    async def handle(self, message: str, ctx: WorkflowContext[Never, str]) -> None:
        await ctx.yield_output("Hello, World!")

Pokud obslužná rutina neodesílá zprávy ani nedává výstupy, není potřeba žádný parametr typu:

class LogExecutor(Executor):

    @handler
    async def handle(self, message: str, ctx: WorkflowContext) -> None:
        print("Doing some work...")

Další kroky