How to build a graph¶
This guide explains the fundamental steps for creating and configuring graphs in SemanticKernel.Graph. You'll learn how to define nodes, connect them with conditional edges, and execute the resulting workflow.
Overview¶
Building a graph involves several key steps:
- Create and configure a
Kernel
with the necessary plugins and functions - Define nodes (functions, conditionals, loops) that represent your workflow steps
- Connect nodes with conditional edges that control execution flow
- Execute with
GraphExecutor
to run the complete workflow
Step-by-Step Process¶
1. Create and Configure Kernel¶
Start by creating a Semantic Kernel instance and adding the required plugins:
using Microsoft.SemanticKernel;
using SemanticKernel.Graph.Core;
using SemanticKernel.Graph.Extensions;
var builder = Kernel.CreateBuilder();
builder.AddOpenAIChatCompletion("gpt-4", "your-api-key");
builder.AddPluginFromObject(new PlannerPlugin(), "Planner");
builder.AddPluginFromObject(new AnalyzerPlugin(), "Analyzer");
builder.AddPluginFromObject(new ExecutorPlugin(), "Executor");
var kernel = builder.Build();
2. Define Graph Nodes¶
Create nodes that represent different steps in your workflow:
// Function nodes that execute kernel functions
var planNode = new FunctionGraphNode(
kernel.GetFunction("Planner", "Plan"),
nodeId: "plan"
);
var analyzeNode = new FunctionGraphNode(
kernel.GetFunction("Analyzer", "Analyze"),
nodeId: "analyze"
);
var actNode = new FunctionGraphNode(
kernel.GetFunction("Executor", "Act"),
nodeId: "act"
);
// Conditional node for branching logic
var decisionNode = new ConditionalGraphNode(
predicate: state => state.GetString("needs_analysis") == "yes",
nodeId: "decision"
);
3. Connect Nodes with Edges¶
Define the flow between nodes using conditional edges:
var graph = new GraphExecutor("workflow-graph", "Complete workflow with analysis");
// Add nodes to the graph
graph.AddNode(planNode)
.AddNode(decisionNode)
.AddNode(analyzeNode)
.AddNode(actNode);
// Connect nodes with conditional logic
graph.AddEdge(planNode, decisionNode)
.AddConditionalEdge(decisionNode, analyzeNode,
condition: state => state.GetString("needs_analysis") == "yes")
.AddConditionalEdge(decisionNode, actNode,
condition: state => state.GetString("needs_analysis") != "yes")
.AddEdge(analyzeNode, actNode);
// Set the starting point
graph.SetStartNode("plan");
4. Execute the Graph¶
Run the complete workflow:
// Prepare execution arguments
var arguments = new KernelArguments
{
["input"] = "Process this data",
["needs_analysis"] = "yes"
};
// Execute the graph
var executor = new GraphExecutor(graph);
var result = await executor.ExecuteAsync(kernel, arguments);
Console.WriteLine($"Result: {result.GetValue<string>()}");
Alternative Builder Pattern¶
For simpler graphs, you can use the fluent builder pattern:
var graph = GraphBuilder.Create()
.AddFunctionNode("plan", kernel, "Planner", "Plan")
.When(state => state.GetString("needs_analysis") == "yes")
.AddFunctionNode("analyze", kernel, "Analyzer", "Analyze")
.AddFunctionNode("act", kernel, "Executor", "Act")
.Build();
Advanced Patterns¶
Conditional Execution¶
Use conditional edges to create complex branching logic:
graph.AddConditionalEdge("start", "branch_a",
condition: state => state.GetInt("priority") > 5)
.AddConditionalEdge("start", "branch_b",
condition: state => state.GetInt("priority") <= 5);
Loop Control¶
Implement loops with iteration limits:
var loopNode = new WhileGraphNode(
condition: state => state.GetInt("attempt") < 3,
maxIterations: 5,
nodeId: "retry_loop"
);
graph.AddNode(loopNode)
.AddEdge("start", "retry_loop")
.AddEdge("retry_loop", "process");
Error Handling¶
Add error handling nodes to your workflow:
var errorHandler = new ErrorHandlerGraphNode(
errorTypes: new[] { ErrorType.Transient, ErrorType.External },
recoveryAction: RecoveryAction.Retry,
maxRetries: 3,
nodeId: "error_handler"
);
graph.AddNode(errorHandler)
.AddEdge("process", "error_handler")
.AddEdge("error_handler", "fallback");
Best Practices¶
Node Design¶
- Single Responsibility: Each node should have one clear purpose
- Meaningful Names: Use descriptive node IDs that explain their function
- State Management: Design nodes to work with the graph state effectively
- Error Handling: Include error handling nodes for robust workflows
Graph Structure¶
- Logical Flow: Organize nodes in a logical sequence
- Conditional Logic: Use conditional edges for dynamic routing
- Loop Prevention: Set appropriate iteration limits to prevent infinite loops
- Start Node: Always define a clear starting point
Performance Considerations¶
- Node Efficiency: Optimize individual node performance
- State Size: Keep graph state manageable for memory efficiency
- Parallel Execution: Use parallel nodes where possible for better performance
- Caching: Implement caching for expensive operations
Troubleshooting¶
Common Issues¶
Graph not executing: Ensure you've set a start node with SetStartNode()
Nodes not connected: Verify all edges are properly defined with AddEdge()
or AddConditionalEdge()
Infinite loops: Check loop conditions and set appropriate maxIterations
State not persisting: Use GraphState
for persistent state across nodes
Debugging Tips¶
- Enable logging to trace execution flow
- Use breakpoints in conditional logic
- Inspect state at each node execution
- Validate graph integrity before execution
Concepts and Techniques¶
GraphExecutor: The main class responsible for executing graph workflows. It manages node execution order, state transitions, and error handling throughout the workflow lifecycle.
FunctionGraphNode: A graph node that wraps and executes Semantic Kernel functions. It handles input/output mapping between the graph state and the underlying kernel function.
ConditionalGraphNode: A node that evaluates predicates to determine execution flow. It enables dynamic routing based on the current state of the graph.
ConditionalEdge: A connection between nodes that includes a condition for execution. It allows for complex branching logic and dynamic workflow paths.
GraphState: A wrapper around KernelArguments that provides additional metadata, execution history, and validation capabilities for graph workflows.
See Also¶
- First Graph in 5 Minutes - Quick start guide for building your first graph
- Conditional Nodes - Learn about branching and conditional execution
- Loops - Implement iterative workflows with loop nodes
- State Management - Understand how to manage data flow between nodes
- Graph Execution - Learn about the execution lifecycle and flow control
- Examples: Basic Graph Building - Complete working examples of graph construction