Chapter 11: The Planner Concept - Auto-Orchestration
Theoretical Foundations
The Planner is the cognitive engine that bridges the gap between ambiguous user intent and deterministic machine execution. It represents the shift from imperative programming (telling the system exactly how to do something) to declarative goal-seeking (telling the system what to achieve). In the context of Microsoft Semantic Kernel, the Planner is not merely a prompt engineering trick; it is a structured orchestration mechanism that leverages Large Language Models (LLMs) to reason about available capabilities and construct a valid execution path.
The Core Problem: The Semantic Gap
To understand the Planner, we must first understand the Semantic Gap. In traditional software engineering, the gap is between high-level business requirements and low-level binary instructions. In AI Engineering, the gap is between unstructured natural language and structured function calls.
Consider a user request: "Book a flight to Paris for next Tuesday, but only if the weather is good, and email the itinerary to my assistant."
Temporal reasoning: What is "next Tuesday" in DateTime terms?
2. External data retrieval: What is the weather forecast?
3. Conditional logic: if (weather.IsGood) then bookFlight else skip.
4. Plugin invocation: Call the FlightBookingPlugin and EmailPlugin.
5. Data flow: Pass the output of the booking (confirmation code) to the input of the emailer.
The Planner exists to close this gap. It acts as a compiler for natural language, translating a goal into an intermediate representation (a plan) that can be executed by the Kernel.
The Analogy: The Master Chef and the Sous-Chef
Imagine a Master Chef (the Planner) working in a kitchen (the Semantic Kernel). The Master Chef receives a vague order from a customer: "I want a comforting dinner that reminds me of Italy."
Sous-Chef A: Expert in pasta (PastaSkill). * Sous-Chef B: Expert in roasting meats (RoastSkill). * Sous-Chef C: Expert in salads (SaladSkill). * Sous-Chef D: Manages the pantry (InventorySkill).
Interpretation: The Master Chef analyzes the request. "Comforting" and "Italy" strongly suggest pasta (Carbonara or Bolognese). 2. Capability Matching: The Master Chef reviews the team's skills. Sous-Chef A is the only one capable of making pasta. 3. Parameter Resolution: The Master Chef checks the pantry (InventorySkill). Do we have eggs, cheese, and guanciale? If not, a shopping trip is added to the plan. 4. Sequencing: The Master Chef dictates the order: "First, check inventory. If ingredients are missing, go shopping. Then, boil water. Then, cook the sauce."
The Plan Adaptation Process:
If the customer later says, "Actually, I'm vegetarian now," the Master Chef doesn't start from scratch. They take the existing plan (Pasta -> Carbonara) and adapt it. They swap the PastaSkill configuration to use mushrooms instead of meat, while keeping the sequence (Boil water -> Cook sauce) intact.
Theoretical Foundations
In Semantic Kernel, the Planner operates on three fundamental pillars: Function Selection, Parameter Resolution, and Plan Synthesis.
1. Function Selection (The "What")
When a goal is received, the Planner must determine which available functions (native code or semantic prompts) are relevant. This is not a simple string match. It involves semantic embedding comparison.
Why this matters: This allows for fuzzy matching. If a user asks to "send a message," the Planner might select a function described as "EmailSender" or "SlackNotifier" based on semantic proximity, even if the exact words don't match.
2. Parameter Resolution (The "How")
Explicit Parameters: Derived directly from the user's prompt (e.g., Destination: "Paris").
* Implicit Parameters: Derived from context or previous steps. If Step 1 outputs a FlightConfirmationCode, and Step 2 requires a ReferenceNumber, the Planner infers the connection.
* Missing Parameters: If a required parameter is missing (e.g., the user didn't specify a date), the Planner can either:
1. Hallucinate a default (risky).
2. Query the user (interactive mode).
3. Search memory (if the user previously stored "I prefer window seats").
3. Plan Synthesis (The "Structure")
The output of the Planner is a structured plan object. In older versions of Semantic Kernel, this was often a sequence of JSON steps. In modern implementations using Auto-Orchestration, the plan is often represented as a chain of function calls or even a generated script.
The synthesis must respect dependencies. You cannot SendEmail before you GenerateItinerary. The Planner builds a Directed Acyclic Graph (DAG) of execution.
Visualizing the Auto-Orchestration Flow
The following diagram illustrates how a user goal flows through the Planner, interacts with the Kernel's plugin registry, and results in an executable plan.
Zero-Shot Planning vs. Plan Adaptation
The distinction between these two modes is critical for building robust AI applications.
Zero-Shot Planning
Mechanism: The Planner sends a prompt to the LLM containing the user goal and a list of available function signatures. The LLM generates the plan in a specific format (e.g., XML or JSON). * Pros: Highly flexible; handles new scenarios dynamically. * Cons: Higher latency; higher token cost; higher risk of logical errors (e.g., selecting the wrong tool).
Plan Adaptation
Mechanism: The Planner loads a saved plan (a sequence of steps) and compares it to the new goal. It identifies which steps are still valid and which need to be swapped or reconfigured. * Pros: Faster (less LLM inference required); more reliable (builds on known-good sequences). * Cons: Less flexible; requires a library of saved plans or a history of successful executions.
Architectural Implications in C
From a C# architectural perspective, the Planner is implemented as a service that consumes the IKernel instance. It leverages modern C# features to manage the complexity of dynamic invocation.
The Role of Interfaces and Generics
The Planner does not hardcode specific plugin types. Instead, it uses interfaces like ISKFunction. This is crucial for modularity. Whether a function is a Semantic Function (prompt-based) or a Native Function (C# method), the Planner treats them uniformly.
// Conceptual representation of how the Planner interfaces with the Kernel
public interface IPlanner
{
// Generates a plan for a given goal
Task<Plan> CreatePlanAsync(string goal);
// Adapts an existing plan to a new goal
Task<Plan> AdaptPlanAsync(Plan existingPlan, string newGoal);
}
// The Planner relies on the Kernel's ability to retrieve functions
public interface IKernel
{
// Returns a collection of all registered functions (plugins)
IEnumerable<ISKFunction> GetAllFunctions();
// Executes a specific function
Task<FunctionResult> RunAsync(string pluginName, string functionName, params object[] args);
}
The Plan Class as a Data Structure
In modern Semantic Kernel, the Plan is not just a string; it is a first-class object that can be serialized, stored, and resumed. It represents the state of the orchestration.
// Simplified conceptual structure of a Plan object
public class Plan
{
public string Goal { get; set; }
public List<PlanStep> Steps { get; set; }
public Dictionary<string, object> State { get; set; } // Context variables
}
public class PlanStep
{
public string PluginName { get; set; }
public string FunctionName { get; set; }
public Dictionary<string, object> Parameters { get; set; }
}
The "Why": Navigating the Combinatorial Explosion
Why do we need a Planner? Why not just chain functions manually in code?
Without a Planner: A developer must write if/else logic for every possible user request.
if (userWantsToBookFlight) { ... }
else if (userWantsToBookHotel) { ... }
else if (userWantsToBookFlightAndHotel) { ... }
FlightBookingPlugin and HotelBookingPlugin. The Planner dynamically reasons that if the user says "book a trip," it should invoke both (or ask for clarification). The Planner handles the logic of invoking the functions, allowing the developer to focus on the implementation of the functions.
Ambiguity Resolution: If two plugins have equal semantic similarity, the Planner must use heuristics (e.g., prefer plugins with fewer required parameters, or those used most frequently) or ask the user for disambiguation. 2. Recursive Planning: Sometimes a step in a plan requires a sub-plan. For example, "Prepare a dinner party" might require a sub-plan for "Cooking the main course." A robust Planner supports hierarchical decomposition. 3. Failure Recovery: If a step in the generated plan fails (e.g., an API is down), the Planner can be invoked to re-plan around the failure, substituting the failed function with an alternative.
Summary
The Planner is the heart of auto-orchestration. It transforms the Semantic Kernel from a simple function caller into a reasoning agent. By utilizing semantic matching for function selection and dependency analysis for sequencing, it allows C# applications to handle complex, multi-step workflows that adapt to user intent dynamically. It is the mechanism that allows software to move from following a rigid script to navigating a map of possibilities.
Basic Code Example
Here is a basic code example demonstrating the Planner concept in Microsoft Semantic Kernel.
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Planning;
using Microsoft.SemanticKernel.Skills.Core;
using System;
using System.Threading.Tasks;
// Context: A user wants to plan a simple meal for dinner.
// Problem: The user has a vague goal ("plan a dinner") but needs the AI to orchestrate
// specific skills (fetching a recipe and generating a shopping list) to achieve it.
// Solution: Use the SequentialPlanner to automatically generate a plan using available plugins.
public class Program
{
public static async Task Main(string[] args)
{
// 1. Initialize the Kernel
var kernel = new KernelBuilder()
.WithAzureChatCompletionService(
deploymentName: "gpt-35-turbo", // Replace with your deployment name
endpoint: "https://your-endpoint.openai.azure.com/", // Replace with your endpoint
apiKey: "your-api-key") // Replace with your API key
.Build();
// 2. Register Native Functions as Skills/Plugins
// We are using the built-in TextSkill for demonstration, but in a real scenario,
// these would be custom functions (e.g., GetRecipeFromDatabase, GenerateShoppingList).
var textSkill = kernel.ImportSkill(new TextSkill(), "text");
// 3. Define the Goal
// The planner will interpret this natural language string and map it to the available functions.
string goal = "Write a haiku about a cat, then capitalize it, and finally reverse the text.";
try
{
// 4. Create the Planner
// SequentialPlanner creates a step-by-step plan to achieve the goal.
var planner = new SequentialPlanner(kernel);
// 5. Generate the Plan
// The planner queries the LLM to determine which functions to call and in what order.
var plan = await planner.CreatePlanAsync(goal);
Console.WriteLine("Generated Plan:");
Console.WriteLine(plan.ToJson());
Console.WriteLine("--------------------------------------------------");
// 6. Execute the Plan
// The kernel executes the generated plan step-by-step.
var result = await kernel.RunAsync(plan);
Console.WriteLine("Execution Result:");
Console.WriteLine(result.Result);
}
catch (Exception ex)
{
Console.WriteLine($"An error occurred: {ex.Message}");
}
}
}
Initialization of the Kernel:
Registration of Native Functions (Skills):
Defining the Goal:
Creating the Planner:
Generating the Plan:
Executing the Plan:
Finally, kernel.RunAsync(plan) takes the generated plan and executes it. The Kernel iterates through the steps, passing the output of one function as the input to the next (chaining). The final result is aggregated and returned. In this specific example, the output is the transformed text resulting from the sequence of operations defined by the Planner.
Missing Function Descriptions:
Circular Dependencies or Infinite Loops:
Parameter Mismatch:
Azure/OpenAI Configuration Errors:
A frequent mistake is incorrect configuration of the WithAzureChatCompletionService. Using the wrong deployment name or mixing up endpoint URLs (e.g., using a completion endpoint instead of a chat completion endpoint) will result in authentication errors or model not found exceptions. Always double-check your Azure AI Studio or OpenAI dashboard settings.
The chapter continues with advanced code, exercises and solutions with analysis, you can find them on the ebook on Leanpub.com or Amazon
Loading knowledge check...
Code License: All code examples are released under the MIT License. Github repo.
Content Copyright: Copyright © 2026 Edgar Milvus | Privacy & Cookie Policy. All rights reserved.
All textual explanations, original diagrams, and illustrations are the intellectual property of the author. To support the maintenance of this site via AdSense, please read this content exclusively online. Copying, redistribution, or reproduction is strictly prohibited.