Main Node Types¶
This document covers the five main node types in SemanticKernel.Graph that provide the foundation for building complex workflows: FunctionGraphNode
, ConditionalGraphNode
, ReasoningGraphNode
, ReActLoopGraphNode
, and ObservationGraphNode
.
FunctionGraphNode¶
The FunctionGraphNode
encapsulates a Semantic Kernel function and provides graph-specific functionality around existing KernelFunction
instances.
Overview¶
This node forwards execution to an underlying KernelFunction
and augments it with graph-aware behavior including navigation, metadata hooks, and lifecycle management.
Key Features¶
- Function Encapsulation: Wraps any
KernelFunction
from Semantic Kernel - Navigation Support: Connect unconditional successors and conditional transitions
- Metadata Hooks: Custom setup, cleanup, and error handling logic
- Thread Safety: Connection lists are guarded by private locks for mutation
- Result Storage: Automatic storage of execution results in graph state
Metadata Hooks¶
The following metadata keys enable custom behavior:
"StoreResultAs"
(string): Stores the last result intoGraphState
under the given key"BeforeExecute"
(Action/Func): Custom setup logic executed inOnBeforeExecuteAsync
"AfterExecute"
(Action/Func): Custom cleanup logic executed inOnAfterExecuteAsync
"OnExecutionFailed"
(Action/Func): Error handling hook executed inOnExecutionFailedAsync
"StrictValidation"
(bool): If true, pre-execution validation failures cause an exception
Usage Examples¶
Basic Function Wrapping¶
// Create a function
var function = kernel.CreateFunctionFromMethod(
(string input) => $"Processed: {input}",
functionName: "process_input"
);
// Wrap in a graph node
var node = new FunctionGraphNode(function, "process_node")
.StoreResultAs("processed_result");
// Connect to next node
node.ConnectTo(nextNode);
From Plugin Function¶
// Create from plugin function
var node = FunctionGraphNode.FromPlugin(kernel, "math", "add")
.StoreResultAs("sum");
// Add conditional edge
node.AddConditionalEdge(new ConditionalEdge(
condition: state => state.GetValue<int>("sum") > 10,
targetNode: highValueNode
));
With Custom Metadata Hooks¶
var node = new FunctionGraphNode(function, "custom_node")
.StoreResultAs("result");
// Add custom lifecycle hooks
node.SetMetadata("BeforeExecute", (Action<KernelArguments>)(args => {
args["execution_start"] = DateTime.UtcNow;
}));
node.SetMetadata("AfterExecute", (Action<KernelArguments, FunctionResult>)((args, result) => {
args["execution_duration"] = DateTime.UtcNow - (DateTime)args["execution_start"];
}));
ConditionalGraphNode¶
The ConditionalGraphNode
implements conditional if/else logic based on graph state, evaluating conditions and routing execution to different paths without executing functions.
Overview¶
This node provides function-based and template-based conditions with advanced caching, debugging support, and comprehensive metrics tracking.
Key Features¶
- Function-based Conditions: Direct evaluation using
Func<GraphState, bool>
- Template-based Conditions: Handlebars-like templates with variable substitution
- Advanced Caching: Automatic cache of evaluation results for performance
- Debugging Support: Integration with
ConditionalDebugger
for step-by-step analysis - Metrics Tracking: Comprehensive execution metrics and performance monitoring
- Thread Safety: All operations are thread-safe for concurrent execution
Condition Types¶
Function-based Conditions¶
// Simple boolean condition
var conditionNode = new ConditionalGraphNode(
condition: state => state.GetValue<int>("score") > 80,
name: "High Score Check"
);
conditionNode.AddTrueNode(successNode);
conditionNode.AddFalseNode(retryNode);
Template-based Conditions¶
// Handlebars-like template
var templateNode = new ConditionalGraphNode(
conditionTemplate: "{{ gt score 0.8 }}",
name: "Score Threshold Check"
);
templateNode.AddTrueNode(successNode);
templateNode.AddFalseNode(retryNode);
Advanced Usage¶
Complex Conditions¶
var complexCondition = new ConditionalGraphNode(
condition: state => {
var score = state.GetValue<int>("score");
var attempts = state.GetValue<int>("attempts");
var maxAttempts = state.GetValue<int>("max_attempts");
return score >= 90 || attempts >= maxAttempts;
},
name: "Complex Decision Logic"
);
Multiple True/False Paths¶
var decisionNode = new ConditionalGraphNode(
condition: state => state.GetValue<string>("status") == "completed",
name: "Status Check"
);
// Multiple true paths
decisionNode.AddTrueNode(successNode);
decisionNode.AddTrueNode(notificationNode);
// Multiple false paths
decisionNode.AddFalseNode(retryNode);
decisionNode.AddFalseNode(errorHandlerNode);
ReasoningGraphNode¶
The ReasoningGraphNode
implements reasoning capabilities for analyzing current situations and planning next actions, designed to be used as part of the ReAct pattern for structured decision-making.
Overview¶
This node analyzes current context, evaluates available information, and generates structured reasoning about what action should be taken next using configurable prompt templates.
Key Features¶
- Context-aware Reasoning: Analyzes current situation and available data
- Template-based Prompts: Uses customizable templates for different reasoning patterns
- Quality Metrics: Tracks reasoning quality and consistency
- Domain Specialization: Can be configured for specific problem domains
- Chain-of-thought Support: Supports step-by-step reasoning patterns
Domain Specialization¶
The node supports predefined domains with specialized prompts:
// Create for specific domain
var mathReasoningNode = ReasoningGraphNode.CreateForDomain(
ReasoningDomain.Mathematics,
nodeId: "math_reasoning"
);
// Create for general reasoning
var generalReasoningNode = new ReasoningGraphNode(
reasoningPrompt: "Analyze the current situation and determine the next logical step.",
name: "General Reasoning"
);
Configuration Options¶
Metadata Configuration¶
var reasoningNode = new ReasoningGraphNode(
"Analyze the problem and plan the solution step by step.",
name: "Problem Analysis"
);
// Configure reasoning behavior
reasoningNode.SetMetadata("ChainOfThoughtEnabled", true);
reasoningNode.SetMetadata("MaxReasoningSteps", 5);
reasoningNode.SetMetadata("ConfidenceThreshold", 0.8);
reasoningNode.SetMetadata("Domain", "problem_solving");
Template Engine Integration¶
var templateEngine = new GraphTemplateEngine();
var reasoningNode = new ReasoningGraphNode(
"Current context: {{context}}\nProblem: {{problem}}\nPlan the next action:",
templateEngine: templateEngine
);
Usage in ReAct Patterns¶
// Create reasoning node for ReAct loop
var reasoningNode = new ReasoningGraphNode(
"Based on the current situation: {{situation}}\n" +
"Available actions: {{available_actions}}\n" +
"What should be the next action?",
name: "ReAct Reasoning"
);
// Configure for iterative reasoning
reasoningNode.SetMetadata("MaxReasoningSteps", 3);
reasoningNode.SetMetadata("ConfidenceThreshold", 0.7);
ReActLoopGraphNode¶
The ReActLoopGraphNode
orchestrates the complete ReAct (Reasoning + Acting) pattern loop, coordinating reasoning, action execution, and observation in iterative cycles until goal achievement.
Overview¶
This node implements the full ReAct pattern by orchestrating reasoning, acting, observation, and loop control in a coordinated manner with configurable limits and sophisticated goal evaluation.
Key Features¶
- Complete ReAct Orchestration: Manages the full reasoning-acting-observation cycle
- Flexible Node Composition: Can use custom reasoning, action, and observation nodes
- Iteration Limits: Configurable maximum iterations with early termination
- Goal Evaluation: Sophisticated goal achievement detection
- Performance Tracking: Comprehensive metrics and timing information
- Error Handling: Robust error handling with recovery strategies
- Context Management: Maintains and updates context across iterations
Component Configuration¶
Basic Setup¶
var reactLoopNode = new ReActLoopGraphNode(
nodeId: "react_loop",
name: "ReAct Problem Solver"
);
// Configure component nodes
reactLoopNode.ConfigureNodes(
reasoningNode, // Analyze and plan
actionNode, // Execute actions
observationNode // Observe results
);
Factory Method¶
var reactLoopNode = ReActLoopGraphNode.CreateWithNodes(
reasoningNode: reasoningNode,
actionNode: actionNode,
observationNode: observationNode,
nodeId: "react_loop"
);
Configuration Options¶
Loop Behavior¶
// Configure iteration limits
reactLoopNode.SetMetadata("MaxIterations", 10);
reactLoopNode.SetMetadata("IterationTimeout", TimeSpan.FromMinutes(5));
reactLoopNode.SetMetadata("TotalTimeout", TimeSpan.FromMinutes(30));
// Configure goal achievement
reactLoopNode.SetMetadata("GoalAchievementThreshold", 0.95);
reactLoopNode.SetMetadata("EarlyTerminationEnabled", true);
Performance Tracking¶
// Enable comprehensive metrics
reactLoopNode.SetMetadata("TrackMetrics", true);
reactLoopNode.SetMetadata("TrackTiming", true);
reactLoopNode.SetMetadata("TrackIterations", true);
Metadata Keys¶
Counters (int)¶
"ExecutionCount"
: Total number of executions"FailureCount"
: Number of failed executions"SuccessfulCompletions"
: Number of successful completions"TotalIterations"
: Total iterations across all executions
Metrics¶
"AverageExecutionTime"
: Average time per execution"AverageIterationsPerExecution"
: Average iterations per execution"SuccessRate"
: Success rate percentage"LastExecutedAt"
: Timestamp of last execution
Configuration¶
"MaxIterations"
: Maximum iterations per execution"GoalAchievementThreshold"
: Threshold for goal achievement"EarlyTerminationEnabled"
: Whether to enable early termination"IterationTimeout"
: Timeout per iteration"TotalTimeout"
: Total timeout for execution"Domain"
: Domain-specific configuration
ObservationGraphNode¶
The ObservationGraphNode
implements observation and analysis capabilities for the ReAct pattern, analyzing action results, extracting insights, and determining if goals have been achieved.
Overview¶
This node analyzes the results of executed actions, evaluates their success, extracts relevant information, and determines the next steps in the reasoning cycle.
Key Features¶
- Result Analysis: Deep analysis of action execution results
- Goal Evaluation: Determines if objectives have been met
- Information Extraction: Extracts key insights and data from results
- Quality Assessment: Evaluates the quality and relevance of results
- Context Update: Updates context for next reasoning iteration
- Decision Making: Determines whether to continue or conclude the ReAct loop
Domain Specialization¶
// Create for specific domain
var mathObservationNode = ObservationGraphNode.CreateForDomain(
ObservationDomain.Mathematics,
nodeId: "math_observation"
);
// Create for general observation
var generalObservationNode = new ObservationGraphNode(
observationPrompt: "Analyze the action result and determine if the goal was achieved.",
name: "General Observation"
);
Configuration Options¶
Analysis Behavior¶
var observationNode = new ObservationGraphNode(
"Analyze the result: {{result}}\nGoal: {{goal}}\nWas the goal achieved?",
name: "Result Analysis"
);
// Configure observation behavior
observationNode.SetMetadata("DeepAnalysisEnabled", true);
observationNode.SetMetadata("GoalAchievementThreshold", 0.9);
observationNode.SetMetadata("ExtractionPatterns", new[] { "result", "insight", "next_step" });
Template Engine Integration¶
var templateEngine = new GraphTemplateEngine();
var observationNode = new ObservationGraphNode(
"Result: {{action_result}}\n" +
"Expected: {{expected_result}}\n" +
"Analysis: {{analysis_request}}",
templateEngine: templateEngine
);
Metadata Keys¶
Counters (int)¶
"ExecutionCount"
: Total number of executions"FailureCount"
: Number of failed executions"GoalAchievedCount"
: Number of times goals were achieved
Metrics¶
"AverageExecutionTime"
: Average time per execution"GoalAchievementRate"
: Rate of goal achievement"AverageSuccessAssessment"
: Average success assessment score"LastExecutedAt"
: Timestamp of last execution
Configuration¶
"Domain"
: Domain-specific configuration"DeepAnalysisEnabled"
: Whether to perform deep analysis"GoalAchievementThreshold"
: Threshold for goal achievement
Behavior Customization¶
"ExtractionPatterns"
: Patterns for information extraction"ResultTypePatterns"
: Patterns for result type analysis"GoalCriteria"
: Criteria for goal evaluation
Integration Patterns¶
Building a Complete ReAct Workflow¶
// 1. Create component nodes
var reasoningNode = new ReasoningGraphNode(
"Analyze the problem: {{problem}}\nPlan the solution:",
name: "Problem Analysis"
);
var actionNode = new ActionGraphNode(kernel, "action_execution");
var observationNode = new ObservationGraphNode(
"Analyze result: {{action_result}}\nGoal achieved?",
name: "Result Analysis"
);
// 2. Create and configure ReAct loop
var reactLoopNode = new ReActLoopGraphNode(
nodeId: "complete_react_workflow"
);
reactLoopNode.ConfigureNodes(reasoningNode, actionNode, observationNode);
// 3. Configure loop behavior
reactLoopNode.SetMetadata("MaxIterations", 5);
reactLoopNode.SetMetadata("GoalAchievementThreshold", 0.9);
reactLoopNode.SetMetadata("EarlyTerminationEnabled", true);
// 4. Add to executor
executor.AddNode(reactLoopNode);
executor.SetStartNode(reactLoopNode);
Conditional Routing with Function Nodes¶
// Create function nodes
var processNode = new FunctionGraphNode(processFunction, "process")
.StoreResultAs("processed_result");
var validateNode = new FunctionGraphNode(validateFunction, "validate")
.StoreResultAs("validation_result");
// Create conditional routing
var qualityCheck = new ConditionalGraphNode(
condition: state => state.GetValue<double>("quality_score") > 0.8,
name: "Quality Check"
);
qualityCheck.AddTrueNode(highQualityNode);
qualityCheck.AddFalseNode(improvementNode);
// Connect the workflow
processNode.ConnectTo(validateNode);
validateNode.ConnectTo(qualityCheck);
Performance Considerations¶
Caching and Optimization¶
- Conditional Nodes: Use template-based conditions for complex logic to leverage caching
- Function Nodes: Enable result storage only when needed to avoid memory overhead
- ReAct Loops: Set appropriate iteration limits and timeouts to prevent infinite loops
Memory Management¶
- Metadata: Use metadata sparingly for configuration; avoid storing large objects
- State: Leverage
StoreResultAs
for important results rather than storing everything - Connections: Minimize the number of conditional edges for better performance
Monitoring and Debugging¶
- Metrics: Enable metrics tracking for performance-critical nodes
- Logging: Use the built-in logging capabilities for debugging complex workflows
- Validation: Implement proper validation to catch issues early
Related Types¶
- IGraphNode: Base interface for all graph nodes
- GraphState: Wrapper around KernelArguments with execution metadata
- ConditionalEdge: Defines conditional transitions between nodes
- ActionGraphNode: Specialized node for executing actions
- GraphExecutor: Orchestrates the execution of graph workflows
See Also¶
- Node Types - Comprehensive overview of available node implementations
- Execution Model - How nodes participate in execution
- ReAct Pattern - Understanding the ReAct reasoning pattern
- Conditional Nodes - Building conditional workflows
- Getting Started - Building your first graph