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
- The Model — Claude makes decisions
- Tools — Functions Claude can call
- The Loop — Code that ties everything together
- Memory — Conversation history
Example: Agent with Tools
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
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
- Set max steps — Prevent infinite loops
- Set token budgets — Prevent runaway costs
- Log every step — For debugging and monitoring
- Human-in-the-loop — Require approval for dangerous actions
- Start simple — Begin with 1-2 tools, add more gradually
Summary
- Agent = Model + Tools + Loop
- Core pattern: Observe -> Think -> Act -> Repeat
- Use
toolsin 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.