advanced26 min

AI Agents and Workflows

Chain multiple tool calls into a bounded plan-act-observe loop.

What you'll learn

  • Describe the plan → act → observe agent loop
  • Explain why an agent loop must be bounded
  • Implement a simple bounded loop that stops on a completion condition

Prerequisites

Explanation

A single tool call answers "look this one thing up." An agent goes further: it can chain multiple steps together, using the result of one action to decide the next one, until it judges the task complete. The common shape is a loop:

  1. Plan — given the goal and everything observed so far, decide what to do next (answer directly, or call a specific tool).
  2. Act — actually perform that action (call the chosen tool with the chosen arguments).
  3. Observe — receive the tool's result and add it to the agent's working context.
  4. Repeat, incorporating each observation into the next planning step, until the agent decides it has enough information to give a final answer — or until a safety limit is hit.

That safety limit matters enormously. An unbounded loop is dangerous: a model that gets confused could call tools indefinitely, burning cost and time with no guaranteed termination. Every real agent loop needs a maximum step count (e.g., "stop after 6 tool calls no matter what, and give the best answer available") as a hard backstop, independent of whether the model ever explicitly decides it's done.

Agents are a good fit for tasks that genuinely require multiple dependent steps — "find this user's most recent order, then check its shipping status, then draft a message about it" — where each step's outcome determines the next action. They're overkill (and a reliability/cost risk) for tasks a single prompt or a single tool call already solves well; more autonomy is not automatically better, and a fixed, deterministic workflow you designed yourself is often more predictable and debuggable than an open-ended agent loop, especially for the beta stage of a product.

Observability matters just as much here as capability: log every planning decision, every tool call with its arguments, and every observation, in an auditable form — both for debugging when something goes wrong, and so a human can review exactly what actions an agent took and why, especially before granting it access to anything with real-world consequences.

The bounded agent loop

Plan (decide next action) → Act (call a tool) → Observe (read the result) → loop back to Plan, until either a completion condition is met or a maximum step count is reached, whichever comes first.

Example

A tiny bounded agent loop using mock tools and a mock 'planner' function (a real agent's planning step would be an LLM call; here it's a simple rule for teaching purposes).

const tools = {
  lookupWeather: () => ({ tempC: 22, condition: "sunny" }),
};

function mockPlan(observations) {
  if (observations.length === 0) {
    return { action: "call-tool", tool: "lookupWeather" };
  }
  return { action: "final-answer", text: "It's a sunny 22°C day." };
}

function runAgent(maxSteps) {
  const observations = [];
  for (let step = 0; step < maxSteps; step++) {
    const decision = mockPlan(observations);
    if (decision.action === "final-answer") {
      return decision.text;
    }
    const result = tools[decision.tool]();
    observations.push(result);
  }
  return "Stopped after reaching the maximum number of steps.";
}

console.log(runAgent(5));

Try it yourself

Lower maxSteps to 0 and see the loop's safety backstop trigger instead of ever calling the tool.

Code editor. Press Escape then Tab to leave the editor if keyboard focus becomes trapped. Press Control+Shift+M inside the editor to toggle Tab-key focus trapping.

Loading editor…

Guided exercise

Guided exercise

Complete `runBoundedLoop(isDone, step, maxSteps)` where `step` is a function taking the current iteration count and returning some value, and `isDone` takes that value and returns a boolean. Call step() repeatedly (passing the iteration index starting at 0), stopping as soon as isDone(result) is true, or after maxSteps calls — whichever comes first. Return the last result produced.

Checks: Stops early once isDone is true · plus 1 hidden check

Code editor. Press Escape then Tab to leave the editor if keyboard focus becomes trapped. Press Control+Shift+M inside the editor to toggle Tab-key focus trapping.

Loading editor…

Stuck? Get a hint.

Independent exercise

Independent exercise

Write `runAgentLoop(tools, plan, maxSteps)`. `plan(observations)` returns either `{ action: 'call-tool', tool: name }` or `{ action: 'final-answer', text }`. Call plan with the growing observations array; if it requests a tool, call `tools[name]()`, push the result into observations, and continue; if it returns a final answer, return that text immediately. If maxSteps is reached without a final answer, return the string 'Stopped: step limit reached.'

Checks: Completes correctly after one tool call · plus 1 hidden check

Code editor. Press Escape then Tab to leave the editor if keyboard focus becomes trapped. Press Control+Shift+M inside the editor to toggle Tab-key focus trapping.

Loading editor…

Stuck? Get a hint.

Common mistakes

  • Building an agent loop with no maximum step count, risking runaway cost or an infinite loop.
  • Reaching for an agent when a single deterministic function call would have solved the task more predictably.
  • Not logging each planning decision and tool call, making failures impossible to debug or audit later.

Knowledge check

Knowledge check

1. What are the three stages of the core agent loop?
2. Why must an agent loop have a maximum step count?
3. When is a fixed, single-purpose function usually preferable to a full agent loop?

Takeaway

An agent is a bounded plan-act-observe loop — powerful for multi-step tasks, but only as safe as its hard step limit.

Summary

Agents chain multiple tool calls together in a plan → act → observe loop, using each observation to inform the next decision, until a completion condition or a hard maximum step count is reached. Agents suit genuinely multi-step, adaptive tasks; simpler deterministic workflows are often better for everything else.

References

Your notes

Notes save automatically.