By the end of this tutorial you will have a small agent that takes a research question, searches the web, reads a few pages and writes a short answer with sources. It is deliberately simple so you can see every moving part.
What you’ll build
A command-line agent with:
- one tool for web search and one for fetching a page,
- a loop with a hard limit of ten steps,
- a stopping rule the model must satisfy,
- a plain text trace so you can see what it did.
Step 1: Set up the project
Create a folder, a virtual environment and install the SDK for your model provider plus httpx for fetching pages.
mkdir research-agent && cd research-agent
python -m venv .venv && source .venv/bin/activate
pip install httpx anthropic
Put your API key in an environment variable. Never hard-code it.
Step 2: Define the tools
Tools are ordinary functions plus a JSON schema the model can read. Keep the descriptions specific: the model picks tools based on them.
import httpx
def search(query: str) -> str:
"""Search the web. Returns titles and URLs, one per line."""
r = httpx.get("https://api.example-search.com", params={"q": query}, timeout=20)
return "\n".join(f"{x['title']} — {x['url']}" for x in r.json()["results"][:5])
def fetch(url: str) -> str:
"""Fetch a page and return the first 4000 characters of text."""
r = httpx.get(url, timeout=20, follow_redirects=True)
return r.text[:4000]
TOOLS = [
{"name": "search", "description": search.__doc__,
"input_schema": {"type": "object", "properties": {"query": {"type": "string"}}, "required": ["query"]}},
{"name": "fetch", "description": fetch.__doc__,
"input_schema": {"type": "object", "properties": {"url": {"type": "string"}}, "required": ["url"]}},
]
Step 3: Write the loop
This is the agent. Everything else is plumbing.
import anthropic
client = anthropic.Anthropic()
SYSTEM = """You are a research agent. Use search and fetch to answer the question.
Stop only when you can cite at least two sources. Answer in under 150 words."""
def run(question: str, max_steps: int = 10) -> str:
messages = [{"role": "user", "content": question}]
for step in range(max_steps):
resp = client.messages.create(model="claude-sonnet-5-5", max_tokens=1024,
system=SYSTEM, tools=TOOLS, messages=messages)
messages.append({"role": "assistant", "content": resp.content})
if resp.stop_reason != "tool_use":
return "".join(b.text for b in resp.content if b.type == "text")
results = []
for block in resp.content:
if block.type == "tool_use":
fn = {"search": search, "fetch": fetch}[block.name]
out = fn(**block.input)
print(f"[step {step}] {block.name}({block.input}) -> {len(out)} chars")
results.append({"type": "tool_result", "tool_use_id": block.id, "content": out})
messages.append({"role": "user", "content": results})
return "Stopped: step limit reached."
Step 4: Add the stopping rule
Notice the system prompt says “stop only when you can cite at least two sources”. That is the stopping rule. The max_steps cap is the safety net for when the model ignores it. You need both.
Step 5: Run it
if __name__ == "__main__":
print(run("What changed in the EU AI Act timeline in 2026?"))
You should see a handful of search and fetch lines in the trace, then a short answer with two or more URLs.
What to improve next
- Trim tool results. Four thousand characters per page adds up. Extract the main text first.
- Add tracing. Pipe each step to Langfuse or a simple JSON log so you can replay failures.
- Add a verifier. A second model call that checks the answer actually cites two sources before you return it.
If you want the same thing without code, our tools page covers n8n, which has a visual agent node that does this loop for you.
Questions, answered
Which model should I use for my first AI agent?
Use a mid-tier model with strong tool-calling support while you build. It is cheaper and fast enough to iterate on. Switch to a top model only once the loop works.
How do I stop an AI agent running forever?
Set a hard cap on loop iterations (10 is a good start), a token or cost budget, and a clear done condition the model must satisfy before it is allowed to stop.
How much does it cost to run a simple agent?
A ten-step research agent on a mid-tier model typically costs a few cents per run. Costs climb quickly with long documents in context, so trim tool results before feeding them back.