Files
crewAI/lib/crewai/src/crewai/agent/planning_config.py
Lorenze Jay 77a61274dc feat(planning): enhance planning configuration and observation handling (#5913)
* feat(planning): enhance planning configuration and observation handling

- Introduced  attribute in  to control LLM calls after each step.
- Updated  to set default  to 1 when planning is enabled without explicit config.
- Modified  to support heuristic observations when LLM calls are disabled.
- Adjusted  to respect  and  settings for step observations.
- Added tests to verify behavior of new configurations and ensure correct observation handling across different reasoning efforts.

* fix(agent_executor): update handling of failed steps in low effort mode

- Adjusted logic to ensure that failed steps are recorded without marking them as completed when using low reasoning effort.

- Introduced feedback for failed steps, allowing the process to continue while tracking failures.
- Added a test to verify that failed steps are correctly marked without triggering a replan.

- And linted

* linted
2026-05-26 09:10:43 -07:00

148 lines
5.5 KiB
Python

from __future__ import annotations
from typing import Literal
from pydantic import BaseModel, Field
from crewai.llms.base_llm import BaseLLM
class PlanningConfig(BaseModel):
"""Configuration for agent planning/reasoning before task execution.
This allows users to customize the planning behavior including prompts,
iteration limits, the LLM used for planning, and the reasoning effort
level that controls post-step observation and replanning behavior.
Note: To disable planning, don't pass a planning_config or set planning=False
on the Agent. The presence of a PlanningConfig enables planning.
Attributes:
reasoning_effort: Controls observation and replanning after each step.
- "low": Skip per-step PlannerObserver LLM calls (heuristic only);
skip the decide/replan/refine pipeline. Fastest option.
- "medium": Observe each step via LLM. On failure, trigger replanning.
On success, skip refinement and continue. Balanced option.
- "high": Full observation pipeline — observe every step, then
route through decide_next_action which can trigger early goal
achievement, full replanning, or lightweight refinement.
Most adaptive but adds latency per step.
observe_steps: When True, run PlannerObserver LLM calls after each step.
When False, use a lightweight heuristic (no extra LLM call).
When None (default), LLM observation runs for "medium" and "high"
only; "low" uses the heuristic path.
max_attempts: Maximum number of planning refinement attempts.
If None, will continue until the agent indicates readiness.
max_steps: Maximum number of steps in the generated plan.
system_prompt: Custom system prompt for planning. Uses default if None.
plan_prompt: Custom prompt for creating the initial plan.
refine_prompt: Custom prompt for refining the plan.
llm: LLM to use for planning. Uses agent's LLM if None.
Example:
```python
from crewai import Agent
from crewai.agent.planning_config import PlanningConfig
agent = Agent(
role="Researcher",
goal="Research topics",
backstory="Expert researcher",
planning_config=PlanningConfig(),
)
agent = Agent(
role="Researcher",
goal="Research topics",
backstory="Expert researcher",
planning_config=PlanningConfig(
reasoning_effort="medium",
),
)
agent = Agent(
role="Researcher",
goal="Research topics",
backstory="Expert researcher",
planning_config=PlanningConfig(
reasoning_effort="high",
max_attempts=3,
max_steps=10,
plan_prompt="Create a focused plan for: {description}",
llm="gpt-4o-mini",
),
)
```
"""
reasoning_effort: Literal["low", "medium", "high"] = Field(
default="medium",
description=(
"Controls post-step observation and replanning behavior. "
"'low' skips per-step PlannerObserver LLM calls (fastest). "
"'medium' observes via LLM and replans only on step failure (balanced). "
"'high' runs full observation pipeline with replanning, refinement, "
"and early goal detection (most adaptive, highest latency)."
),
)
observe_steps: bool | None = Field(
default=None,
description=(
"Run PlannerObserver LLM calls after each step. "
"None (default): LLM observation for 'medium' and 'high' only; "
"'low' uses a heuristic (no extra LLM). "
"Set False to disable observation at any effort level."
),
)
max_attempts: int | None = Field(
default=None,
description=(
"Maximum number of planning refinement attempts. "
"If None, will continue until the agent indicates readiness."
),
)
max_steps: int = Field(
default=20,
description="Maximum number of steps in the generated plan.",
ge=1,
)
system_prompt: str | None = Field(
default=None,
description="Custom system prompt for planning. Uses default if None.",
)
plan_prompt: str | None = Field(
default=None,
description="Custom prompt for creating the initial plan.",
)
refine_prompt: str | None = Field(
default=None,
description="Custom prompt for refining the plan.",
)
max_replans: int = Field(
default=3,
description="Maximum number of full replanning attempts before finalizing.",
ge=0,
)
max_step_iterations: int = Field(
default=15,
description=(
"Maximum LLM iterations per step in the StepExecutor multi-turn loop. "
"Lower values make steps faster but less thorough."
),
ge=1,
)
step_timeout: int | None = Field(
default=None,
description=(
"Maximum wall-clock seconds for a single step execution. "
"If exceeded, the step is marked as failed and observation decides "
"whether to continue or replan. None means no per-step timeout."
),
)
llm: str | BaseLLM | None = Field(
default=None,
description="LLM to use for planning. Uses agent's LLM if None.",
)
model_config = {"arbitrary_types_allowed": True}