Pick a depth. Each prompt opens in your AI pre-loaded with the lesson. Click a row to preview the prompt.
Start the smallest. A true agent needs: one tool, a loop, a hard iteration cap, and a way to stop. The minimal example fits in 30 lines and exposes the core mechanics: tool definition, model decision, tool execution, result handoff, loop. Master the minimum before reaching for LangGraph or LlamaIndex; otherwise you're debugging the framework, not your agent.
The pattern: define a tool's schema, send it to the model with a user message, the model either generates end_turn (final answer) or tool_use (call the tool). On tool_use, execute the tool, append the result as a tool_result message, loop. Iteration cap prevents infinite loops. This is the entire agentic primitive — everything else (sub-agents, memory, planning) is layered on top.
from anthropic import Anthropic
import json
client = Anthropic()
# One tool
TOOLS = [{
"name": "get_weather",
"description": "Get the current weather for a city.",
"input_schema": {
"type": "object",
"properties": {"city": {"type": "string", "description": "City name"}},
"required": ["city"],
},
}]
def get_weather(city):
# call your weather API
return {"city": city, "temp_c": 22, "conditions": "sunny"}
def run_agent(user_msg, max_steps=4):
messages = [{"role": "user", "content": user_msg}]
for step in range(max_steps):
resp = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=800,
tools=TOOLS,
messages=messages,
)
messages.append({"role": "assistant", "content": resp.content})
if resp.stop_reason == "end_turn":
return resp.content[0].text
# execute every tool_use block
tool_results = []
for block in resp.content:
if block.type == "tool_use":
if block.name == "get_weather":
result = get_weather(block.input["city"])
else:
result = {"error": "unknown tool"}
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": json.dumps(result),
})
messages.append({"role": "user", "content": tool_results})
return "(agent reached max_steps without finishing)"
print(run_agent("What's the weather in Paris and Berlin?"))
# Expected: model calls get_weather twice (often in parallel), then answers
# with both temperatures. ~2 LLM calls + 2 tool calls.python3 main.py