Planning

1 min read
On trails:AGENTSstep 7/9

A goal like “research this and write it up” is too big for one step. Planning decomposes a high-level goal into steps and works through them in order, using chain of thought: the model writes out intermediate reasoning before it commits to an action.

The steps

Multi-step work needs the agent to keep hold of where it is:

  1. Make a plan.
  2. Store the plan, so it survives from one step to the next.
  3. Track the steps, so it knows what is done and what is left.
  4. Execute one step, get the result, let the LLM process it, and continue.

Tool calls fit inside a step (see tool useTool useFunction calling gives the model hands: it asks, and code does the work.Opens in a new tab). A step can be one call or several.

In LangGraph

The plan and the progress are fields in the graph state, so every node can see them. The planner runs once. The executor loops until every step has a result.

Python
from pydantic import BaseModelfrom typing_extensions import TypedDictfrom langchain.chat_models import init_chat_modelfrom langgraph.graph import END, START, StateGraph class Plan(BaseModel):    steps: list[str] class State(TypedDict):    goal: str    plan: list[str]    done: list[str] def make_plan(state: State):    planner = init_chat_model("anthropic:claude-sonnet-5").with_structured_output(Plan)    plan = planner.invoke(f"Break this goal into short, ordered steps: {state['goal']}")    return {"plan": plan.steps} def run_step(state: State):    step = state["plan"][len(state["done"])]    return {"done": state["done"] + [f"result of: {step}"]} def more_steps(state: State):    return "run_step" if len(state["done"]) < len(state["plan"]) else END builder = StateGraph(State)builder.add_node("make_plan", make_plan)builder.add_node("run_step", run_step)builder.add_edge(START, "make_plan")builder.add_edge("make_plan", "run_step")builder.add_conditional_edges("run_step", more_steps, ["run_step", END])graph = builder.compile()

The model is called once to plan. plan and done are the stored plan and the tracked steps. The conditional edge is the loop. In a real agent run_step would call a model or a tool, and each result would feed the next step.

Against ReAct

LangChain’s write-up of plan-and-execute contrasts it with ReActReActReason, act, observe, repeat: planning, tool use and a loop in one pattern.Opens in a new tab, which needs a model call after every action. Planning up front can be faster and cheaper, since a smaller model can run the steps, and it forces the planner to think through the whole task. The catch is that a fixed plan can be wrong. The usual answer is a replan step: after the steps run, the model decides whether to finish or to write a follow-up plan.


Sources