langgraphresearchagents

LangGraph Deep Research Search Layer

Search layer architecture for LangGraph deep research agents. Problem: search quality and cost at 50-200 queries/task. Solution: structured API with budget caps.

9 min

Deep research agents built on LangGraph typically make 50-200 search queries per task. At SerpAPI pricing ($0.015-$0.036/query effective), a single research task costs $0.75-$7.20 just for search. Switching to a credit-based search API with budget caps keeps costs predictable and prevents runaway spending when agents enter search loops.

The problem: uncontrolled search costs

LangGraph deep research agents follow a plan-search-analyze-repeat cycle. Each cycle generates multiple search queries. A complex research task ("analyze the competitive landscape of CRM tools for SMBs") can trigger 150+ searches as the agent explores subtopics, verifies claims, and fills knowledge gaps. Without budget controls, costs are unbounded.

LangGraph agent with budgeted search

Python
import os, requests
from langgraph.graph import StateGraph, END
from typing import TypedDict, Annotated

class ResearchState(TypedDict):
    query: str
    search_results: list
    analysis: str
    budget_remaining: float
    searches_made: int

COST_PER_QUERY = 0.005
H = {"x-api-key": os.environ["SCAVIO_API_KEY"]}

def search_node(state: ResearchState) -> ResearchState:
    """Execute search with budget check."""
    if state["budget_remaining"] < COST_PER_QUERY:
        return {**state, "search_results": [],
                "analysis": "Budget exhausted. Returning partial results."}
    resp = requests.post("https://api.scavio.dev/api/v1/search",
        headers=H, json={"query": state["query"], "platform": "google"})
    results = resp.json().get("organic_results", [])[:5]
    return {
        **state,
        "search_results": results,
        "budget_remaining": state["budget_remaining"] - COST_PER_QUERY,
        "searches_made": state["searches_made"] + 1,
    }

def should_continue(state: ResearchState) -> str:
    if state["budget_remaining"] < COST_PER_QUERY:
        return END
    if state["searches_made"] >= 50:
        return END
    return "search"

graph = StateGraph(ResearchState)
graph.add_node("search", search_node)
graph.add_conditional_edges("search", should_continue)
graph.set_entry_point("search")

Multi-platform search for richer context

Python
def multi_platform_search(query: str, platforms: list = None):
    """Search across platforms for comprehensive research."""
    platforms = platforms or ["google", "reddit", "youtube"]
    results = {}
    for platform in platforms:
        resp = requests.post("https://api.scavio.dev/api/v1/search",
            headers=H, json={"query": query, "platform": platform})
        results[platform] = resp.json().get("organic_results", [])[:5]
    return results
    # Cost: 3 platforms x $0.005 = $0.015 per multi-platform search
    # vs single-platform: $0.005
    # Richer context for the agent to analyze

Cost comparison for a 100-query research task

  • SerpAPI Developer ($75/mo for 5K): $1.50 effective cost. Eats 2% of monthly quota per task
  • Tavily ($0.008/credit, basic): $0.80 per task. AI-summarized results, less structured
  • Scavio ($0.005/credit): $0.50 per task. Structured JSON, multi-platform
  • Exa ($5/1K requests): $0.50 per task. Semantic search, different result quality

Design pattern: search budget as agent constraint

The budget cap is not just a cost control -- it is a design constraint that forces the agent to be efficient. An agent with unlimited searches will over-search, making redundant queries for information it already has. A budgeted agent must decide: "is this search worth $0.005 given what I already know?" This decision-making produces better research output because the agent prioritizes high-value queries.