Principle:Microsoft Agent framework Executor Definition
| Knowledge Sources | |
|---|---|
| Domains | Workflow_Engine, Agent_Architecture |
| Last Updated | 2026-02-11 |
Overview
The Executor Definition principle describes the fundamental unit of work within the Microsoft Agent Framework's workflow engine. An Executor is a graph node that receives typed messages, processes them through handler methods, and sends results to downstream nodes or yields output to the workflow caller. Executors support handler discovery via decorators, lifecycle hooks, and state management, making them the building blocks of all graph-based workflow compositions.
Description
An Executor in the Microsoft Agent Framework is the atomic processing element in a directed workflow graph. Where an Agent wraps an LLM with tools and conversation management, an Executor is a lower-level primitive that performs a discrete transformation step -- it may invoke an LLM, apply a deterministic function, filter data, aggregate results, or perform any other operation that fits within the message-passing paradigm.
Every Executor:
- Receives typed input messages routed to it by the workflow engine based on the graph topology.
- Processes messages through handler methods decorated with
@handler, which the engine discovers automatically at registration time. - Sends results downstream via
WorkflowContext.send_message()to connected nodes in the graph. - Yields workflow output via
WorkflowContext.yield_output()to surface results to the workflow caller.
Handler Discovery
Executors use a decorator-based handler discovery mechanism. Methods decorated with @handler are automatically registered as message processors when the Executor is added to a workflow graph. The engine inspects the handler's type annotations to determine which message types it can process, enabling type-safe routing of messages through the graph.
Each handler receives two arguments:
- The typed input message matching the handler's declared input type.
- A
WorkflowContextobject that provides access to downstream messaging, workflow output yielding, and execution metadata.
Lifecycle Hooks
Executors participate in the workflow lifecycle through hooks that fire at well-defined points:
- Initialization: The
__init__method sets up the Executor's identity and any initial state. - Handler registration: When the Executor is added to a workflow graph, the engine discovers and registers all
@handlermethods. - Message dispatch: The engine routes incoming messages to the appropriate handler based on type matching.
- Completion: The Executor signals completion by either sending messages downstream or yielding output.
State Management
Executors inherit from both RequestInfoMixin and DictConvertible, providing:
- Request metadata access through
RequestInfoMixin, which exposes information about the current execution request. - Serialization support through
DictConvertible, enabling Executors to be converted to and from dictionary representations for persistence, debugging, and transport.
Instance-level state can be maintained across handler invocations within a single workflow run, allowing Executors to accumulate results, track counters, or manage any mutable state required by their processing logic.
Design Properties
| Property | Value |
|---|---|
| Granularity | Single processing step in a directed workflow graph |
| Input Model | Typed messages routed by the workflow engine based on handler annotations |
| Output Model | Downstream messages via send_message() or workflow output via yield_output()
|
| Handler Discovery | Automatic via @handler decorator and type annotation inspection
|
| State Scope | Instance-level, persisted across handler invocations within a workflow run |
| Serialization | Dictionary conversion via DictConvertible base class
|
Theoretical Basis
The Executor Definition principle draws from several established patterns in workflow and dataflow systems:
1. Dataflow graph nodes: In dataflow programming, computation is modeled as a directed graph where nodes transform data and edges carry messages between them. The Executor is the node primitive in this model, receiving input on inbound edges and emitting output on outbound edges.
2. Actor model: Like actors in the actor model of computation, Executors are independent processing units that communicate exclusively through message passing. This eliminates shared mutable state between Executors and enables safe concurrent execution.
3. Strategy pattern via handlers: The @handler decorator allows an Executor to define multiple processing strategies, each specialized for a different message type. The engine selects the appropriate strategy at runtime based on the incoming message's type, following the strategy pattern.
4. Separation of topology and logic: The Executor encapsulates processing logic while the workflow graph defines topology (which Executors connect to which). This separation allows the same Executor class to be reused in different graph configurations without modification.
Usage
Use the Executor Definition pattern when:
- Building workflow graphs that require discrete processing steps connected by typed message channels.
- Composing agent pipelines where each step performs a specific transformation (e.g., preprocessing, LLM invocation, postprocessing, validation).
- Implementing custom logic nodes that do not require the full weight of an Agent but need to participate in a workflow.
- Creating reusable processing components that can be wired into different workflow topologies.
Example
from agent_framework import Executor, handler, WorkflowContext
class UpperCase(Executor):
def __init__(self, id: str):
super().__init__(id=id)
@handler
async def to_upper(self, text: str, ctx: WorkflowContext[str]) -> None:
result = text.upper()
await ctx.send_message(result)