HomePrompt EngineeringBuilding AI Agent Loops
advanced18 min read· Module 7, Lesson 5

🤖Building AI Agent Loops

The observe-think-act agent pattern with tool use and multi-step reasoning

Building AI Agent Loops

An AI agent is a system that uses a large language model (like Claude) to make decisions and take actions autonomously. Instead of a single question and answer, an agent works in a loop: observe -> think -> act -> observe until it achieves the goal.

The Core Pattern

Goal -> Observe -> Think -> Act -> (repeat until done)

Core Components

  1. The Model — Claude makes decisions
  2. Tools — Functions Claude can call
  3. The Loop — Code that ties everything together
  4. Memory — Conversation history

Example: Agent with Tools

JavaScript
import Anthropic from "@anthropic-ai/sdk"; const client = new Anthropic(); const tools = [ { name: "calculate", description: "Evaluates a mathematical expression", input_schema: { type: "object", properties: { expression: { type: "string", description: "Math expression" } }, required: ["expression"] } }, { name: "get_exchange_rate", description: "Gets currency exchange rate", input_schema: { type: "object", properties: { from: { type: "string" }, to: { type: "string" } }, required: ["from", "to"] } } ]; function executeTool(name, input) { if (name === "calculate") { try { return { result: Function(`"use strict"; return (${input.expression})`)() }; } catch (e) { return { error: e.message }; } } if (name === "get_exchange_rate") { const rates = { "USD_EUR": 0.92, "USD_GBP": 0.79 }; return { rate: rates[`${input.from}_${input.to}`] || "unavailable" }; } return { error: "Unknown tool" }; } async function agentLoop(userMessage) { const messages = [{ role: "user", content: userMessage }]; while (true) { const response = await client.messages.create({ model: "claude-sonnet-4-20250514", max_tokens: 1024, tools, messages, }); if (response.stop_reason === "end_turn") { const textContent = response.content.find(c => c.type === "text"); return textContent?.text || ""; } if (response.stop_reason === "tool_use") { messages.push({ role: "assistant", content: response.content }); const toolResults = []; for (const block of response.content) { if (block.type === "tool_use") { console.log(`Tool: ${block.name}(${JSON.stringify(block.input)})`); const result = executeTool(block.name, block.input); toolResults.push({ type: "tool_result", tool_use_id: block.id, content: JSON.stringify(result), }); } } messages.push({ role: "user", content: toolResults }); } } } const answer = await agentLoop( "How much is $500 in euros, and if I pay 20% tax, how much is left?" ); console.log(answer);

Python Agent

Python
import anthropic import json client = anthropic.Anthropic() tools = [ { "name": "search_database", "description": "Search the customer database", "input_schema": { "type": "object", "properties": {"query": {"type": "string"}}, "required": ["query"], }, }, { "name": "send_email", "description": "Send an email", "input_schema": { "type": "object", "properties": { "to": {"type": "string"}, "subject": {"type": "string"}, "body": {"type": "string"}, }, "required": ["to", "subject", "body"], }, }, ] def execute_tool(name, tool_input): if name == "search_database": return {"results": [{"name": "Alice", "email": "alice@example.com"}]} if name == "send_email": return {"status": "sent"} return {"error": "Unknown tool"} def agent_loop(user_message, max_steps=10): messages = [{"role": "user", "content": user_message}] for step in range(max_steps): response = client.messages.create( model="claude-sonnet-4-20250514", max_tokens=1024, tools=tools, messages=messages, ) if response.stop_reason == "end_turn": for block in response.content: if block.type == "text": return block.text return "" if response.stop_reason == "tool_use": messages.append({"role": "assistant", "content": response.content}) tool_results = [] for block in response.content: if block.type == "tool_use": result = execute_tool(block.name, block.input) tool_results.append({ "type": "tool_result", "tool_use_id": block.id, "content": json.dumps(result), }) messages.append({"role": "user", "content": tool_results}) return "Max steps reached" result = agent_loop("Find Alice and send her a meeting invite for tomorrow") print(result)

When to Build an Agent

  • Task requires multiple steps — search + analyze + write
  • Needs external information — APIs, databases, files
  • Decisions depend on results — next step determined by previous result

When NOT to Build an Agent

  • Simple Q&A — just use a regular API call
  • Deterministic tasks — use traditional code
  • Time-critical tasks — agents can be slow

Best Practices

  1. Set max steps — Prevent infinite loops
  2. Set token budgets — Prevent runaway costs
  3. Log every step — For debugging and monitoring
  4. Human-in-the-loop — Require approval for dangerous actions
  5. Start simple — Begin with 1-2 tools, add more gradually

Summary

  • Agent = Model + Tools + Loop
  • Core pattern: Observe -> Think -> Act -> Repeat
  • Use tools in the API to give Claude capabilities
  • Set max steps and token budgets
  • Start simple and add complexity gradually

Next: We'll build a practical project — a Document Analyzer.