Agent Delegation Best Practices

Eric Brasher February 21, 2026 at 9:42 AM 5 min read

FabrCore provides the primitives for agent-to-agent delegation — health checks, messaging, and routing. The orchestration logic that ties them together is your application code.

The Building Blocks

Agent delegation in FabrCore uses three primitives that are already part of the framework:

  • GetAgentHealth() — Query any agent's health and readiness before delegating work
  • SendAndReceiveMessage() — Send a message to another agent and wait for a response
  • SendMessage() — Fire-and-forget delegation for background work

These are sufficient for most delegation patterns. A custom orchestration layer on top is usually unnecessary complexity.

Health-Aware Delegation

Before delegating work, check the target agent's health. This is a 10-line pattern, not a framework feature:

DelegateAgent.cs
private async Task<List<string>> GetHealthyAgentsAsync(
    string[] candidateHandles)
{
    var healthy = new List<string>();
    foreach (var handle in candidateHandles)
    {
        var health = await AgentHost
            .GetAgentHealth(handle, HealthDetail.Basic);
        if (health?.Status == AgentHealthStatus.Active)
            healthy.Add(handle);
    }
    return healthy;
}

Request-Response Delegation

Use SendAndReceiveMessage when you need the result before continuing:

Synchronous Delegation
var response = await AgentHost.SendAndReceiveMessage(
    targetHandle,
    new AgentMessage
    {
        Message = userMessage,
        MessageType = "delegation",
        Channel = "internal"
    });

// Response contains the target agent's reply
return response;

Use SendMessage with MessageKind.OneWay when you don't need to wait:

Fire-and-Forget Delegation
await AgentHost.SendMessage(
    targetHandle,
    new AgentMessage
    {
        Message = "Process this in the background",
        Kind = MessageKind.OneWay,
        Channel = "background-tasks"
    });

Why Not a Built-in Orchestrator?

Teams sometimes request a built-in delegation/orchestration framework. Here's why FabrCore provides primitives instead:

Delegation logic is application-specific. How you select agents, retry failures, aggregate results, and handle timeouts depends entirely on your domain. A weather agent delegates differently than a customer support router.

Orchestration boilerplate is small. A typical delegation pattern is 30-50 lines of application code. That's not framework territory — it's straightforward code that's easy to understand, debug, and modify.

Abstractions hide important decisions. When delegation fails, you need to know exactly what happened. A framework abstraction between your code and the messaging primitives makes that harder, not easier.

Learn More

Check out the delegation patterns documentation for the complete reference.


Eric Brasher

Builder of FabrCore and OpenCaddis.