Tutorial

How to Add Search to a Deep Research Agent

Wire multi-platform search into a deep research agent's search-read-compute loop. Python implementation with budget controls.

Deep research agents iterate through search-read-compute loops: query a topic, extract data from results, reason over findings, then search again with refined queries. The quality of the search step determines whether the agent grounds its analysis in real data or hallucinates. This tutorial wires multi-platform search into a research agent, giving it Google, Reddit, and YouTube in each iteration at $0.005 per query.

Prerequisites

  • Python 3.10+
  • requests library installed
  • A Scavio API key from scavio.dev
  • An OpenAI API key for reasoning

Walkthrough

Step 1: Build the multi-platform search function

Create a search that queries multiple platforms and merges results for the LLM.

Python
import os, requests, json

SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
OPENAI_KEY = os.environ['OPENAI_API_KEY']
SH = {'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json'}

def multi_search(query, platforms=None):
    if platforms is None: platforms = ['google', 'reddit']
    all_results = []
    for platform in platforms:
        resp = requests.post('https://api.scavio.dev/api/v1/search',
            headers=SH, json={'query': query, 'platform': platform, 'country_code': 'us'})
        for r in resp.json().get('organic_results', [])[:3]:
            all_results.append({'platform': platform, 'title': r.get('title', ''),
                'snippet': r.get('snippet', ''), 'url': r.get('link', '')})
    return all_results

def format_context(results):
    return '\n\n'.join(f"[{r['platform'].upper()}] {r['title']}\n{r['snippet']}" for r in results)

Step 2: Implement the research loop

The agent decides what to search, analyzes results, and determines whether to continue or produce output.

Python
def llm_call(system, user):
    resp = requests.post('https://api.openai.com/v1/chat/completions',
        headers={'Authorization': f'Bearer {OPENAI_KEY}', 'Content-Type': 'application/json'},
        json={'model': 'gpt-4o', 'temperature': 0,
            'messages': [{'role': 'system', 'content': system}, {'role': 'user', 'content': user}]})
    return resp.json()['choices'][0]['message']['content']

def research_loop(topic, max_iterations=5):
    findings = []
    search_count = 0
    for i in range(max_iterations):
        plan = json.loads(llm_call('Return JSON only.',
            f'Topic: {topic}\nFindings: {json.dumps(findings[-3:])}\n'
            f'Return: {{"query": "...", "platforms": [...], "done": bool}}'))
        if plan.get('done'): break
        results = multi_search(plan['query'], plan.get('platforms', ['google']))
        search_count += len(plan.get('platforms', ['google']))
        analysis = llm_call('Extract key facts.', f'Results:\n{format_context(results)}')
        findings.append({'query': plan['query'], 'analysis': analysis})
        print(f'  [{i+1}] "{plan["query"]}" -> {len(results)} results')
    return findings, search_count

Step 3: Generate the final report

Synthesize all findings into a structured report with citations.

Python
def generate_report(topic, findings, search_count):
    text = '\n'.join(f"Query: {f['query']}\n{f['analysis']}" for f in findings)
    report = llm_call('Write a structured report with key findings.', f'Topic: {topic}\n\n{text}')
    print(f'\n{report[:500]}')
    print(f'\nSearches: {search_count}, Cost: ${search_count * 0.005:.3f}')
    return report

findings, count = research_loop('SERP API trends 2026')
generate_report('SERP API trends 2026', findings, count)

Step 4: Add budget controls

Prevent runaway costs with a hard budget cap.

Python
def research_with_budget(topic, max_budget=0.50, max_iter=10):
    findings, total_cost = [], 0.0
    for i in range(max_iter):
        remaining = int((max_budget - total_cost) / 0.005)
        if remaining < 1:
            print(f'  Budget exhausted at ${total_cost:.3f}')
            break
        plan = json.loads(llm_call('Return JSON only.',
            f'Topic: {topic}\nFindings: {json.dumps(findings[-3:])}\n'
            f'Budget: {remaining} searches left\n'
            f'Return: {{"query": "...", "platforms": [...], "done": bool}}'))
        if plan.get('done'): break
        platforms = plan.get('platforms', ['google'])[:remaining]
        results = multi_search(plan['query'], platforms)
        total_cost += len(platforms) * 0.005
        analysis = llm_call('Extract key facts.', f'Results:\n{format_context(results)}')
        findings.append({'query': plan['query'], 'analysis': analysis})
        print(f'  [{i+1}] ${total_cost:.3f} spent')
    return findings, total_cost

research_with_budget('search API comparison', max_budget=0.25)

Python Example

Python
import os, requests, json

SK = os.environ['SCAVIO_API_KEY']
SH = {'x-api-key': SK, 'Content-Type': 'application/json'}

def search(query, platform='google'):
    data = requests.post('https://api.scavio.dev/api/v1/search',
        headers=SH, json={'query': query, 'platform': platform, 'country_code': 'us'}).json()
    return [{'title': r['title'], 'snippet': r.get('snippet', '')}
            for r in data.get('organic_results', [])[:3]]

def research(topic, queries):
    for q in queries:
        g = search(q)
        r = search(q, 'reddit')
        print(f'"{q}": {len(g)} Google + {len(r)} Reddit')
    print(f'Cost: ${len(queries) * 2 * 0.005:.3f}')

research('AI search', ['best search api agents 2026', 'tavily alternatives reddit'])

JavaScript Example

JavaScript
const SK = process.env.SCAVIO_API_KEY;
const SH = { 'x-api-key': SK, 'Content-Type': 'application/json' };

async function search(query, platform = 'google') {
  const data = await fetch('https://api.scavio.dev/api/v1/search', {
    method: 'POST', headers: SH,
    body: JSON.stringify({ query, platform, country_code: 'us' })
  }).then(r => r.json());
  return (data.organic_results || []).slice(0, 3);
}

async function research(queries) {
  for (const q of queries) {
    const g = await search(q);
    const r = await search(q, 'reddit');
    console.log(`"${q}": ${g.length}G + ${r.length}R`);
  }
  console.log(`Cost: $${(queries.length * 2 * 0.005).toFixed(3)}`);
}
research(['best search api 2026', 'tavily alternatives']).catch(console.error);

Expected Output

JSON
  [1] "AI agent search API comparison 2026" -> 6 results
  [2] "tavily vs scavio vs exa agents" -> 3 results
  [3] "self-hosted search SearXNG agents" -> 6 results
  [4] Research complete.

Searches: 5, Cost: $0.025

Related Tutorials

Frequently Asked Questions

Most developers complete this tutorial in 15 to 30 minutes. You will need a Scavio API key (free tier works) and a working Python or JavaScript environment.

Python 3.10+. requests library installed. A Scavio API key from scavio.dev. An OpenAI API key for reasoning. A Scavio API key gives you 250 free credits per month.

Yes. The free tier includes 250 credits per month, which is more than enough to complete this tutorial and prototype a working solution.

Scavio has a native LangChain package (langchain-scavio), an MCP server, and a plain REST API that works with any HTTP client. This tutorial uses the raw REST API, but you can adapt to your framework of choice.

Start Building

Wire multi-platform search into a deep research agent's search-read-compute loop. Python implementation with budget controls.