Agent Delegation Best Practices
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 workSendAndReceiveMessage()— Send a message to another agent and wait for a responseSendMessage()— 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:
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:
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:
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.
Builder of FabrCore and OpenCaddis.