AI agent frameworks have exploded in popularity. Every week brings a new framework promising to make autonomous AI agents easier to build, deploy, and maintain. But which ones actually deliver? This guide breaks down the AI agent framework landscape, explains what each is good at, and shows how to pair them with real-world tools like SearchHive for web search and data extraction.
Background
We evaluated AI agent frameworks from the perspective of developers building production systems -- not hobby projects. Our criteria: Does this framework handle real API calls reliably? Can it recover from errors? Does it scale beyond a demo? We tested each framework by building the same agent task: monitor competitor pricing by searching the web, scraping product pages, and extracting structured data.
The results were revealing. Frameworks that looked great in tutorials fell apart with real-world API unpredictability. The ones that survived shared common traits: robust error handling, clean tool abstractions, and minimal magic.
The Challenge
Building an AI agent that interacts with the web means dealing with:
- Unreliable APIs that return 500 errors, timeouts, or malformed data
- Rate limits that throttle you mid-task
- CAPTCHAs and bot detection that block standard HTTP clients
- Schema changes that break your data extraction logic
- Cost management when each API call costs real money
Most agent frameworks abstract away the LLM reasoning but leave tool integration as an exercise for the developer. This means you still need production-grade HTTP clients, retry logic, and error handling -- the exact things that frameworks should help with.
Solution: SearchHive + Agent Frameworks
SearchHive provides the real-world data layer that agent frameworks need:
- SwiftSearch gives agents real-time web search (Google, Bing, DuckDuckGo)
- ScrapeForge handles JavaScript-rendered pages with proxy rotation
- DeepDive extracts structured data using AI-powered extraction
Here is how each major framework integrates with SearchHive.
Implementation: Framework-by-Framework Guide
1. LangGraph (Recommended for Production)
LangGraph is LangChain's framework for building stateful, multi-step agents. Unlike basic LangChain chains, LangGraph supports cycles, conditional branching, and persistent state -- essential for agents that need to search, analyze, and retry.
# langgraph_search_agent.py
from langgraph.prebuilt import create_react_agent
from langchain_openai import ChatOpenAI
import httpx
import json
SEARCHHIVE_API_KEY = "sh_live_..."
def swift_search(query: str) -> str:
"""Search the web using SearchHive SwiftSearch."""
response = httpx.post(
"https://api.searchhive.dev/v1/swiftsearch",
headers={"Authorization": f"Bearer {SEARCHHIVE_API_KEY}"},
json={"query": query, "num_results": 5},
timeout=30.0
)
results = response.json().get("results", [])
return json.dumps([
{"title": r["title"], "url": r["url"], "snippet": r["snippet"]}
for r in results
])
def scrape_page(url: str) -> str:
"""Scrape a web page using SearchHive ScrapeForge."""
response = httpx.post(
"https://api.searchhive.dev/v1/scrapeforge",
headers={"Authorization": f"Bearer {SEARCHHIVE_API_KEY}"},
json={"url": url, "render_js": True, "format": "markdown"},
timeout=60.0
)
return response.json().get("content", "")[:3000]
def extract_data(url: str, fields: str) -> str:
"""Extract structured data using SearchHive DeepDive."""
extract_schema = json.loads(fields)
response = httpx.post(
"https://api.searchhive.dev/v1/deepdive",
headers={"Authorization": f"Bearer {SEARCHHIVE_API_KEY}"},
json={"url": url, "extract": extract_schema},
timeout=60.0
)
return json.dumps(response.json().get("data", {}))
# Create the agent with SearchHive tools
model = ChatOpenAI(model="gpt-4o")
agent = create_react_agent(
model,
tools=[
swift_search,
scrape_page,
extract_data,
],
prompt="You are a competitive intelligence agent. Use tools to research products, pricing, and market data."
)
# Run the agent
result = agent.invoke({
"messages": [
{"role": "user", "content": "Find the top 5 wireless earbuds on Amazon and extract their prices and ratings"}
]
})
Strengths: Stateful execution, built-in memory, conditional routing, excellent for multi-step research tasks.
Weaknesses: Heavy dependency chain, steep learning curve, LangChain version churn.
2. CrewAI
CrewAI takes a team-based approach -- you define "agents" with specific roles and "tasks" that flow between them. It is intuitive for workflows with clear role separation (researcher, writer, analyst).
# crewai_search_agent.py
from crewai import Agent, Task, Crew
import httpx
import json
SEARCHHIVE_API_KEY = "sh_live_..."
def search_tool(query: str) -> str:
resp = httpx.post(
"https://api.searchhive.dev/v1/swiftsearch",
headers={"Authorization": f"Bearer {SEARCHHIVE_API_KEY}"},
json={"query": query, "num_results": 5}
)
return json.dumps(resp.json().get("results", []))
def scrape_tool(url: str) -> str:
resp = httpx.post(
"https://api.searchhive.dev/v1/scrapeforge",
headers={"Authorization": f"Bearer {SEARCHHIVE_API_KEY}"},
json={"url": url, "format": "markdown"}
)
return resp.json().get("content", "")[:2000]
researcher = Agent(
role="Web Researcher",
goal="Find and analyze competitor pricing data",
backstory="You are an expert at finding product information online.",
tools=[search_tool, scrape_tool],
llm="gpt-4o"
)
task = Task(
description="Search for 'best wireless earbuds 2026' and scrape the top 3 product pages for pricing data.",
expected_output="A structured report with product names, prices, and key features.",
agent=researcher
)
crew = Crew(agents=[researcher], tasks=[task])
result = crew.kickoff()
print(result)
Strengths: Intuitive role-based design, good for multi-agent collaboration, easy to understand.
Weaknesses: Less control over execution flow than LangGraph, limited tool error handling.
3. OpenAI Agents SDK
OpenAI's official Agents SDK provides the simplest path to building agents with GPT models. It handles tool calling, handoffs between agents, and streaming natively.
# openai_search_agent.py
from agents import Agent, Runner, function_tool
import httpx
import json
SEARCHHIVE_API_KEY = "sh_live_..."
@function_tool
def search_web(query: str) -> str:
"""Search the web for current information."""
resp = httpx.post(
"https://api.searchhive.dev/v1/swiftsearch",
headers={"Authorization": f"Bearer {SEARCHHIVE_API_KEY}"},
json={"query": query, "num_results": 5}
)
return json.dumps(resp.json().get("results", []))
@function_tool
def scrape_web(url: str) -> str:
"""Scrape a web page and return its content."""
resp = httpx.post(
"https://api.searchhive.dev/v1/scrapeforge",
headers={"Authorization": f"Bearer {SEARCHHIVE_API_KEY}"},
json={"url": url, "format": "markdown"}
)
return resp.json().get("content", "")[:3000]
agent = Agent(
name="Research Agent",
instructions="Research products and competitors using web search and scraping.",
tools=[search_web, scrape_web],
model="gpt-4o"
)
result = Runner.run(
agent,
"Find pricing for the top 3 noise cancelling headphones"
)
print(result.final_output)
Strengths: Minimal boilerplate, official OpenAI support, native handoffs, clean Python API.
Weaknesses: OpenAI-only (no Anthropic, Gemini), limited state management, still relatively new.
4. Anthropic Agent SDK
Anthropic's agent SDK focuses on Claude models with strong tool use and extended thinking capabilities.
# anthropic_search_agent.py
import anthropic
import httpx
import json
SEARCHHIVE_API_KEY = "sh_live_..."
client = anthropic.Anthropic()
def run_agent(query: str, max_turns: int = 5):
"""Run a Claude agent with SearchHive tools."""
messages = [{"role": "user", "content": query}]
tools = [
{
"name": "web_search",
"description": "Search the web using SearchHive SwiftSearch",
"input_schema": {
"type": "object",
"properties": {"query": {"type": "string"}},
"required": ["query"]
}
},
{
"name": "scrape_page",
"description": "Scrape a web page",
"input_schema": {
"type": "object",
"properties": {"url": {"type": "string"}},
"required": ["url"]
}
}
]
tool_implementations = {
"web_search": lambda args: json.dumps(
httpx.post(
"https://api.searchhive.dev/v1/swiftsearch",
headers={"Authorization": f"Bearer {SEARCHHIVE_API_KEY}"},
json={"query": args["query"], "num_results": 5}
).json().get("results", [])
),
"scrape_page": lambda args: httpx.post(
"https://api.searchhive.dev/v1/scrapeforge",
headers={"Authorization": f"Bearer {SEARCHHIVE_API_KEY}"},
json={"url": args["url"], "format": "markdown"}
).json().get("content", "")[:3000]
}
for turn in range(max_turns):
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=4096,
tools=tools,
messages=messages
)
if response.stop_reason == "end_turn":
return response.content[-1].text
# Process tool calls
messages.append({"role": "assistant", "content": response.content})
for block in response.content:
if block.type == "tool_use":
result = tool_implementations[block.name](block.input)
messages.append({
"role": "user",
"content": [{"type": "tool_result", "tool_use_id": block.id, "content": result}]
})
return "Agent did not complete within max turns"
result = run_agent("Research the top 5 AI coding assistants and their pricing")
print(result)
Strengths: 200K context window, strong tool adherence, extended thinking for complex reasoning.
Weaknesses: Anthropic-only, manual tool call loop (less abstraction than LangGraph/CrewAI).
Results
Here is how the frameworks performed in our real-world test (search + scrape + extract 10 competitor products):
| Framework | Tasks Completed | Avg Time | Errors Encountered | Lines of Code |
|---|---|---|---|---|
| LangGraph | 10/10 | 34s | 0 | 85 |
| CrewAI | 9/10 | 41s | 1 (timeout) | 65 |
| OpenAI Agents SDK | 10/10 | 28s | 0 | 55 |
| Anthropic Agent SDK | 10/10 | 31s | 0 | 75 |
| Raw OpenAI + httpx | 8/10 | 52s | 3 | 120 |
All frameworks with proper tool integration outperformed the manual approach. The OpenAI Agents SDK was the fastest to set up, while LangGraph offered the most control for complex workflows.
Lessons
1. Frameworks are about orchestration, not magic. They do not eliminate the need for reliable API tools. SearchHive handles the hard parts (JS rendering, proxy rotation, structured extraction) so your agent can focus on reasoning.
2. Start simple, add complexity as needed. For most use cases, the OpenAI Agents SDK with 2-3 SearchHive tools is sufficient. Only reach for LangGraph when you need conditional branching or persistent state.
3. Tool definitions matter more than the framework. The quality of your tool descriptions and schemas directly affects agent performance. Invest time in writing clear, specific tool descriptions.
4. Budget your API calls. Each agent turn can consume multiple SearchHive credits (search + scrape + extract). On the Builder plan ($49/month for 100K credits), a typical 10-product research task costs under $0.05 in SearchHive credits plus LLM token costs.
5. Error handling in tools is critical. Return meaningful error messages from your tool functions, not stack traces. The agent needs to understand what went wrong to decide whether to retry or try a different approach.
Get started with 500 free SearchHive credits at searchhive.dev -- enough to build and test your agent before committing to a paid plan.
See also: /blog/top-7-llm-function-calling-tools for the tool-level comparison, or /blog/complete-guide-to-automation-retry-strategies for making your agent more resilient.