Skip to main content
C carlos.enredando.me CTO · Advisor · Builder

Mastering Agentic AI: The Planning Pattern

·1242 words·6 mins
Carlos Prados
Author
Carlos Prados
Telecommunications Engineer, Entrepreneur, CTO & CIO, Team Leader & Manager, IoT-M2M-Big Data Consultant, Pre-sales Engineer, Product-Service Manager & Strategist.

In the previous post, Tool Use gave our agents senses and limbs — the ability to actually do something in the world. But there’s still a gap. Tools are great when the LLM knows which tool to use and when. They break down the moment the task is too complex to be handled by a single decision.

Ask an LLM with a calculator tool to “calculate the factorial of 12” and it’ll handle it. Ask it to “write me a comprehensive research report on the economic impact of semaglutide, including market trends, competitor analysis, and regulatory landscape” and you’re suddenly asking for something that no single tool call can produce. You need a sequence. You need a plan.

That’s the Planning pattern. It’s where agents stop reacting and start strategizing.

Pattern #6: Planning
#

The Problem
#

Complex problems can’t be solved in one shot. They require foresight — breaking a high-level objective into a sequence of smaller, executable steps, then carrying each one out while remembering what’s already been done and what comes next.

Without an explicit planning step, an agent faced with a multi-step request behaves like a junior engineer thrown into a sprint with no ticket breakdown: it picks whichever sub-task looks easiest, makes some progress, gets stuck, and ends up with an incomplete result. There’s no strategy, no dependency management, no awareness of the overall objective. Just reactive flailing.

This is exactly the gap modern “Deep Research” features fill — Google’s DeepResearch, OpenAI’s Deep Research, Perplexity’s. None of them are doing magic. They’re applying the Planning pattern: decompose the question into research queries, execute each one, synthesize the findings.

The Solution
#

Planning introduces an explicit plan-and-execute structure: the LLM first produces a plan, then a second pass (or a chain of passes) executes against it. The output of the planning step becomes context for the execution step.

The simplest possible form is a two-stage LCEL chain. Stage one generates a plan, stage two writes the article using that plan as context:

plan_chain = plan_prompt | llm | StrOutputParser()

full_chain = (
    RunnablePassthrough.assign(plan=plan_chain)
    | write_prompt
    | llm
    | StrOutputParser()
)

article = full_chain.invoke({"topic": "How AI agents transform software workflows"})

RunnablePassthrough.assign(plan=plan_chain) is the elegant part. After the planning chain runs, its output is added to the running dict under the key plan. The write prompt then has access to both the original topic and the generated plan. The model that writes the article isn’t starting from scratch — it’s given a structured outline to follow.

The planning prompt itself is where the work happens:

plan_prompt = ChatPromptTemplate.from_messages([
    ("system",
     "You are an expert article planner. Create a structured outline for an article "
     "on the given topic. Include:\n"
     "1. Title\n"
     "2. Key sections (3-4)\n"
     "3. Main points for each section\n"
     "4. Target audience"),
    ("user", "Create an article plan for: {topic}")
])

This is the moment the LLM is forced to think before it writes. The structure of the prompt — title, sections, main points, audience — is the scaffolding the execution step relies on. Garbage plan, garbage article. The quality of the final output is bounded by the quality of the plan.

Planning as Query Generation
#

The pattern generalizes to anything that needs decomposition before execution. Research is the canonical case. Instead of asking the LLM to “write a research report,” you ask it to first generate the right questions, then synthesize the report against those questions:

query_prompt = ChatPromptTemplate.from_messages([
    ("system",
     "You are a research assistant. Given a research topic, generate 3-5 specific "
     "search queries that would help gather comprehensive information. "
     "Output only the queries, one per line."),
    ("user", "Research topic: {topic}")
])

synthesis_prompt = ChatPromptTemplate.from_messages([
    ("system",
     "You are a senior research analyst. Based on the topic and the search queries "
     "that were planned, provide a comprehensive research report. Include:\n"
     "1. Executive Summary\n"
     "2. Key Findings (organized by query area)\n"
     "3. Conclusions and Recommendations\n\n"
     "Research queries planned:\n{queries}"),
    ("user", "Write the research report for: {topic}")
])

full_chain = (
    RunnablePassthrough.assign(queries=query_chain)
    | synthesis_prompt
    | llm
    | StrOutputParser()
)

Same structural pattern, different semantics. The “plan” here is a list of queries the agent would search for. In a production setup, those queries would be passed to a real search tool (Tavily, Brave, an internal vector store), the results would replace the plan in the synthesis step, and you’d have a working Deep Research clone in well under 100 lines of Python.

This is also where Planning starts composing with the patterns we’ve already seen:

  • Plan + Parallelization: generate N queries, fan them out to a search tool concurrently, fan back into synthesis.
  • Plan + Tool Use: each step in the plan corresponds to a tool call.
  • Plan + Reflection: critique the plan before executing it, or critique the output and re-plan if it fails the bar.

Why This Matters
#

Planning is what separates a “smart autocomplete” from an agent. The shift is small in code — a two-stage chain instead of a one-stage one — but the behavioral shift is large. The agent goes from “I’ll generate text that looks like an answer” to “I’ll figure out what the steps are, then execute them.”

It’s also where two important capabilities emerge naturally:

  • Adaptive plans. Once you have an explicit plan, you can let later steps modify it. If step 2 reveals new information, step 3 can be revised. This is the foundation for true agentic behavior — adjusting strategy based on what’s been learned.
  • Observability. A plan is a debuggable artifact. When something goes wrong in a single-prompt agent, you have a wall of generated text and no idea where it went off the rails. When something goes wrong in a plan-and-execute agent, you can read the plan, see what was supposed to happen, and find the exact step that failed. This alone justifies the pattern in production.

Trade-offs to be honest about:

  • Latency: two LLM calls minimum, often more. Single-pass is faster.
  • Cost: same reason. Token usage at least doubles.
  • Plan rigidity: a plan generated up-front can be wrong about the world. For dynamic environments, you want iterative planning — generate a plan, execute one step, re-plan based on the result. That’s what we’ll see in later chapters (Goal Setting and Monitoring, Exploration and Discovery).

Rule of thumb from the book: use this pattern when the user’s request is too complex to be handled by a single action or tool. Multi-step processes — research reports, onboarding flows, competitive analyses — are the sweet spot. For simple lookups, planning is overkill.


The Bigger Picture
#

This is post #6 in my series documenting Antonio Gulli’s Agentic Design Patterns. As always, full credit for the conceptual framework goes to him.

We’ve now covered the six foundational patterns: Prompt Chaining, Routing, Parallelization, Reflection, Tool Use, and Planning. Together they form the building blocks of any non-trivial agentic system. Everything from here on — Multi-Agent Collaboration, Memory, MCP, Goal Setting, RAG — composes on top of this base layer.

All the code from this post is in my repository: carlosprados/Agentic_Design_Patterns, under 06_Planning/. Two runnable examples — the article planning writer and the deep research pipeline — both working with Gemini and Ollama through the shared get_llm() abstraction.


What’s Next
#

In the next post we’ll tackle Multi-Agent Collaboration — when a single agent isn’t enough and you need a team of specialized agents working together. Researchers, writers, critics, coordinators. This is where the “agentic team” metaphor becomes literal.

Stay tuned.