Advanced Routing¶
Advanced routing in SemanticKernel.Graph goes beyond simple conditional edges to provide intelligent, context-aware node selection using multiple strategies. This guide covers the sophisticated routing capabilities that enable dynamic, adaptive graph execution.
Overview¶
Advanced routing combines multiple strategies to make intelligent decisions about which node to execute next:
- Semantic Routing: Uses embeddings to find semantically similar nodes
- Content Similarity: Leverages execution history to find similar patterns
- Probabilistic Routing: Applies weighted random selection with dynamic weights
- Contextual Routing: Considers execution history patterns and transitions
- Feedback Learning: Adapts routing decisions based on user feedback
Core Components¶
AdvancedRoutingEngine¶
The main orchestrator that coordinates all routing strategies:
var advancedRoutingEngine = new AdvancedRoutingEngine(
embeddingService: embeddingService,
memoryService: memoryService,
options: new AdvancedRoutingOptions
{
EnableSemanticRouting = true,
EnableSimilarityRouting = true,
EnableProbabilisticRouting = true,
EnableContextualRouting = true,
EnableFeedbackLearning = true
}
);
DynamicRoutingEngine Integration¶
The DynamicRoutingEngine
automatically integrates advanced routing when embedding or memory services are available:
var routingEngine = new DynamicRoutingEngine(
templateEngine: null,
options: new DynamicRoutingOptions { EnableCaching = true, EnableFallback = true },
logger: logger,
embeddingService: embeddingService,
memoryService: memoryService
);
// Configure graph to use advanced routing
graph.RoutingEngine = routingEngine;
Routing Strategies¶
1. Semantic Routing Strategy¶
Uses text embeddings to find semantically similar nodes based on context:
public sealed class SemanticRoutingStrategy : IRoutingStrategy
{
public RoutingStrategyType Type => RoutingStrategyType.Semantic;
public double GetWeight() => 0.3; // High weight for semantic similarity
// Selects node based on embedding similarity
public async Task<RoutingStrategyResult?> SelectNodeAsync(
List<IGraphNode> candidates,
AdvancedRoutingContext context,
CancellationToken cancellationToken = default)
}
How it works: 1. Generates embedding for current execution context 2. Retrieves or creates embeddings for candidate nodes 3. Calculates cosine similarity between context and node embeddings 4. Selects node with highest similarity above threshold (default: 0.5)
Configuration:
var options = new AdvancedRoutingOptions
{
EnableSemanticRouting = true,
SemanticSimilarityThreshold = 0.7 // Adjustable threshold
};
2. Content Similarity Routing Strategy¶
Leverages execution history to find nodes that performed well in similar situations:
public sealed class ContentSimilarityRoutingStrategy : IRoutingStrategy
{
public RoutingStrategyType Type => RoutingStrategyType.Similarity;
public double GetWeight() => 0.25;
// Selects node based on historical success in similar contexts
public async Task<RoutingStrategyResult?> SelectNodeAsync(
List<IGraphNode> candidates,
AdvancedRoutingContext context,
CancellationToken cancellationToken = default)
}
How it works: 1. Analyzes similar executions from memory service 2. Calculates state similarity between current and historical executions 3. Identifies nodes with high frequency and success rates 4. Selects node with best combination of frequency and success rate
Requirements:
* IGraphMemoryService
implementation
* Similar executions in context (context.SimilarExecutions
)
3. Probabilistic Routing Strategy¶
Applies weighted random selection with dynamically adjusted weights:
public sealed class ProbabilisticRoutingStrategy : IRoutingStrategy
{
public RoutingStrategyType Type => RoutingStrategyType.Probabilistic;
public double GetWeight() => 0.2;
// Selects node using weighted random with dynamic weights
public async Task<RoutingStrategyResult?> SelectNodeAsync(
List<IGraphNode> candidates,
AdvancedRoutingContext context,
CancellationToken cancellationToken = default)
}
How it works: 1. Calculates dynamic weights based on historical performance 2. Applies decay factor to prevent over-reliance on old data 3. Normalizes weights and performs weighted random selection 4. Adapts weights based on execution confidence and recency
Configuration:
var options = new AdvancedRoutingOptions
{
EnableProbabilisticRouting = true,
ProbabilisticDecayFactor = 0.95, // Weight decay over time
MinimumConfidenceThreshold = 0.3 // Minimum confidence for selection
};
4. Contextual Routing Strategy¶
Considers execution history patterns and transition probabilities:
public sealed class ContextualRoutingStrategy : IRoutingStrategy
{
public RoutingStrategyType Type => RoutingStrategyType.Contextual;
public double GetWeight() => 0.15;
// Selects node based on historical transition patterns
public async Task<RoutingStrategyResult?> SelectNodeAsync(
List<IGraphNode> candidates,
AdvancedRoutingContext context,
CancellationToken cancellationToken = default)
}
How it works: 1. Analyzes routing history for current node 2. Calculates transition probabilities to candidate nodes 3. Considers success rates of historical transitions 4. Selects node with best historical performance pattern
Features: * Looks back at recent history (configurable limit) * Considers both frequency and success rate * Adapts to changing execution patterns
5. Feedback Learning Routing Strategy¶
Adapts routing decisions based on user feedback:
public sealed class FeedbackLearningRoutingStrategy : IRoutingStrategy
{
public RoutingStrategyType Type => RoutingStrategyType.FeedbackLearning;
public double GetWeight() => 0.1;
// Selects node based on feedback-adjusted scores
public async Task<RoutingStrategyResult?> SelectNodeAsync(
List<IGraphNode> candidates,
AdvancedRoutingContext context,
CancellationToken cancellationToken = default)
}
// Provides feedback to improve future routing
public async Task ProvideFeedbackAsync(string routingDecisionId,
RoutingFeedbackInfo feedbackInfo, CancellationToken cancellationToken = default)
}
How it works: 1. Calculates feedback-adjusted scores for candidates 2. Weights recent feedback more heavily 3. Selects node with highest feedback score 4. Continuously learns from user feedback
Feedback Types:
public enum RoutingFeedbackType
{
Positive, // Good routing decision
Negative, // Poor routing decision
Neutral, // Acceptable but not optimal
Correction // Explicit correction
}
Configuration and Options¶
AdvancedRoutingOptions¶
Comprehensive configuration for all routing strategies:
public sealed class AdvancedRoutingOptions
{
// Enable/disable individual strategies
public bool EnableSemanticRouting { get; set; } = true;
public bool EnableSimilarityRouting { get; set; } = true;
public bool EnableProbabilisticRouting { get; set; } = true;
public bool EnableContextualRouting { get; set; } = true;
public bool EnableFeedbackLearning { get; set; } = true;
// Thresholds and limits
public double SemanticSimilarityThreshold { get; set; } = 0.7;
public int HistoryLookbackLimit { get; set; } = 10;
public double MinimumConfidenceThreshold { get; set; } = 0.3;
// Learning and adaptation parameters
public double FeedbackLearningRate { get; set; } = 0.1;
public double ProbabilisticDecayFactor { get; set; } = 0.95;
}
Strategy Weights¶
Each strategy contributes to the final decision with configurable weights:
- Semantic: 0.3 (30%) - High weight for semantic understanding
- Similarity: 0.25 (25%) - Good weight for historical patterns
- Probabilistic: 0.2 (20%) - Balanced weight for exploration
- Contextual: 0.15 (15%) - Moderate weight for patterns
- Feedback: 0.1 (10%) - Lower weight for learning
Usage Examples¶
Basic Setup¶
// 1. Create kernel with embedding service
var kernelBuilder = Kernel.CreateBuilder();
kernelBuilder.AddTextEmbeddingGeneration("text-embedding-ada-002", "your-api-key");
var kernel = kernelBuilder.Build();
// 2. Create memory service (if available)
var memoryService = new GraphMemoryService(); // Your implementation
// 3. Create advanced routing engine
var advancedRoutingEngine = new AdvancedRoutingEngine(
embeddingService: kernel.GetRequiredService<ITextEmbeddingGenerationService>(),
memoryService: memoryService,
options: new AdvancedRoutingOptions
{
EnableSemanticRouting = true,
EnableSimilarityRouting = true,
EnableProbabilisticRouting = true,
EnableContextualRouting = true,
EnableFeedbackLearning = true
}
);
// 4. Configure graph with advanced routing
var graph = new GraphExecutor(kernel);
graph.RoutingEngine = new DynamicRoutingEngine(
embeddingService: kernel.GetRequiredService<ITextEmbeddingGenerationService>(),
memoryService: memoryService
);
Providing Feedback¶
// Get feedback strategy from routing engine
var feedbackStrategy = routingEngine.GetFeedbackStrategy();
// Provide feedback for a routing decision
await feedbackStrategy.ProvideFeedbackAsync(
routingDecisionId: "decision-123",
new RoutingFeedbackInfo
{
NodeId = "selected-node",
FeedbackType = RoutingFeedbackType.Positive,
Score = 0.9,
Comments = "Excellent routing decision",
Timestamp = DateTimeOffset.UtcNow
}
);
Custom Strategy Weights¶
// Override default strategy weights
var customOptions = new AdvancedRoutingOptions
{
EnableSemanticRouting = true,
EnableSimilarityRouting = true,
EnableProbabilisticRouting = false, // Disable probabilistic
EnableContextualRouting = true,
EnableFeedbackLearning = true,
// Adjust thresholds
SemanticSimilarityThreshold = 0.8, // Higher threshold
HistoryLookbackLimit = 20, // More history
MinimumConfidenceThreshold = 0.5 // Higher confidence required
};
Advanced Features¶
Routing Context¶
The AdvancedRoutingContext
provides rich information for routing decisions:
public sealed class AdvancedRoutingContext
{
public required string CurrentNodeId { get; init; }
public required string CurrentNodeName { get; init; }
public required GraphState GraphState { get; init; }
public FunctionResult? ExecutionResult { get; init; }
public required DateTimeOffset Timestamp { get; init; }
public required string ExecutionId { get; init; }
public required int ExecutionStep { get; init; }
public List<GraphExecutionMemory> SimilarExecutions { get; set; } = new();
public Random Random { get; init; } = new();
}
Strategy Aggregation¶
Multiple strategies contribute to the final decision:
// Results from different strategies
var routingResults = new List<RoutingStrategyResult>();
// Add results from enabled strategies
if (semanticResult != null) routingResults.Add(semanticResult);
if (similarityResult != null) routingResults.Add(similarityResult);
if (probabilisticResult != null) routingResults.Add(probabilisticResult);
if (contextualResult != null) routingResults.Add(contextualResult);
if (feedbackResult != null) routingResults.Add(feedbackResult);
// Aggregate and select final node
var finalResult = AggregateRoutingResults(routingResults, routingContext);
Routing History¶
Track and analyze routing decisions:
public sealed class RoutingHistory
{
public required string DecisionId { get; init; }
public required string CurrentNodeId { get; init; }
public required string SelectedNodeId { get; init; }
public required List<RoutingStrategyType> UsedStrategies { get; init; }
public required double FinalConfidence { get; init; }
public required DateTimeOffset Timestamp { get; init; }
public required string ContextSnapshot { get; init; }
}
Performance Considerations¶
Caching¶
The DynamicRoutingEngine
includes built-in caching:
var routingOptions = new DynamicRoutingOptions
{
EnableCaching = true,
MaxCacheSize = 1000,
CacheExpiration = TimeSpan.FromMinutes(30)
};
Memory Management¶
- Node embeddings are cached with TTL (24 hours default)
- Routing history uses concurrent dictionaries for thread safety
- Similar executions are limited by
HistoryLookbackLimit
Fallback Mechanisms¶
When advanced routing fails, fallback options ensure execution continues:
var routingOptions = new DynamicRoutingOptions
{
EnableFallback = true, // Always select a node
EnableCaching = true, // Cache decisions for performance
MaxCacheSize = 100 // Limit memory usage
};
Monitoring and Debugging¶
Routing Metrics¶
Track routing performance and decisions:
// Get routing metrics for specific node
var nodeMetrics = routingEngine.GetRoutingMetrics("node-id");
// Get all routing metrics
var allMetrics = routingEngine.GetRoutingMetrics();
Logging¶
Comprehensive logging for debugging routing decisions:
// Enable debug logging for routing
var logger = LoggerFactory.Create(builder =>
builder.SetMinimumLevel(LogLevel.Debug)
).CreateLogger<DynamicRoutingEngine>();
var routingEngine = new DynamicRoutingEngine(
logger: logger,
embeddingService: embeddingService,
memoryService: memoryService
);
Strategy Details¶
Each routing result includes detailed information about the decision:
var result = await routingEngine.SelectNextNodeAsync(candidates, currentNode, state);
// Access strategy details
foreach (var strategyResult in result.UsedStrategies)
{
var details = strategyResult.StrategyDetails;
// Process strategy-specific details
}
Best Practices¶
1. Service Availability¶
- Always check if required services are available before enabling strategies
- Provide fallback mechanisms when services are unavailable
- Use dependency injection for service management
2. Threshold Tuning¶
- Start with default thresholds and adjust based on your use case
- Monitor routing confidence scores to identify optimal thresholds
- Use feedback learning to automatically tune parameters
3. Memory Management¶
- Set appropriate limits for history lookback and cache sizes
- Monitor memory usage in production environments
- Implement cleanup policies for old routing data
4. Performance Monitoring¶
- Track routing decision latency
- Monitor cache hit rates
- Analyze strategy contribution patterns
5. Feedback Quality¶
- Provide consistent and meaningful feedback
- Use appropriate feedback types for different scenarios
- Regularly review and clean up feedback data
Troubleshooting¶
Common Issues¶
Low routing confidence: * Check if embedding service is working correctly * Verify memory service has relevant historical data * Adjust similarity thresholds
Slow routing decisions: * Enable caching for frequently accessed routes * Reduce history lookback limits * Optimize embedding generation
Inconsistent routing: * Check strategy weights and thresholds * Verify feedback data quality * Monitor routing history patterns
Debug Information¶
Enable detailed logging to diagnose routing issues:
// Enable debug logging
var logger = LoggerFactory.Create(builder =>
builder.SetMinimumLevel(LogLevel.Debug)
).CreateLogger<AdvancedRoutingEngine>();
// Check strategy results
var result = await routingEngine.SelectNextNodeAsync(candidates, currentNode, state);
Console.WriteLine($"Used strategies: {string.Join(", ", result.UsedStrategies)}");
Console.WriteLine($"Final confidence: {result.FinalConfidence:F3}");
See Also¶
- Conditional Nodes - Basic conditional routing
- Dynamic Routing - Template-based routing
- State Management - Graph state and context
- Memory and Templates - Memory services and templates
- Performance Metrics - Monitoring routing performance
Examples¶
- Advanced Routing Example - Complete demonstration
- Dynamic Routing Example - Template-based routing
- Multi-Agent Workflow - Complex routing scenarios