Skip to content

Deprecated Planners

Key Points

  • SK Planners (SequentialPlanner, StepwisePlanner, HandlebarsPlanner) are deprecated.
  • Replaced by FunctionChoiceBehavior.Auto + iterative tool calling — modern reasoning models do planning natively.
  • DO NOT use planners in new code.
  • For existing planner-based code: migrate to FunctionChoiceBehavior.Auto (in SK) or Agent Framework with UseFunctionInvocation().

What planners did

// OLD — DEPRECATED
var planner = new HandlebarsPlanner();
var plan = await planner.CreatePlanAsync(kernel, "Book a trip to Rome");
var result = await plan.InvokeAsync(kernel);

Planners would: 1. List all available functions/plugins. 2. Ask LLM to generate a plan (sequence of function calls). 3. Execute.

Why deprecated

  • Modern LLMs plan natively via function calling — no separate planning step.
  • Reasoning models (o-series, Claude with thinking) plan implicitly.
  • Planners brittle: LLM-generated plans often had syntax errors.
  • Hard to debug: opaque plan generation.
  • Slow: planning + execution are sequential round-trips.

Modern replacement

// NEW — current best practice
var settings = new OpenAIPromptExecutionSettings
{
    FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
};

var resp = await kernel.InvokePromptAsync(
    "Book a trip to Rome.",
    new(settings));

Or in Agent Framework:

chat = chat.AsBuilder().UseFunctionInvocation().Build();
var agent = new ChatClientAgent(chat) { Tools = [...] };
var resp = await agent.InvokeAsync("Book a trip to Rome");

LLM decides which functions to call; runtime invokes; repeat until done. Same behavior; simpler; faster.

Migration

// OLD
var planner = new HandlebarsPlanner();
var plan = await planner.CreatePlanAsync(kernel, prompt);
await plan.InvokeAsync(kernel);

// NEW
var settings = new OpenAIPromptExecutionSettings { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() };
await kernel.InvokePromptAsync(prompt, new(settings));

Drop planner; use FunctionChoiceBehavior.Auto.

What about complex multi-step?

  • For straightforward tool use: FunctionChoiceBehavior.Auto enough; LLM iterates.
  • For complex orchestration: Agent Framework's orchestration patterns (sequential, magentic, etc.).
  • For deterministic workflows: Durable Functions / workflow engines.

What if I need a "plan" output?

If you specifically want the LLM to output a plan (for human review, audit, etc.):

new ChatOptions
{
    ResponseFormat = ChatResponseFormat.ForJsonSchema(JsonSchema.FromType<Plan>(), strict: true)
};

var plan = await chat.GetResponseAsync("Generate a plan to do X");

Treat plan as data; execute in your own code with explicit control.

Status

SK planners technically still in package; emit deprecation warnings; will be removed.

Senior considerations

  • Don't write new planner code.
  • Migrate existing: low-priority maintenance task.
  • Prompt templates still useful — those AREN'T deprecated.
  • Plugin definitions still useful as KernelFunctions → adapt to AIFunction.

Cross-references