-
Notifications
You must be signed in to change notification settings - Fork 649
Description
Summary
When using AgentWorkflowBuilder.BuildConcurrent() or fan-out/fan-in patterns with multiple agents, the workflow visualizations (Mermaid and DOT diagrams) display mysterious "Batcher" nodes with cryptic identifiers. These appear to be internal framework components for managing concurrent agent execution, but they create significant visual noise and make diagrams difficult to understand.
These Batcher nodes serve no purpose for end users trying to understand workflow structure and should either be:
- Hidden from visualizations (preferred)
- Simplified into a single fan-in aggregation node
- Clearly labeled with meaningful names if they must be shown
Related Issues
#1495
Current Behavior
When building a concurrent workflow with multiple agents, the visualization output includes intermediate "Batcher" nodes:
// Build a concurrent workflow with 3 translation agents
var workflow = AgentWorkflowBuilder.BuildConcurrent(
from lang in new[] { "French", "Spanish", "English" }
select GetTranslationAgent(lang, chatClient)
);
// Generate visualization
Console.WriteLine(workflow.ToMermaidString());
Actual Output (Mermaid):
flowchart TD
Start["Start (Start)"];
4eaedcde6c56467e8fd92a68b98fb057["4eaedcde6c56467e8fd92a68b98fb057"];
cc0c636b920b4dd1ba5000ccfdadf6de["cc0c636b920b4dd1ba5000ccfdadf6de"];
1524c98619994e4fbb45bd2b26414a4e["1524c98619994e4fbb45bd2b26414a4e"];
Batcher/4eaedcde6c56467e8fd92a68b98fb057["Batcher/4eaedcde6c56467e8fd92a68b98fb057"];
Batcher/cc0c636b920b4dd1ba5000ccfdadf6de["Batcher/cc0c636b920b4dd1ba5000ccfdadf6de"];
Batcher/1524c98619994e4fbb45bd2b26414a4e["Batcher/1524c98619994e4fbb45bd2b26414a4e"];
ConcurrentEnd["ConcurrentEnd"];
fan_in::ConcurrentEnd::BAD20FD4((fan-in))
Start --> 4eaedcde6c56467e8fd92a68b98fb057;
Start --> cc0c636b920b4dd1ba5000ccfdadf6de;
Start --> 1524c98619994e4fbb45bd2b26414a4e;
4eaedcde6c56467e8fd92a68b98fb057 --> Batcher/4eaedcde6c56467e8fd92a68b98fb057;
cc0c636b920b4dd1ba5000ccfdadf6de --> Batcher/cc0c636b920b4dd1ba5000ccfdadf6de;
1524c98619994e4fbb45bd2b26414a4e --> Batcher/1524c98619994e4fbb45bd2b26414a4e;
Batcher/4eaedcde6c56467e8fd92a68b98fb057 --> fan_in::ConcurrentEnd::BAD20FD4;
Batcher/cc0c636b920b4dd1ba5000ccfdadf6de --> fan_in::ConcurrentEnd::BAD20FD4;
Batcher/1524c98619994e4fbb45bd2b26414a4e --> fan_in::ConcurrentEnd::BAD20FD4;
fan_in::ConcurrentEnd::BAD20FD4 --> ConcurrentEnd;
Issues:
- Three mysterious "Batcher" nodes appear between agents and the fan-in aggregator
- Each Batcher node has a GUID-based identifier (e.g., Batcher/4eaedcde6c56467e8fd92a68b98fb057)
- Doubles the visual complexity - what should be 3 agents + 1 aggregator becomes 3 agents + 3 batchers + 1 fan-in node
- No user-facing purpose - these appear to be internal implementation details
- Same issue as agent GUIDs - both problems compound to make diagrams nearly unreadable
Expected Behavior
Batcher nodes should be hidden from end-user visualizations or simplified into the fan-in aggregation node:
Option 1: Hide Batchers
flowchart TD
Start["Start"];
FrenchAgent["French Translation Agent"];
SpanishAgent["Spanish Translation Agent"];
EnglishAgent["English Translation Agent"];
ConcurrentEnd["Aggregator"];
Start --> FrenchAgent;
Start --> SpanishAgent;
Start --> EnglishAgent;
FrenchAgent --> ConcurrentEnd;
SpanishAgent --> ConcurrentEnd;
EnglishAgent --> ConcurrentEnd;
✅ Clean, understandable, shows only user-defined components
Option 2: Single Aggregation Node (Preferred)
flowchart TD
Start["Start"];
FrenchAgent["French Translation Agent"];
SpanishAgent["Spanish Translation Agent"];
EnglishAgent["English Translation Agent"];
FanIn((Fan-In Aggregator));
ConcurrentEnd["Output"];
Start --> FrenchAgent;
Start --> SpanishAgent;
Start --> EnglishAgent;
FrenchAgent --> FanIn;
SpanishAgent --> FanIn;
EnglishAgent --> FanIn;
FanIn --> ConcurrentEnd;
✅ Shows aggregation explicitly but keeps it simple
Option 3: Meaningful Names (If Must Show)
flowchart TD
Start["Start"];
FrenchAgent["French Translation Agent"];
SpanishAgent["Spanish Translation Agent"];
EnglishAgent["English Translation Agent"];
FrenchBatcher["French Output Batcher"];
SpanishBatcher["Spanish Output Batcher"];
EnglishBatcher["English Output Batcher"];
ConcurrentEnd["Aggregator"];
Start --> FrenchAgent;
Start --> SpanishAgent;
Start --> EnglishAgent;
FrenchAgent --> FrenchBatcher;
SpanishAgent --> SpanishBatcher;
EnglishAgent --> EnglishBatcher;
FrenchBatcher --> ConcurrentEnd;
SpanishBatcher --> ConcurrentEnd;
EnglishBatcher --> ConcurrentEnd;
Benefits:
- Clarity: Diagrams show only meaningful workflow components
- Simplicity: Reduced visual noise for complex workflows
- Professionalism: Diagrams are presentation-ready
- Consistency: Matches user expectations (no internal implementation leaking)
Root Cause Analysis (Hypothesis)
The "Batcher" executors appear to be an internal framework mechanism for:
- Managing concurrent agent execution and message distribution
- Collecting agent outputs before passing to fan-in aggregators
- Possibly handling streaming/buffering of agent responses
Possible reasons they appear in visualizations:
• Batchers are registered as graph nodes during workflow construction
• Visualization logic includes ALL executors without filtering internal ones
• No distinction between "user-facing" and "internal" executors
Why this is problematic:
• Leaks implementation details into user-facing API
• Makes abstraction layer transparent when it should be opaque
• Violates principle of least surprise
Workaround
Current workaround: None available. Developers must:
• Manually edit generated diagrams to remove Batcher nodes
• Ignore Batcher nodes when reading diagrams (confusing for new users)
• Avoid using workflow visualizations for documentation
