ScavioScavio
ProductPricingDocs
Sign InGet Started
  1. Home
  2. Tutorials
  3. How to Add Search to a Multi-Agent System with Caching
Tutorial

How to Add Search to a Multi-Agent System with Caching

Add a shared search tool to CrewAI, AutoGen, or custom multi-agent systems. Includes a dedup cache to prevent agents from repeating the same query.

Get Free API KeyAPI Docs

Adding shared search capability to a multi-agent system lets each agent ground its reasoning in live web data without duplicating queries or blowing through API credits. The core pattern is a thin wrapper around a search API (like Scavio) combined with an in-memory or Redis-backed cache keyed by query hash. Each agent calls the shared tool, and the cache ensures identical queries across agents return instantly from the local store. This tutorial builds the shared search tool, wires it into CrewAI as an example, and shows how to adapt it for AutoGen or a custom orchestrator.

Prerequisites

  • Python 3.10+ installed
  • crewai and requests libraries installed (pip install crewai requests)
  • A Scavio API key from scavio.dev
  • Basic familiarity with multi-agent frameworks

Walkthrough

Step 1: Build the cached search tool

Create a search function with an in-memory cache keyed by the SHA-256 hash of the query and country. Any agent calling this function with the same query gets the cached result, saving credits and latency.

Python
import requests, os, hashlib, json

API_KEY = os.environ.get('SCAVIO_API_KEY', 'your_scavio_api_key')
ENDPOINT = 'https://api.scavio.dev/api/v1/search'
_cache = {}

def cached_search(query: str, country: str = 'us') -> dict:
    key = hashlib.sha256(f'{query}:{country}'.encode()).hexdigest()
    if key in _cache:
        print(f'[cache hit] {query}')
        return _cache[key]
    resp = requests.post(ENDPOINT,
        headers={'x-api-key': API_KEY, 'Content-Type': 'application/json'},
        json={'query': query, 'country_code': country})
    resp.raise_for_status()
    data = resp.json()
    _cache[key] = data
    print(f'[cache miss] {query} -> {len(data.get("organic_results", []))} results')
    return data

Step 2: Wrap as a CrewAI tool

CrewAI tools are decorated functions with a name and description. Wrap the cached search function so any CrewAI agent can call it.

Python
from crewai.tools import tool

@tool('web_search')
def web_search_tool(query: str) -> str:
    '''Search the web for a query and return top 5 results with titles, links, and snippets.'''
    data = cached_search(query)
    results = data.get('organic_results', [])[:5]
    lines = []
    for r in results:
        lines.append(f"Title: {r['title']}")
        lines.append(f"URL: {r['link']}")
        lines.append(f"Snippet: {r.get('snippet', '')}")
        lines.append('')
    return '\n'.join(lines)

Step 3: Assign the tool to multiple agents

Create two agents that share the same search tool. When both agents research overlapping topics, the cache prevents duplicate API calls.

Python
from crewai import Agent, Task, Crew

researcher = Agent(
    role='Market Researcher',
    goal='Find the top 3 CRM tools by market share in 2026',
    backstory='Expert in SaaS market analysis',
    tools=[web_search_tool],
    verbose=True
)

analyst = Agent(
    role='Pricing Analyst',
    goal='Compare pricing tiers of the top CRM tools',
    backstory='Expert in SaaS pricing strategy',
    tools=[web_search_tool],
    verbose=True
)

task1 = Task(description='Research top CRM tools 2026', agent=researcher,
    expected_output='List of top 3 CRM tools with market share')
task2 = Task(description='Compare CRM pricing tiers', agent=analyst,
    expected_output='Pricing comparison table')

crew = Crew(agents=[researcher, analyst], tasks=[task1, task2], verbose=True)
result = crew.kickoff()
print(f'Cache size: {len(_cache)} queries (saved credits on duplicates)')

Step 4: Adapt for AutoGen or custom agents

The same cached_search function works with any orchestrator. For AutoGen, register it as a function. For custom agents, call it directly. The cache is shared across all callers in the same process.

Python
# AutoGen example
from autogen import register_function

def autogen_search(query: str) -> str:
    data = cached_search(query)
    return json.dumps(data.get('organic_results', [])[:5], indent=2)

# Register for any AutoGen agent
# register_function(autogen_search, caller=assistant, executor=user_proxy,
#     name='web_search', description='Search the web')

# Custom agent loop example
def agent_step(agent_name: str, query: str):
    results = cached_search(query)
    organic = results.get('organic_results', [])[:5]
    print(f'[{agent_name}] {query} -> {len(organic)} results')
    return organic

# Both agents share the cache
agent_step('researcher', 'best crm tools 2026')
agent_step('analyst', 'best crm tools 2026')  # cache hit

Python Example

Python
import requests, os, hashlib, json
from crewai import Agent, Task, Crew
from crewai.tools import tool

API_KEY = os.environ.get('SCAVIO_API_KEY', 'your_scavio_api_key')
ENDPOINT = 'https://api.scavio.dev/api/v1/search'
_cache = {}

def cached_search(query: str, country: str = 'us') -> dict:
    key = hashlib.sha256(f'{query}:{country}'.encode()).hexdigest()
    if key in _cache:
        return _cache[key]
    resp = requests.post(ENDPOINT,
        headers={'x-api-key': API_KEY, 'Content-Type': 'application/json'},
        json={'query': query, 'country_code': country})
    resp.raise_for_status()
    _cache[key] = resp.json()
    return _cache[key]

@tool('web_search')
def web_search_tool(query: str) -> str:
    '''Search the web and return top 5 results.'''
    data = cached_search(query)
    results = data.get('organic_results', [])[:5]
    return '\n'.join(f"{r['title']}: {r['link']}" for r in results)

researcher = Agent(role='Researcher', goal='Find top CRM tools',
    backstory='Market analyst', tools=[web_search_tool])
analyst = Agent(role='Analyst', goal='Compare CRM pricing',
    backstory='Pricing expert', tools=[web_search_tool])

task1 = Task(description='Research CRM tools 2026', agent=researcher,
    expected_output='Top 3 CRM tools')
task2 = Task(description='Compare pricing', agent=analyst,
    expected_output='Pricing table')

crew = Crew(agents=[researcher, analyst], tasks=[task1, task2])
result = crew.kickoff()
print(f'Unique queries: {len(_cache)}')
print(result)

JavaScript Example

JavaScript
const API_KEY = process.env.SCAVIO_API_KEY || 'your_scavio_api_key';
const ENDPOINT = 'https://api.scavio.dev/api/v1/search';
const cache = new Map();

async function cachedSearch(query, country = 'us') {
  const key = `${query}:${country}`;
  if (cache.has(key)) return cache.get(key);
  const resp = await fetch(ENDPOINT, {
    method: 'POST',
    headers: { 'x-api-key': API_KEY, 'Content-Type': 'application/json' },
    body: JSON.stringify({ query, country_code: country })
  });
  if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
  const data = await resp.json();
  cache.set(key, data);
  return data;
}

async function agentSearch(agentName, query) {
  const data = await cachedSearch(query);
  const results = (data.organic_results || []).slice(0, 5);
  console.log(`[${agentName}] ${query} -> ${results.length} results (cache size: ${cache.size})`);
  return results;
}

async function main() {
  await agentSearch('researcher', 'best crm tools 2026');
  await agentSearch('analyst', 'best crm tools 2026');
  await agentSearch('analyst', 'crm pricing comparison 2026');
  console.log(`Total unique queries: ${cache.size}`);
}

main().catch(console.error);

Expected Output

JSON
[cache miss] best crm tools 2026 -> 10 results
[cache hit] best crm tools 2026
[cache miss] crm pricing comparison 2026 -> 10 results
Total unique queries: 2

Researcher found: Salesforce, HubSpot, Pipedrive
Analyst pricing table:
  Salesforce: $25-$300/user/mo
  HubSpot: $0-$150/user/mo
  Pipedrive: $14-$99/user/mo

Related Tutorials

  • How to Add MCP Search to Claude Code
  • How to Ground a Local LLM with Structured Search
  • How to Build a Cross-Platform Search Pipeline

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+ installed. crewai and requests libraries installed (pip install crewai requests). A Scavio API key from scavio.dev. Basic familiarity with multi-agent frameworks. A Scavio API key gives you 50 free credits on signup.

Yes. The free tier includes 50 credits on signup, 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.

Related Resources

Solution

Add Unified Search to Multi-Agent Systems with Scavio

Read more
Best Of

Best Multi-Agent Search Tool in 2026

Read more
Best Of

Best Search API for CrewAI Agents in 2026

Read more
Use Case

Multi-Agent System Search Integration

Read more
Use Case

Pi Coding Agent Web Search Integration

Read more
Workflow

Hourly Multi-Agent Search Refresh Workflow

Read more

Start Building

Add a shared search tool to CrewAI, AutoGen, or custom multi-agent systems. Includes a dedup cache to prevent agents from repeating the same query.

Get Free API KeyRead the Docs
ScavioScavio

Real-time search API for AI agents. Search every platform, not just Google.

Product

  • Features
  • Pricing
  • Dashboard
  • Affiliates

Developers

  • Documentation
  • API Reference
  • Quickstart
  • MCP Integration
  • Python SDK

Alternatives

  • Tavily Alternative
  • SerpAPI Alternative
  • Firecrawl Alternative
  • Exa Alternative

Tools

  • JSON Formatter
  • cURL to Code
  • Token Counter
  • All Tools

© 2026 Scavio. All rights reserved.

Featured on TAAFT
Terms of ServicePrivacy Policy