THE FUTURE MARKETACADEMY
Your classroomRoom 01 · AI Lab
School of AI

Multi-Step Agents: tools, memory and reliability

Step 6 of 7 in AI Lab

Next in your path: 1.5.3 Claude Code Projects: larger codebases, tests and git

What you'll be able to do
  • Write the agent loop yourself and explain every message in it (tool_use, tool_result, stop_reason).
  • Give an agent several tools and design them so Claude picks the right one.
  • Return errors to Claude in a way that lets it recover, and know when to stop retrying.
  • Keep context across many steps and across sessions, using the conversation, the memory tool and a progress file.
  • Add limits and logs so a run cannot go on forever and you can always see what it did.
  • Put a human approval step in front of any risky tool, and test the whole agent without paying for API calls.

Before this course: Agents First Steps (course 1.4.1) and Build AI Agents with Claude: No-Code to Code (course 1.4). You should already know the words workflow, agent, tool and tool runner, and have run a first API call in Python. This course goes deeper: you open up the loop that the tool runner hides, then make it safe and reliable. You need Python 3.9 or newer and a terminal. Examples use claude-opus-5-5.

Words in this course 45Open the Vocabulary Hall
01

Open the loop (the manual agent loop)

In simple words

In course 1.4 a robot did the errands and you only saw the result. Now you hold the clipboard. Claude says "please check the stock room," you go and check, you write the answer on the clipboard and hand it back. Then Claude decides what to ask next. That back and forth is the whole agent.

Key facts
  • When Claude wants to use a client tool, the response has stop_reason of tool_use and one or more tool_use blocks. Each block has an id, a name and an input (the arguments).
  • Your code runs the tool, then sends a new user message that holds tool_result blocks. Each result carries the tool_use_id of the request it answers, plus content and an optional is_error.
  • Formatting rules from the docs: the tool results must come right after the assistant message that asked for them, and in the user message the tool_result blocks must come first. Any text goes after them.
  • Claude can ask for several tools in one turn. Answer every tool_use id with a matching tool_result.
  • The loop ends when stop_reason is something other than tool_use (for example end_turn).
  • Tool results often carry content from outside your control, such as web pages or emails. Treat it as untrusted: it may contain instructions meant to trick Claude (prompt injection).
  • Why do this by hand? The tool runner is simpler, but Anthropic's docs say to use the manual loop when you need human-in-the-loop approval, custom logging or conditional execution. That is exactly what this course adds.
MessageWho sends itWhat is inside
1You (user)The question
2Claude (assistant)Text plus tool_use blocks, stop_reason: tool_use
3You (user)tool_result blocks, one per tool_use id
4Claude (assistant)The final answer, stop_reason: end_turn (or more tool calls)
Example (Python, a manual loop; tested with a stand-in for the API)
import anthropic

client = anthropic.Anthropic() # reads ANTHROPIC_API_KEY

TOOLS = [{
  "name": "check_stock",
  "description": "Check how many units of a product are in stock. Use the exact product name, for example 'blue mug'.",
  "input_schema": {
    "type": "object",
    "properties": {"item": {"type": "string", "description": "Product name"}},
    "required": ["item"],
  },
}]
STOCK = {"blue mug": 12, "red mug": 0}

def check_stock(item):
  return str(STOCK[item.lower()])

messages = [{"role": "user", "content": "Do we have blue mugs and red mugs?"}]
while True:
  response = client.messages.create(
    model="claude-opus-5-5", max_tokens=1024, tools=TOOLS, messages=messages
  )
  if response.stop_reason != "tool_use":
    break
  messages.append({"role": "assistant", "content": response.content})
  results = []
  for block in response.content:
    if block.type == "tool_use":
      results.append({
        "type": "tool_result",
        "tool_use_id": block.id,
        "content": check_stock(**block.input),
      })
  messages.append({"role": "user", "content": results})

print("".join(b.text for b in response.content if b.type == "text"))

This loop has no limit and no error handling yet. Lessons 3 and 5 fix both.

Step by step
  1. Make a folder and a Python virtual environment, then run pip install anthropic (names of commands can differ on Windows).
  2. Set your key in the ANTHROPIC_API_KEY environment variable. Never type it into the file.
  3. Create loop.py and paste the example above.
  4. Run it with python loop.py.
  5. Before the final print, add print(messages) and run again. Find the tool_use block and the matching tool_result block.
  6. Check: you can point at the tool_use_id in your result and find the same id in Claude's request.
Watch on YouTube
Tips for building AI agentsAnthropic · YouTube · youtube.com
Getting Started with Tool Use in the Anthropic APIRam Vegiraju · YouTube · youtube.com

Videos by other creators on YouTube, for reference. They are not made by or affiliated with The Future Market.

LESSON 01Open the loop (the manual agent loop)
LESSON 01 / ANIMATED LESSON / AI VOICE00:00 / 01:15
Read the video script
[Host] "An agent is a loop. Today we open it up."
[Screen: the message table] "You ask. Claude answers with a tool request. You run the tool and send back a result with the same id."
[Text on screen: stop_reason: tool_use] "While the stop reason says tool use, the loop keeps going."
[Screen: the while loop in the editor] "Run the tools, append the results, call Claude again."
[Host] "Once you see the loop, every agent framework makes sense."
Try it now

Run the loop with a question that needs both mugs. Print len(response.content) on the first turn to see whether Claude asked for both tools at once. Then write two sentences explaining why every tool_use id needs a tool_result.

ClaudeStuck? Copy a ready-made prompt for Claude

Copy this, open Claude, paste it, and Claude will walk you through the lesson step by step.

For a grown-up: Claude is for adults (18+). Copy this, paste it into Claude, and use the answer to explain the lesson to your child.

I'm learning "Multi-Step Agents: tools, memory and reliability" on The Future Market. Lesson 1: "Open the loop (the manual agent loop)".

What the lesson teaches:
- When Claude wants to use a client tool, the response has stop_reason of tool_use and one or more tool_use blocks. Each block has an id, a name and an input (the arguments).
- Your code runs the tool, then sends a new user message that holds tool_result blocks. Each result carries the tool_use_id of the request it answers, plus content and an optional is_error.
- Formatting rules from the docs: the tool results must come right after the assistant message that asked for them, and in the user message the tool_result blocks must come first. Any text goes after them.
- Claude can ask for several tools in one turn. Answer every tool_use id with a matching tool_result.
- The loop ends when stop_reason is something other than tool_use (for example end_turn).
- Tool results often carry content from outside your control, such as web pages or emails. Treat it as untrusted: it may contain instructions meant to trick Claude (prompt injection).
- Why do this by hand? The tool runner is simpler, but Anthropic's docs say to use the manual loop when you need human-in-the-loop approval, custom logging or conditional execution. That is exactly what this course adds.

The exercise I'm working on:
Run the loop with a question that needs both mugs. Print len(response.content) on the first turn to see whether Claude asked for both tools at once. Then write two sentences explaining why every tool_use id needs a tool_result.

I'm stuck. Please:
1. Explain the main idea in plain, simple words with one everyday example.
2. Walk me through the exercise one small step at a time. Ask me what I've done so far before giving the next step.
3. Don't just give me the final answer. Help me do it myself, and check my work when I share it.
I'm a parent helping my child (about 8 years old) with a lesson called "Open the loop (the manual agent loop)" from the course "Multi-Step Agents: tools, memory and reliability".

Here's what the lesson says:
In course 1.4 a robot did the errands and you only saw the result. Now you hold the clipboard. Claude says "please check the stock room," you go and check, you write the answer on the clipboard and hand it back. Then Claude decides what to ask next. That back and forth is the whole agent.

The activity:
Run the loop with a question that needs both mugs. Print len(response.content) on the first turn to see whether Claude asked for both tools at once. Then write two sentences explaining why every tool_use id needs a tool_result.

Please explain this so an 8-year-old understands: short sentences, a fun everyday example, and no hard words.
Then give me 3 simple questions I can ask my child to check they understood, and a way to do the activity together, one tiny step at a time.
Open Claude
Sources
My notes
02

Several tools, designed well

This lesson is part of full access: every course and every level for one payment.

03

When a tool fails (error recovery)

This lesson is part of full access: every course and every level for one payment.

04

Memory and context across many steps

This lesson is part of full access: every course and every level for one payment.

05

Limits and logs

This lesson is part of full access: every course and every level for one payment.

06

Human approval for risky steps

This lesson is part of full access: every course and every level for one payment.

07

Test the agent without paying for every run

This lesson is part of full access: every course and every level for one payment.

++

Final project

This lesson is part of full access: every course and every level for one payment.

??

Quiz

  1. What does stop_reason "tool_use" mean?

  2. What must each tool_result contain so Claude knows which request it answers?

  3. Where must tool_result blocks go in the user message?

  4. How do you tell Claude a tool failed?

  5. What makes a good error message for a tool?

  6. What does the memory tool do, and who runs it?

  7. Why must you validate paths in a memory handler?

  8. How can you keep a long run from going on forever?

  9. When do Anthropic's docs suggest the manual loop instead of the tool runner?

  10. Which kinds of actions should need human approval?

  11. How can you test your loop without paying for API calls?

EX

Final exam

This lesson is part of full access: every course and every level for one payment.

CE

Certificate

This lesson is part of full access: every course and every level for one payment.