{"course":{"slug":"agents-and-automation","title":"Agents and Automation","url":"https://addaly.com/learn/agents-and-automation","level":"intermediate","track":"build"},"lesson":{"slug":"the-loop","title":"Plan, act, observe, repeat","url":"https://addaly.com/learn/agents-and-automation/the-loop","position":14,"of":72,"minutes":7,"answer":"The loop is trivial; deciding what goes back in as the observation is the entire craft.","keyIdea":"The loop is trivial; deciding what goes back in as the observation is the entire craft."},"body":{"format":"markdown","text":"## The whole thing is about twelve lines\n\nStrip away the frameworks and an agent is this:\n\n```python\nmessages = [{\"role\": \"user\", \"content\": task}]\n\nfor step in range(MAX_STEPS):\n    reply = model(messages, tools=TOOLS)      # plan\n    messages.append(reply)\n\n    if not reply.tool_calls:                  # it thinks it is done\n        return reply.text\n\n    for call in reply.tool_calls:             # act\n        result = execute(call)                # your code, not the model's\n        messages.append(tool_result(call.id, result))   # observe\n\nraise BudgetExceeded(step, messages)\n```\n\nThat is it. LangGraph, CrewAI, the Agents SDK, whatever you use next year: they all wrap this. Worth writing once by hand, because everything that goes wrong later goes wrong inside these lines.\n\nNotice what is *not* there. There is no memory. There is no plan stored anywhere. When the model writes \"first I'll check the database, then I'll email the customer,\" that plan is not state: it is a sentence in the transcript, with no more force than any other sentence. If it is not in `messages`, it does not exist.\n\n## The observe step is the whole engineering problem\n\nPlan and act are handled for you. Observe is where you make every meaningful decision, and it is the step people paste in without thinking.\n\nSuppose a tool fetches a supplier page. The raw response is 190 KB of HTML: navigation, cookie banner, a footer in three languages, and one table with the price you wanted. Append that verbatim and you have done three bad things at once. You spent about 50,000 tokens. You buried the price under noise. And you did it again on the next call, and the one after, because the transcript keeps growing.\n\nGood observations are:\n\n- **Small.** Extract the table. Strip the chrome.\n- **Informative on failure.** `No price found on this page; the page returned a 404 body` is worth twenty times `''`.\n- **Honestly truncated.** If you cut, say so: `[first 40 of 812 rows shown]`. A silent truncation makes the model confidently reason about data it never saw.\n\n## Cost does not grow linearly\n\nEvery turn re-sends the whole transcript. A task with a 2,000-token brief and 1,500-token observations is sending about 3,500 tokens on step one and about 25,000 on step fifteen. Total spend across a run grows roughly with the square of the step count, not with the step count.\n\nSo the two levers on an agent's bill are the same two levers on its quality: **fewer steps, smaller observations.**\n\n## The quiet failure this causes\n\nHere is the pattern you will meet. An agent runs beautifully for four or five steps, then starts repeating searches it already ran and contradicting facts it established earlier. The instinct is to say it \"forgot.\" Usually nothing was dropped at all: the context window is not even full. The earlier findings are still sitting there, three thousand tokens down, under two full web pages the loop appended without trimming.\n\nDegradation starts long before hard truncation does. What you feed back in step three determines whether step nine works.\n\nThe fix is unglamorous and it works: summarise as you go. After each tool result, write a one-line note of what was learned, and keep the notes near the end of the transcript where they stay salient. Some teams keep a running scratchpad the agent rewrites each turn. Either way, you are doing the same thing: deciding what is worth carrying forward, instead of carrying everything."},"check":{"question":"A research agent works well for five steps, then begins re-running searches it already ran and contradicting findings from step two. Token counts show the context window is about 40% full. What is the best explanation?","options":[{"text":"The early findings are still present but diluted: the loop appended full page dumps that now crowd out the useful facts.","correct":true},{"text":"The earlier steps have fallen out of the model's context window and are genuinely gone.","correct":false,"tempting":"Assumes the only context failure is hard truncation, when quality degrades well before the window fills, and here it is only 40% full."},{"text":"The agent has no memory tool, so it has no mechanism for recalling what it did earlier.","correct":false,"tempting":"Reaches for an architecture change when the transcript already contains everything; memory tools help by curating, not by making recall possible."},{"text":"The task was underspecified, so the agent has no criterion for deciding a search is redundant.","correct":false,"tempting":"Blames the prompt for a context-management failure, though the identical prompt produced five good steps first."}]},"prev":{"slug":"system-prompts-for-agents","title":"The instruction block that has to survive forty turns","url":"https://addaly.com/learn/agents-and-automation/system-prompts-for-agents"},"next":{"slug":"planning-and-decomposition","title":"Plan first, or just start?","url":"https://addaly.com/learn/agents-and-automation/planning-and-decomposition"},"authorship":"Founder and series editor: Dr Mustafa Mun. Written by AI models to a written standard. Exam keys checked blind by a second model: 3,665 of 3,666 agreed. Academic review invited.","review":{"status":"Draft, open for academic review"},"cite":"Addaly (2026) 'Plan, act, observe, repeat', in Agents and Automation. Edited by M. Mun. Addaly. Available at: https://addaly.com/learn/agents-and-automation/the-loop (Accessed: 31 October 2026).","licence":{"name":"CC BY-NC-SA 4.0","url":"https://creativecommons.org/licenses/by-nc-sa/4.0/"},"reader":{"schema":1,"title":"Plan, act, observe, repeat","courseTitle":"Agents and Automation","module":{"index":2,"slug":"how-the-loop-runs","title":"The machinery: transcript, tools, loop"},"answer":null,"keyIdea":"The loop is trivial; deciding what goes back in as the observation is the entire craft.","hero":{"kind":"plate","image":null,"alt":null,"caption":null},"blocks":[{"t":"h2","id":"the-whole-thing-is-about-twelve-lines","runs":[{"text":"The whole thing is about twelve lines"}]},{"t":"p","runs":[{"text":"Strip away the frameworks and an agent is this:"}]},{"t":"code","lang":"python","label":"Python","text":"messages = [{\"role\": \"user\", \"content\": task}]\n\nfor step in range(MAX_STEPS):\n    reply = model(messages, tools=TOOLS)      # plan\n    messages.append(reply)\n\n    if not reply.tool_calls:                  # it thinks it is done\n        return reply.text\n\n    for call in reply.tool_calls:             # act\n        result = execute(call)                # your code, not the model's\n        messages.append(tool_result(call.id, result))   # observe\n\nraise BudgetExceeded(step, messages)"},{"t":"p","runs":[{"text":"That is it. LangGraph, CrewAI, the Agents SDK, whatever you use next year: they all wrap this. Worth writing once by hand, because everything that goes wrong later goes wrong inside these lines."}]},{"t":"p","runs":[{"text":"Notice what is "},{"text":"not","i":true},{"text":" there. There is no memory. There is no plan stored anywhere. When the model writes “first I’ll check the database, then I’ll email the customer,” that plan is not state: it is a sentence in the transcript, with no more force than any other sentence. If it is not in "},{"text":"messages","code":true},{"text":", it does not exist."}]},{"t":"h2","id":"the-observe-step-is-the-whole-engineering-problem","runs":[{"text":"The observe step is the whole engineering problem"}]},{"t":"p","runs":[{"text":"Plan and act are handled for you. Observe is where you make every meaningful decision, and it is the step people paste in without thinking."}]},{"t":"p","runs":[{"text":"Suppose a tool fetches a supplier page. The raw response is 190 KB of HTML: navigation, cookie banner, a footer in three languages, and one table with the price you wanted. Append that verbatim and you have done three bad things at once. You spent about 50,000 tokens. You buried the price under noise. And you did it again on the next call, and the one after, because the transcript keeps growing."}]},{"t":"p","runs":[{"text":"Good observations are:"}]},{"t":"ul","items":[[{"text":"Small.","b":true},{"text":" Extract the table. Strip the chrome."}],[{"text":"Informative on failure.","b":true},{"text":" "},{"text":"No price found on this page; the page returned a 404 body","code":true},{"text":" is worth twenty times "},{"text":"''","code":true},{"text":"."}],[{"text":"Honestly truncated.","b":true},{"text":" If you cut, say so: "},{"text":"[first 40 of 812 rows shown]","code":true},{"text":". A silent truncation makes the model confidently reason about data it never saw."}]]},{"t":"h2","id":"cost-does-not-grow-linearly","runs":[{"text":"Cost does not grow linearly"}]},{"t":"p","runs":[{"text":"Every turn re-sends the whole transcript. A task with a 2,000-token brief and 1,500-token observations is sending about 3,500 tokens on step one and about 25,000 on step fifteen. Total spend across a run grows roughly with the square of the step count, not with the step count."}]},{"t":"p","runs":[{"text":"So the two levers on an agent’s bill are the same two levers on its quality: "},{"text":"fewer steps, smaller observations.","b":true}]},{"t":"h2","id":"the-quiet-failure-this-causes","runs":[{"text":"The quiet failure this causes"}]},{"t":"p","runs":[{"text":"Here is the pattern you will meet. An agent runs beautifully for four or five steps, then starts repeating searches it already ran and contradicting facts it established earlier. The instinct is to say it “forgot.” Usually nothing was dropped at all: the context window is not even full. The earlier findings are still sitting there, three thousand tokens down, under two full web pages the loop appended without trimming."}]},{"t":"p","runs":[{"text":"Degradation starts long before hard truncation does. What you feed back in step three determines whether step nine works."}]},{"t":"p","runs":[{"text":"The fix is unglamorous and it works: summarise as you go. After each tool result, write a one-line note of what was learned, and keep the notes near the end of the transcript where they stay salient. Some teams keep a running scratchpad the agent rewrites each turn. Either way, you are doing the same thing: deciding what is worth carrying forward, instead of carrying everything."}]}],"check":{"question":[{"text":"A research agent works well for five steps, then begins re-running searches it already ran and contradicting findings from step two. Token counts show the context window is about 40% full. What is the best explanation?"}],"options":[{"text":[{"text":"The early findings are still present but diluted: the loop appended full page dumps that now crowd out the useful facts."}],"correct":true,"tempting":null},{"text":[{"text":"The earlier steps have fallen out of the model’s context window and are genuinely gone."}],"correct":false,"tempting":[{"text":"Assumes the only context failure is hard truncation, when quality degrades well before the window fills, and here it is only 40% full."}]},{"text":[{"text":"The agent has no memory tool, so it has no mechanism for recalling what it did earlier."}],"correct":false,"tempting":[{"text":"Reaches for an architecture change when the transcript already contains everything; memory tools help by curating, not by making recall possible."}]},{"text":[{"text":"The task was underspecified, so the agent has no criterion for deciding a search is redundant."}],"correct":false,"tempting":[{"text":"Blames the prompt for a context-management failure, though the identical prompt produced five good steps first."}]}],"order":[1,3,0,2],"why":null},"prev":{"slug":"system-prompts-for-agents","title":"The instruction block that has to survive forty turns","minutes":9},"next":{"slug":"planning-and-decomposition","title":"Plan first, or just start?","minutes":9}}}