Semantic Kernel Planners
Planners in Semantic Kernel enable AI systems to automatically determine how to accomplish a goal by selecting and sequencing the appropriate functions from available plugins. Instead of manually scripting every step, you give the planner a high‑level objective; it discovers the necessary tools, generates a step‑by‑step plan, and executes it—handling dependencies, error recovery, and result aggregation along the way. This article is a practical, implementation‑focused guide to building and using planners: you’ll learn how they work, how to configure them, how to debug their output, and how to apply planning patterns in production.
What Are Planners in Semantic Kernel
A planner is a component that takes a user’s goal (expressed in natural language), inspects the kernel’s available functions, and produces a plan—an ordered list of function calls—to achieve that goal. The kernel then executes the plan, calling each function in sequence and feeding outputs into subsequent steps.
Think of the planner as an AI orchestration engine: it reasons about what needs to be done and in which order, using the same underlying language model to generate a blueprint for the workflow.
A simple example:
- Goal: “Summarize the latest news about AI agents and send it to me by email.”
- Available plugins:
NewsPlugin(search news),SummarizationPlugin(summarize text),EmailPlugin(send email). - Planner output: a plan that calls
NewsPlugin.search("AI agents"), thenSummarizationPlugin.summarize(…), thenEmailPlugin.send(to, subject, body).
In code, using a FunctionCallingStepwisePlanner:
from semantic_kernel.planners import FunctionCallingStepwisePlanner, FunctionCallingStepwisePlannerOptions
planner = FunctionCallingStepwisePlanner(
kernel=kernel,
options=FunctionCallingStepwisePlannerOptions(max_iterations=10)
)
goal = "Summarize the latest AI agent news and email it to user@example.com"
result = await planner.invoke(goal)
print(result.final_answer)
The planner automatically figures out the sequence and invokes the functions—no manual wiring needed.
Why Planning Matters
- Complex task execution – real‑world requests often span multiple domains; a planner can decompose them into a chain of simple function calls.
- Dynamic decision making – the plan can adapt based on intermediate results (e.g., if a search returns no results, the planner may try a different query).
- Reduced manual orchestration – you don’t need to hard‑code every possible workflow; the planner assembles them on the fly.
- Flexible workflows – adding a new plugin instantly makes it available to the planner without changing existing orchestration logic.
- Improved automation – planners enable agents that can handle novel tasks not anticipated during development.
What Is AI Planning
AI planning in Semantic Kernel is the process of transforming a high‑level goal into executable steps:
Goal → Steps → Function Calls → Results
The planner is not a static script generator; it’s an LLM‑powered reasoner that interacts with the kernel at runtime. It can iterate, ask for clarifications, and even generate new sub‑goals.
Core Planner Concepts
| Concept | Purpose |
|---|---|
| Goal | The user’s high‑level objective, expressed in natural language. |
| Plan | An ordered sequence of steps (function calls) to achieve the goal. |
| Step | A single action – a call to a specific function with concrete arguments. |
| Function Selection | The process of matching the goal to the most relevant available functions. |
| Execution Engine | The Kernel, which runs each step, handles errors, and manages context. |
The planner relies on function metadata (descriptions, parameter schemas) to reason about capabilities, just as a developer would read API documentation.
How Semantic Kernel Planning Works
Planners integrate directly into the Kernel’s execution loop. A typical invocation follows this flow:
- Function Discovery – the planner asks the Kernel for all registered functions, complete with names, descriptions, and parameter schemas.
- Plan Generation – the planner uses an LLM to reason about the goal, the available functions, and the necessary steps. It outputs a structured plan (e.g., JSON list of function calls).
- Execution – the planner iterates through the steps. For each, it invokes the function via the Kernel, captures the result, and feeds it as context for subsequent steps.
- Re‑planning (if needed) – if a step fails or the result indicates a different path is needed, the planner can dynamically adjust the remaining plan.
The modern FunctionCallingStepwisePlanner implements this using the LLM’s native function‑calling capability, making it extremely reliable and transparent.
Planner Lifecycle
From goal to completion, every plan passes through these stages:
- Goal definition – The user provides a natural‑language objective.
- Function discovery – The planner scans the kernel’s plugin registry.
- Plan generation – The LLM produces an initial plan (a list of function calls with arguments).
- Step sequencing – The planner orders the steps, ensuring dependencies are respected.
- Execution – The kernel runs each step, passing outputs as context.
- Result collection – Intermediate results are captured; the planner may adjust subsequent steps.
- Completion – Once all steps are executed (or the LLM determines the goal is achieved), the final answer is assembled.
Types of Planning
Semantic Kernel offers different planning strategies to suit various use cases.
Sequential Planning
A linear chain of steps executed one after another. The classic SequentialPlanner generates a simple, non‑branching plan.
Use when: The task is a known pipeline (e.g., search → summarize → send).
from semantic_kernel.planners import SequentialPlanner
planner = SequentialPlanner(kernel, ...)
plan = await planner.create_plan(goal)
result = await plan.invoke(kernel)
Conditional Planning
The plan branches based on runtime conditions. Achieved by the FunctionCallingStepwisePlanner, which can re‑evaluate the next step after each function call. For example, “If the invoice amount is > $1000, request manager approval; otherwise, process payment.” The planner includes a “condition” step that checks the output and decides the next action.
Dynamic Planning
Plans are generated entirely at runtime, with no predefined script. The FunctionCallingStepwisePlanner exemplifies this: it doesn’t output a full plan upfront but iteratively decides the next step based on the accumulated results. This is the most flexible and recommended for complex, open‑ended tasks.
Iterative Planning
Plans that involve loops, refinements, or repeated steps until a condition is met. For instance, “generate a draft, review it; if quality < 8, revise; else publish.” The planner uses a loop counter and a condition check (often implemented as a native function that returns a boolean).
Function Selection
A critical step: the planner must match the goal to the correct functions. It relies entirely on metadata:
- Function name – should be descriptive (e.g.,
SearchNews). - Description – a concise, natural‑language summary of what the function does.
- Parameter descriptions – for each input, clear and detailed.
The LLM receives a system message that lists all available functions in a JSON‑schema format. It uses its language understanding to infer which functions are relevant.
Example metadata:
class NewsPlugin:
@kernel_function(
name="SearchNews",
description="Search the latest news articles for a given query."
)
def search(self, query: Annotated[str, "The search query, e.g., 'AI agents'"]) -> str:
...
If the description is vague or missing, the planner may skip the function entirely or misuse it. Invest in good documentation.
Plan Generation
The planner creates the actual sequence of steps. In SequentialPlanner, this is a single LLM call that returns a list of Plan steps. Each step specifies:
- The plugin and function name.
- The arguments, derived from the goal and previous steps’ outputs.
In FunctionCallingStepwisePlanner, the LLM generates the plan incrementally. It receives the conversation history and the list of functions, then outputs a function call (just like an agent). After execution, it sees the tool result and decides the next call.
Generated plan example (conceptual):
[
{"function": "NewsPlugin.SearchNews", "args": {"query": "latest AI agents"}},
{"function": "SummarizationPlugin.Summarize", "args": {"input": "$SearchNews.result"}},
{"function": "EmailPlugin.Send", "args": {"to": "user@example.com", "subject": "AI News Summary", "body": "$Summarize.result"}}
]
The planner resolves argument references (e.g., $SearchNews.result) using the context that accumulates during execution.
Plan Execution
Execution is handled by the Kernel. The planner iterates through the plan steps, invoking each function and capturing its output. If a step fails, the planner can:
- Retry the step (if configured).
- Skip the step and continue (if optional).
- Halt the plan and return an error.
In FunctionCallingStepwisePlanner, the execution loop is inherent: the LLM’s function call is executed, the result is fed back, and the LLM decides whether to call another function or stop.
Planner and Plugins
Plugins are the source of functions for planners. The planner’s effectiveness is directly tied to the quality and organization of your plugins.
- Discovery: The planner scans all plugins registered in the kernel. You can limit the scope by using a
kernel.clone()with only the required plugins. - Selection: Only functions with clear descriptions will be considered. Hide internal helper functions by not decorating them with
@kernel_function. - Execution: The planner invokes functions through the same kernel, so they benefit from all registered services (logging, memory, AI backends).
Planner and Memory
Memory enhances planning by providing historical context.
- Context awareness: Before generating a plan, the planner can retrieve relevant memories (e.g., “user prefers short emails”). These memories become part of the goal or the prompt.
- Historical execution: Storing past plans and their outcomes allows the planner to learn successful patterns or avoid previously failed approaches.
- Knowledge retrieval: Functions that search the memory can be included as steps in the plan, allowing the planner to dynamically fetch information.
Planner and Tool Calling
At a fundamental level, planning is orchestrated tool calling. Each step in a plan is a tool invocation. The FunctionCallingStepwisePlanner blurs the line between planning and agentic behavior—it uses the LLM’s function‑calling mechanism directly, making the planning process transparent and fully traceable. The planner becomes a loop of “LLM chooses tool → execute → LLM sees result → choose next tool”.
Planning Patterns
Here are common patterns you can implement with planners.
Research Workflow
- Step 1: Search news / web.
- Step 2: Extract and clean text.
- Step 3: Analyze sentiment or extract key entities.
- Step 4: Compile a report.
Data Processing Workflow
- Step 1: Read data from a source (SQL, API, file).
- Step 2: Validate and clean.
- Step 3: Transform (aggregations, joins).
- Step 4: Write to destination.
Customer Support Workflow
- Step 1: Classify intent (prompt function).
- Step 2: Look up relevant policies (native function with database).
- Step 3: Retrieve previous interactions (memory function).
- Step 4: Compose response.
Report Generation Workflow
- Step 1: Gather data from multiple sources.
- Step 2: Perform calculations (native math functions).
- Step 3: Render a template (prompt function).
- Step 4: Export to PDF (native file export).
Automation Workflow
- Step 1: Triggered by a webhook.
- Step 2: Parse payload.
- Step 3: Execute a series of internal API calls.
- Step 4: Notify stakeholders.
Each of these can be expressed as a goal, and the planner will assemble the steps using the available plugins.
Error Handling
Planners must be resilient. Implement these strategies:
- Missing functions: If no suitable function exists, the planner should return a clear message. Pre‑filter functions to ensure only relevant ones are exposed.
- Invalid plans: If the LLM generates malformed JSON or hallucinates a function name, the planner should catch parsing errors and retry with a correction hint.
- Failed execution steps: Wrap function calls in try/catch. Return an error message as the result; the LLM can then decide to try an alternative or abort.
- Dependency failures: If a required earlier step fails, the plan should terminate gracefully.
- Recovery strategies: Implement a maximum number of retries and a fallback final answer if the planner cannot succeed after N attempts.
The FunctionCallingStepwisePlanner handles many of these natively by feeding error messages back to the LLM.
Performance Considerations
- Planning latency: Each planning pass incurs an LLM call. Reduce overhead by caching plans for common goals (using the goal text as a cache key).
- Large function sets: Sending the schema of 100+ functions can be slow and confuse the model. Use
kernel.clone()to provide only the relevant plugins for the task at hand. - Context optimization: The planner’s prompt includes all function descriptions. Keep descriptions concise but clear.
- Execution efficiency: If steps are independent, you can modify the plan to run them in parallel (though not natively supported by the basic planner; you would need to implement a custom execution engine).
- Optimization checklist:
- Limit exposed functions to those needed.
- Use the smallest capable model for planning (e.g.,
gpt-4o-mini). - Set
max_iterationsto prevent runaway loops. - Cache plans when possible.
Common Beginner Mistakes
- Overcomplicated planning – using a planner for tasks that could be a single function call.
- Poor function descriptions – causing the planner to miss relevant tools.
- Excessive function exposure – giving the planner dozens of unrelated functions, leading to confusion.
- Weak execution validation – not checking intermediate results, resulting in cascading failures.
- Ignoring dependencies – expecting the planner to magically order steps without proper metadata.
- Not setting a max iteration limit – the planner may loop indefinitely if the model never determines the goal is complete.
Best Practices
- Keep functions atomic – each function should do one thing well.
- Use clear metadata – the function description is the planner’s primary documentation.
- Limit planner scope – clone the kernel with only the required plugins.
- Validate execution results – include a “check” function that the planner can call after critical steps.
- Monitor planning performance – log the generated plan, execution time per step, and success rate.
- Optimize function discovery – pre‑filter functions based on user intent or category before invoking the planner.
Practical Example: Research Report Generator
We’ll build a planner that, given a topic, searches the web for recent articles, summarizes them, and creates a short report.
1. Set up the kernel and plugins
from semantic_kernel import Kernel
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion
from semantic_kernel.functions import kernel_function
kernel = Kernel()
kernel.add_service(OpenAIChatCompletion(service_id="gpt", api_key="..."))
# Define a simple search plugin
class SearchPlugin:
@kernel_function(name="SearchWeb", description="Search the web for given query, return a list of snippets")
async def search(self, query: str) -> str:
# Call an actual search API
return "Snippet 1... Snippet 2..."
# Summarization prompt plugin (loaded from a directory)
kernel.add_plugin(SearchPlugin(), "Search")
kernel.add_plugin_from_prompt_directory("./Prompts/SummarizationPlugin", "Summarization")
2. Create the planner
from semantic_kernel.planners import FunctionCallingStepwisePlanner, FunctionCallingStepwisePlannerOptions
options = FunctionCallingStepwisePlannerOptions(
max_iterations=8,
max_tokens=4000,
)
planner = FunctionCallingStepwisePlanner(kernel=kernel, options=options)
3. Invoke the planner
goal = "Research the topic 'quantum computing breakthroughs 2026', summarize the findings, and output a markdown report."
result = await planner.invoke(goal)
print(result.final_answer)
What happens internally:
- The planner sends a prompt to the LLM including the goal and the schemas of
Search.SearchWebandSummarization.Summarize. - The LLM decides to first call
Search.SearchWeb(query="quantum computing breakthroughs 2026"). - The kernel executes the function, returning search snippets.
- The LLM then calls
Summarization.Summarize(input=<search results>). - Finally, the LLM determines the goal is achieved and returns a final markdown report.
- The planner returns the final answer.
If the search returned no results, the planner might have tried a different query or informed the user. This dynamic adaptability is the power of AI planning.
Planning in Production Systems
- Reliability: Use retries and clear error handling. Monitor planner success rate.
- Monitoring: Log the generated plan and each step’s execution. Integrate with your observability stack.
- Cost Control: Each planning step is an LLM call. Cache repeated goals. Use a cost‑efficient model for planning.
- Observability: Traces from the planner’s execution are available through OpenTelemetry or the Semantic Kernel logger.
- Optimization: Periodically review planner logs to identify frequently used plans; consider hard‑coding those as a standard workflow for efficiency.
Planners and Other Semantic Kernel Concepts
- Core Concepts – the Kernel, AI services, and plugins are the environment in which the planner operates.
- Plugins – the planner’s toolbox; their quality directly determines planning success.
- Memory – provides historical context that can guide planning.
- Production – production deployment of planners requires reliability and monitoring.
- MCP – MCP tools can be wrapped as plugins and made available to planners.
Semantic Kernel Planners vs Other Frameworks
| Framework | Planning approach | Strengths |
|---|---|---|
| Semantic Kernel | LLM‑based planners (sequential, stepwise) that dynamically discover and sequence functions | Deep integration with enterprise plugins; supports re‑planning; excellent for Microsoft ecosystem |
| LangGraph | Explicit graph definition with nodes and edges; planning is developer‑defined | Full control; can implement any planning algorithm; checkpoints for state |
| CrewAI | Tasks assigned to agents; a crew runs them sequentially/hierarchically; no dynamic plan generation | Simple, role‑based; good for predefined pipelines |
| AutoGen | Conversations and group chats drive the workflow; agents can be instructed to plan | Highly interactive; dynamic routing via LLM speaker selection |
| OpenAI Agents SDK | Uses handoffs to delegate; no explicit planner, but agents can call tools sequentially | Lightweight; relies on model’s ability to chain tool calls |
Semantic Kernel’s planners provide the most structured, metadata‑driven approach to dynamic workflow generation. They are particularly powerful when combined with a large library of well‑documented plugins.
FAQ
1. What is a Planner in Semantic Kernel?
A Planner is a component that automatically determines a sequence of function calls to achieve a given goal, using the available plugins in the Kernel.
2. How does planning work?
The planner uses an LLM to reason about the goal and the functions’ metadata, generates a plan, and then executes it step by step through the Kernel.
3. How are functions selected?
Based on their names and descriptions provided in the metadata. The LLM matches the goal semantics to the function capabilities.
4. Can plans be generated dynamically?
Yes, especially with FunctionCallingStepwisePlanner, which re‑evaluates after each step and can adapt the plan in real time.
5. How does memory affect planning?
Memory can provide additional context (like user preferences) that the planner includes in its reasoning, leading to more personalized and accurate plans.
6. How do planners handle failures?
They capture error messages from function calls and feed them back to the LLM, which can then decide to retry, choose an alternative, or abort.
7. Are planners production‑ready?
Yes, with proper error handling, monitoring, and function scoping, they are used in enterprise production environments.
8. What’s the difference between SequentialPlanner and FunctionCallingStepwisePlanner?
SequentialPlanner generates a full plan upfront and executes it linearly. FunctionCallingStepwisePlanner decides the next step on the fly using function calling, making it more flexible and robust.
9. How do I limit which functions the planner can use?
Use kernel.clone() and add only the specific plugins you want the planner to see, or filter functions manually before invoking.
10. Can I cache plans?
Yes, you can store the generated plan (list of function calls) and reuse it for identical goals. For dynamic planners, caching the final answer or intermediate steps can reduce LLM calls.
11. What models work best for planning?
GPT‑4o and GPT‑4o‑mini are excellent. The model must support function calling and have strong reasoning capabilities.
12. How do I debug a planner?
Enable kernel logging. Inspect the generated plan (available in the planner’s output or via a custom logger). Trace each function call and its result.
13. Can planners call other planners?
Yes, you can create a plugin that wraps a planner and call it as a function, enabling hierarchical planning.
14. What is the maximum number of steps a planner can take?
Configurable via max_iterations (for stepwise) or you can set a hard limit on plan length. Default is typically 10–25.
15. Does Semantic Kernel support multi‑agent planning?
While the kernel itself doesn’t have a built‑in multi‑agent planner, you can orchestrate multiple agents (each with their own kernel) using a custom workflow or an external orchestrator.
Conclusion
Planners bring a new level of autonomy to Semantic Kernel applications. By delegating the orchestration of functions to the AI, you can build systems that handle novel requests without hard‑coding every workflow. The combination of clear function metadata, the Kernel’s execution engine, and LLM‑powered reasoning creates a flexible, production‑ready planning solution.
Key takeaways:
- Planners decompose goals into ordered function calls.
- Function metadata is the fuel—invest in good descriptions.
- Stepwise planning adapts dynamically, while sequential planning is simpler and predictable.
- Plugins and memory provide the planner’s toolbox.
- Production requires monitoring, error handling, and cost control.
Now, continue your journey:
- Semantic Kernel Core Concepts – understand the Kernel and plugins.
- Semantic Kernel Plugins – build the tools your planners will use.
- Semantic Kernel Memory – add context and personalization.
- Semantic Kernel Production – deploy, monitor, and scale.
For cross‑framework comparisons, explore the LangGraph, CrewAI, AutoGen, and OpenAI Agents SDK guides. The framework comparison can help you choose the right orchestration model. To standardise tools, see the MCP Guide.
With planners, you’re not just programming agents—you’re teaching them to think ahead.