Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Исполнителями являются основные стандартные блоки, обрабатывающие сообщения в рабочем процессе. Они являются автономными единицами обработки, которые получают типизированные сообщения, выполняют операции и могут создавать выходные сообщения или события.
Обзор
Каждый исполнитель имеет уникальный идентификатор и может обрабатывать определенные типы сообщений. Исполнителями могут быть:
- Пользовательские компоненты логики — обработка данных, вызов API или преобразование сообщений
- Агенты ИИ — используйте LLM для создания ответов (см. раздел "Агенты в рабочих процессах")
Это важно
Рекомендуемый способ определения обработчиков сообщений исполнителя в C# — использовать [MessageHandler] атрибут для методов в классе, наследуемом partial от Executor. В этом случае используется генерация исходного кода во время компиляции для регистрации обработчиков, что обеспечивает лучшую производительность, проверку на этапе компиляции и совместимость с Native AOT.
Базовая структура исполнителя
Исполнители наследуют от Executor базового класса и используют [MessageHandler] атрибут для объявления методов обработчика. Класс должен быть помечен 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
}
}
Вы также можете отправлять сообщения вручную, не возвращая значение:
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
}
}
Подсказка
Исполнители могут хранить изменяемое состояние. Если исполнитель с отслеживанием состояния используется в нескольких запусках рабочего процесса, он должен реализовать IResettableExecutor для очистки устаревшего состояния между запусками. Дополнительные сведения см. в разделе "Сбрасываемые исполнители".
Несколько типов входных данных
Обработка нескольких типов входных данных путем определения нескольких [MessageHandler] методов:
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);
}
}
Функционально-ориентированные исполнители
Создайте исполнителя из функции с помощью BindExecutor метода расширения:
Func<string, string> uppercaseFunc = s => s.ToUpperInvariant();
var uppercase = uppercaseFunc.BindExecutor("UppercaseExecutor");
Объект IWorkflowContext
Эта IWorkflowContext предоставляет методы для взаимодействия с рабочим процессом в ходе выполнения.
-
SendMessageAsync— отправка сообщений подключенным исполнителям -
YieldOutputAsync— создание результатов рабочего процесса, возвращаемых или передаваемых потоково вызывающему
internal sealed partial class OutputExecutor() : Executor("OutputExecutor")
{
[MessageHandler]
private async ValueTask HandleAsync(string message, IWorkflowContext context)
{
await context.YieldOutputAsync("Hello, World!");
}
}
Если обработчик не отправляет сообщения и не выдает выходные данные, он может просто выполнять побочные эффекты:
internal sealed partial class LogExecutor() : Executor("LogExecutor")
{
[MessageHandler]
private void Handle(string message, IWorkflowContext context)
{
Console.WriteLine("Doing some work...");
}
}
Базовая структура исполнителя
Исполнители наследуются от Executor базового класса. Каждый обработчик использует методы с декоратором @handler. Обработчики должны иметь правильные заметки типа, чтобы указать типы сообщений, которые они обрабатывают.
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())
Функционально-ориентированные исполнители
Создайте исполнителя из функции с помощью @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())
Несколько типов входных данных
Обработка нескольких типов входных данных путем определения нескольких обработчиков:
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)
Явные параметры типа
В качестве альтернативы примечаниям типа можно явно указать типы с помощью параметров декоратора:
Это важно
При использовании явных параметров типа необходимо указать все типы с помощью декоратора— нельзя смешивать явные параметры с заметками типа. Параметр input является обязательным; output и workflow_output необязателен.
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)
Объект WorkflowContext
Эта WorkflowContext предоставляет методы для взаимодействия с рабочим процессом в ходе выполнения.
-
send_message— отправка сообщений подключенным исполнителям -
yield_output— создание результатов рабочего процесса, возвращаемых или передаваемых потоково вызывающему
class OutputExecutor(Executor):
@handler
async def handle(self, message: str, ctx: WorkflowContext[Never, str]) -> None:
await ctx.yield_output("Hello, World!")
Если обработчик не отправляет сообщения и не выдает выходные данные, параметр типа не требуется:
class LogExecutor(Executor):
@handler
async def handle(self, message: str, ctx: WorkflowContext) -> None:
print("Doing some work...")