Tutorial

How to Add Search to a Local Multi-Agent Coding Setup

Give your Pi or llama-swap multi-agent coding setup real-time search. Ground code generation with live documentation and package data.

Local multi-agent coding setups using Pi, llama-swap, or similar tools generate code in a private, offline environment. The problem: they hallucinate API signatures, invent non-existent packages, and use deprecated patterns. Adding a search tool that checks current documentation before generating code fixes this. This tutorial connects your local multi-agent setup to the Scavio API ($0.005/search) so agents can verify APIs, check package versions, and reference current docs.

Prerequisites

  • A local multi-agent setup (Pi, llama-swap, or similar)
  • Python 3.9+ installed
  • requests library installed
  • A Scavio API key from scavio.dev

Walkthrough

Step 1: Build the documentation search tool

Create a search function optimized for code documentation lookups. It targets specific documentation sites and formats results for code context.

Python
import os, requests

SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
URL = 'https://api.scavio.dev/api/v1/search'
H = {'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json'}

def search_docs(query: str, language: str = 'python') -> str:
    """Search for code documentation and API references."""
    # Add language context
    doc_sites = {
        'python': 'docs.python.org OR pypi.org OR readthedocs.io',
        'javascript': 'developer.mozilla.org OR npmjs.com OR nodejs.org',
        'typescript': 'typescriptlang.org OR npmjs.com',
        'rust': 'docs.rs OR crates.io',
    }
    site_filter = doc_sites.get(language, '')
    full_query = f'{query} {language} {site_filter}'.strip()
    resp = requests.post(URL, headers=H,
        json={'query': full_query, 'country_code': 'us', 'num_results': 5})
    results = resp.json().get('organic_results', [])
    if not results:
        return f'No documentation found for: {query}'
    return '\n\n'.join(
        f'[{i+1}] {r["title"]}\n{r.get("snippet", "")}\nURL: {r["link"]}'
        for i, r in enumerate(results)
    )

# Test: search for API documentation
print(search_docs('requests post json headers', 'python'))
print('---')
print(search_docs('fetch api post request', 'javascript'))

Step 2: Add package version checking

Before using a package in generated code, verify it exists and check the current version. This prevents the agent from importing non-existent packages.

Python
def check_package(name: str, language: str = 'python') -> dict:
    """Verify a package exists and get current version info."""
    if language == 'python':
        query = f'pypi.org {name} package'
    elif language in ('javascript', 'typescript'):
        query = f'npmjs.com {name} package'
    else:
        query = f'{name} package {language}'
    resp = requests.post(URL, headers=H,
        json={'query': query, 'country_code': 'us', 'num_results': 3})
    results = resp.json().get('organic_results', [])
    if not results:
        return {'name': name, 'exists': False}
    # Check if pypi/npm appears in results
    registry_hit = any('pypi.org' in r.get('link', '') or 'npmjs.com' in r.get('link', '')
                       for r in results)
    return {
        'name': name,
        'exists': registry_hit,
        'top_result': results[0]['title'],
        'snippet': results[0].get('snippet', '')[:150],
        'url': results[0]['link'],
    }

# Test packages
for pkg in ['requests', 'fastapi', 'nonexistent-fake-pkg-xyz']:
    result = check_package(pkg)
    status = 'EXISTS' if result['exists'] else 'NOT FOUND'
    print(f'[{status}] {pkg}: {result.get("top_result", "N/A")[:50]}')

Step 3: Create the agent tool interface

Define tools that your multi-agent system can call. The search_docs and check_package tools integrate with any OpenAI-compatible tool calling setup.

Python
import json

AGENT_TOOLS = [
    {
        'type': 'function',
        'function': {
            'name': 'search_docs',
            'description': 'Search for programming documentation, API references, and code examples. Use BEFORE writing code that uses external libraries or APIs.',
            'parameters': {
                'type': 'object',
                'properties': {
                    'query': {'type': 'string', 'description': 'What to search for (e.g., "fastapi dependency injection")'},
                    'language': {'type': 'string', 'enum': ['python', 'javascript', 'typescript', 'rust'], 'description': 'Programming language context'}
                },
                'required': ['query']
            }
        }
    },
    {
        'type': 'function',
        'function': {
            'name': 'check_package',
            'description': 'Verify a package exists before importing it. Prevents hallucinated package names.',
            'parameters': {
                'type': 'object',
                'properties': {
                    'name': {'type': 'string', 'description': 'Package name'},
                    'language': {'type': 'string', 'enum': ['python', 'javascript'], 'description': 'Package ecosystem'}
                },
                'required': ['name']
            }
        }
    }
]

def handle_tool_call(name: str, args: dict) -> str:
    if name == 'search_docs':
        return search_docs(args['query'], args.get('language', 'python'))
    elif name == 'check_package':
        result = check_package(args['name'], args.get('language', 'python'))
        return json.dumps(result)
    return 'Unknown tool'

print('Agent tools defined:', [t['function']['name'] for t in AGENT_TOOLS])

Step 4: Wire into the multi-agent loop

Connect the tools to your local multi-agent system. The coding agent searches docs before writing code, and the review agent checks packages before approving.

Python
def coding_agent_loop(task: str, model: str = 'llama3') -> str:
    """A coding agent that searches docs before generating code."""
    llm_url = 'http://localhost:11434/v1/chat/completions'
    messages = [
        {'role': 'system', 'content': (
            'You are a coding assistant. ALWAYS use search_docs to check API '
            'signatures before writing code. ALWAYS use check_package to verify '
            'packages exist before importing them. Write working, tested code.'
        )},
        {'role': 'user', 'content': task}
    ]
    for turn in range(5):
        resp = requests.post(llm_url, json={
            'model': model, 'messages': messages,
            'tools': AGENT_TOOLS, 'max_tokens': 1024
        })
        msg = resp.json()['choices'][0]['message']
        messages.append(msg)
        if not msg.get('tool_calls'):
            return msg.get('content', '')
        for tc in msg['tool_calls']:
            args = json.loads(tc['function']['arguments']) if isinstance(tc['function']['arguments'], str) else tc['function']['arguments']
            result = handle_tool_call(tc['function']['name'], args)
            messages.append({'role': 'tool', 'tool_call_id': tc['id'], 'content': result})
    return messages[-1].get('content', 'Max turns reached')

# Test the coding agent
code = coding_agent_loop('Write a Python function that fetches JSON from an API using httpx')
print(code[:500])

Python Example

Python
import os, requests, json

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

def search_docs(query, lang='python'):
    resp = requests.post('https://api.scavio.dev/api/v1/search', headers=H,
        json={'query': f'{query} {lang} documentation', 'country_code': 'us', 'num_results': 3})
    return '\n'.join(f'[{i+1}] {r["title"]}: {r.get("snippet","")}'
                     for i, r in enumerate(resp.json().get('organic_results', [])))

def check_pkg(name, lang='python'):
    registry = 'pypi.org' if lang == 'python' else 'npmjs.com'
    resp = requests.post('https://api.scavio.dev/api/v1/search', headers=H,
        json={'query': f'{registry} {name}', 'country_code': 'us', 'num_results': 1})
    results = resp.json().get('organic_results', [])
    exists = any(registry in r.get('link', '') for r in results)
    print(f"{'EXISTS' if exists else 'NOT FOUND'}: {name}")

print(search_docs('httpx async client'))
check_pkg('httpx')
check_pkg('fake-nonexistent-pkg')

JavaScript Example

JavaScript
const SCAVIO_KEY = process.env.SCAVIO_API_KEY;

async function searchDocs(query, lang = 'javascript') {
  const resp = await fetch('https://api.scavio.dev/api/v1/search', {
    method: 'POST',
    headers: { 'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json' },
    body: JSON.stringify({ query: `${query} ${lang} documentation`, country_code: 'us', num_results: 3 })
  });
  return ((await resp.json()).organic_results || []).map((r, i) => `[${i+1}] ${r.title}: ${r.snippet || ''}`).join('\n');
}

async function checkPkg(name) {
  const resp = await fetch('https://api.scavio.dev/api/v1/search', {
    method: 'POST',
    headers: { 'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json' },
    body: JSON.stringify({ query: `npmjs.com ${name}`, country_code: 'us', num_results: 1 })
  });
  const results = (await resp.json()).organic_results || [];
  console.log(`${results.some(r => r.link.includes('npmjs.com')) ? 'EXISTS' : 'NOT FOUND'}: ${name}`);
}

searchDocs('fetch api post').then(console.log);
checkPkg('express');

Expected Output

JSON
[EXISTS] requests: requests 2.32.0 - PyPI
[EXISTS] fastapi: fastapi - PyPI - A modern, fast web framework
[NOT FOUND] nonexistent-fake-pkg-xyz

Agent tools defined: ['search_docs', 'check_package']

[1] requests - PyPI: HTTP library for Python
    Requests allows you to send HTTP requests extremely easily...
    URL: https://pypi.org/project/requests/

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.

A local multi-agent setup (Pi, llama-swap, or similar). Python 3.9+ installed. requests library installed. A Scavio API key from scavio.dev. 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

Give your Pi or llama-swap multi-agent coding setup real-time search. Ground code generation with live documentation and package data.