Build an AI Web Research Agent
Bright Leaf Coffee's marketing team, referenced throughout this site's Google Ads and Content Marketing series, needs regular competitive research — this part builds a real agent to do it, using part 10's web search tool.
The real, complete research agent
tools = [
{
"name": "web_search",
"description": "Search the web for real, current information",
"input_schema": {
"type": "object",
"properties": {"query": {"type": "string"}},
"required": ["query"],
},
},
]
SYSTEM_PROMPT = """You research competitors for Bright Leaf Coffee,
a small-batch coffee subscription business. When asked to research
a topic, search multiple real, specific queries to build a complete
picture — do not rely on a single search. Cite the real source URL
for every claim. If you can't find real, current information on
something, say so directly rather than guessing."""
def run_research_agent(request: str) -> str:
messages = [{"role": "user", "content": request}]
for _ in range(8): # research genuinely needs more real steps
# than the inventory agent's simpler task
response = client.messages.create(
model="claude-sonnet-5", max_tokens=2048,
system=SYSTEM_PROMPT, tools=tools, messages=messages,
)
messages.append({"role": "assistant", "content": response.content})
if response.stop_reason != "tool_use":
return response.content[0].text
tool_call = next(b for b in response.content if b.type == "tool_use")
result = web_search(**tool_call.input)
messages.append({
"role": "user",
"content": [{"type": "tool_result", "tool_use_id": tool_call.id, "content": str(result)}],
})
return "Research incomplete after maximum steps — review manually."A real, concrete example run
print(run_research_agent(
"Research current subscription pricing for 3 direct competitors "
"in the small-batch coffee subscription space."
))Real, expected execution trace:
Iteration 1: web_search("small batch coffee subscription pricing 2026")
Iteration 2: web_search("[Competitor A] subscription plans pricing")
Iteration 3: web_search("[Competitor B] subscription plans pricing")
Iteration 4: web_search("[Competitor C] subscription plans pricing")
Iteration 5: synthesizes findings into a final, real, structured
report, with a source URL cited for every specific pricing claimNotice the agent genuinely decided to run four separate real searches rather than one — exactly the "search multiple, specific queries" instruction from the system prompt, directly shaping real, observed behavior.
The explicit "cite the real source URL for every claim" instruction directly extends the AI Projects series' own citation technique into an agent context — for a real competitive research report the marketing team will actually use to make decisions, an unsourced claim about a competitor's pricing is genuinely much less useful (and much riskier if wrong) than one a person can independently verify.
Why a research agent genuinely needs MORE loop iterations than part 6's version
Part 6's inventory agent: a real, bounded task with a predictable,
small number of real steps (check stock, check lead time, reorder)
This research agent: a genuinely open-ended task where the right
number of real searches depends entirely on how much real
information is actually needed for a complete pictureThis is exactly why max_iterations (part 18 of the LLM & Advanced AI series) is set higher here — a real, honest reflection of this task's genuinely different shape, not an arbitrary number.
A real, structured output for the marketing team to actually use
SYSTEM_PROMPT += """
Present your final findings as a structured comparison:
Competitor | Price | Plan Details | Source URL
"""Requesting a real, structured comparison format — directly applying the AI Fundamentals series' own explicit-formatting technique — produces a genuinely more usable real deliverable than unstructured prose, ready to drop directly into a real team document.
A real, honest limitation: search results can be wrong or outdated
Web search results are themselves NOT guaranteed accurate or current
— the agent's own honest "cite sources" discipline is what lets a
real, human reviewer catch a genuinely stale or incorrect search
result before treating it as reliable competitive intelligenceThis is the same honest, calibrated caution this entire site's AI series apply consistently — a real, useful research assistant, not an infallible one, with citations as the practical, real safeguard against blind trust.
Next: teaching your research agent to cite sources more rigorously — real, structured citation tracking beyond a plain URL mention.