A reasoning model is a language model that spends additional computation working through a problem before giving its final answer. A non-reasoning model produces its answer without a separate, extended deliberation phase. The extra work can help with difficult multistep problems, but it also uses more tokens and takes longer. section 5.1
Chain-of-thought prompting is a different approach: it asks a model to write intermediate steps as part of its output. That can discourage shallow answers, but it does not turn a weak model into a strong reasoner. Likewise, a model’s built-in reasoning mode does not guarantee a sound plan. section 5.1 section 1.1.2
Choose deliberation for the step, not automatically for the whole agent:
- Use none or minimal reasoning effort for routine, well-scoped steps whose prompts and tools already constrain the work. section 2.3.2
- Raise effort for planning, complex tool selection, or debugging a stuck loop, where extra deliberation may justify its latency and token cost. section 2.3.2
- Keep the process bounded: limit iterations, inspect tool results, and fail safely when the agent cannot finish. section 11.1.3
A bounded planning agent
A planning agent can draft a short checklist, execute against it, and inspect each tool observation before continuing. Its output can include a status indicating whether follow-up is needed, while a turn limit prevents an endless loop. Built-in reasoning still needs these controls: it does not ensure the agent will do the right thing. section 11.1.3
Listing 11.3 03_reasoning_planning_tips.py
from typing import Literal
from pydantic import BaseModel
from agents import Agent, Runner
from agents.mcp import MCPServerStdio
MAX_TURNS = 3 #1
thinking_srv = MCPServerStdio( #2
name="sequential-thinking",
params={
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-sequential-thinking"],
},
)
class Answer(BaseModel):
status: Literal["ok", "needs_followup"] = "ok"
checklist: list[str] = []
summary: str
sources: list[str]
instructions = f"""
You are a planner-executor.
If the message starts with 'PLAN ONLY',
return only the checklist (no actions).
1) Plan→Execute: draft a concise 3–5 item checklist, then execute. #2
2) ReAct: Thought→Action(tool)→Observation; #3
inspect each observation before continuing.
3) Limit: stop after at most {MAX_TURNS} tool calls; #1
if reached, set status='needs_followup' and return best effort.
4) Self-review: before final, catch obvious mistakes, #4
ensure the question is answered, and cite sources.
Use seq_think between actions to decide the next step.
Return Answer JSON only.
"""
async def main():
agent = Agent(
name="Planner",
instructions=instructions,
mcp_servers=[thinking_srv],
max_turns=MAX_TURNS,
output_type=Answer)
async with thinking_srv:
question = "Summarize our refund policy and cite relevant internal docs."
plan = await Runner.run(agent, f"PLAN ONLY. Question: {question}")
print(plan.final_output.checklist)
result = await Runner.run(agent, question)
print(result.final_output)
if __name__ == "__main__":
import asyncio
asyncio.run(main())
The example code makes the safeguards inspectable: a maximum-turn constant, a structured answer with follow-up status, and instructions to plan before acting and inspect observations. section 11.1.3



