Tutorial

How to Ground a Local LLM with Multi-Platform Search Data

Feed Google, Reddit, and YouTube data into Ollama or llama.cpp to ground local LLM answers with real-time multi-platform context. Step-by-step guide.

Local LLMs like Llama 3 and Mistral run without sending data to the cloud but lack real-time knowledge. Grounding them with multi-platform search data solves this: your LLM gets Google results for factual answers, Reddit posts for community opinions, and YouTube metadata for video context. Scavio provides all three platforms through one POST endpoint at $0.005 per request. This tutorial builds a grounding layer that routes queries to the right platforms based on intent.

Prerequisites

  • Ollama or llama.cpp running locally
  • Python 3.9+ installed
  • requests library installed
  • A Scavio API key from scavio.dev

Walkthrough

Step 1: Set up platform-specific search functions

Create search functions for Google, Reddit, and YouTube. Each normalizes results into a common format with platform-specific metadata.

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_google(query: str, num: int = 5) -> list:
    resp = requests.post(URL, headers=H,
        json={'query': query, 'country_code': 'us', 'num_results': num})
    return [{'source': 'google', 'title': r['title'], 'snippet': r.get('snippet', ''),
             'url': r['link']} for r in resp.json().get('organic_results', [])]

def search_reddit(query: str, num: int = 5) -> list:
    resp = requests.post(URL, headers=H,
        json={'query': f'site:reddit.com {query}', 'country_code': 'us', 'num_results': num})
    return [{'source': 'reddit', 'title': r['title'], 'snippet': r.get('snippet', ''),
             'url': r['link']} for r in resp.json().get('organic_results', [])]

def search_youtube(query: str, num: int = 3) -> list:
    resp = requests.post(URL, headers=H,
        json={'query': f'site:youtube.com {query}', 'country_code': 'us', 'num_results': num})
    return [{'source': 'youtube', 'title': r['title'].replace(' - YouTube', ''),
             'snippet': r.get('snippet', ''), 'url': r['link']}
            for r in resp.json().get('organic_results', [])]

print('Multi-platform search ready')

Step 2: Build the intent router

Classify queries by intent to choose which platforms to search. Factual questions hit Google, opinion questions hit Reddit, how-to queries hit YouTube.

Python
def classify_intent(query: str) -> list[str]:
    q = query.lower()
    platforms = []
    # Always include Google for factual grounding
    platforms.append('google')
    # Opinion and discussion queries -> Reddit
    opinion_words = ['best', 'worst', 'recommend', 'opinion', 'experience',
                     'worth it', 'vs', 'alternative', 'should i']
    if any(w in q for w in opinion_words):
        platforms.append('reddit')
    # Tutorial and how-to queries -> YouTube
    howto_words = ['how to', 'tutorial', 'guide', 'setup', 'install',
                   'configure', 'build', 'demo', 'walkthrough']
    if any(w in q for w in howto_words):
        platforms.append('youtube')
    return platforms

# Test intent classification
for q in ['what is the capital of France',
          'best laptop for programming 2026',
          'how to deploy fastapi on railway']:
    print(f'{q} -> {classify_intent(q)}')

Step 3: Create the multi-platform context builder

Gather results from all relevant platforms and format them as LLM context. Each source is clearly labeled so the LLM can cite platforms in its answer.

Python
import time

def build_context(query: str) -> str:
    platforms = classify_intent(query)
    all_results = []
    for p in platforms:
        if p == 'google':
            all_results.extend(search_google(query))
        elif p == 'reddit':
            all_results.extend(search_reddit(query))
        elif p == 'youtube':
            all_results.extend(search_youtube(query))
        time.sleep(0.2)
    # Format for LLM consumption
    lines = [f'Search results for: {query}', f'Platforms searched: {", ".join(platforms)}', '']
    for i, r in enumerate(all_results, 1):
        lines.append(f'[{i}] ({r["source"].upper()}) {r["title"]}')
        if r['snippet']:
            lines.append(f'    {r["snippet"][:200]}')
        lines.append(f'    URL: {r["url"]}')
        lines.append('')
    context = '\n'.join(lines)
    print(f'Built context: {len(all_results)} results from {len(platforms)} platforms')
    return context

ctx = build_context('best python web framework 2026')
print(ctx[:500])

Step 4: Connect to the local LLM

Send the search context and user question to Ollama. The system prompt instructs the LLM to answer only from search results and cite sources by number and platform.

Python
LLM_URL = 'http://localhost:11434/v1/chat/completions'

def ask_local_llm(context: str, question: str) -> str:
    messages = [
        {'role': 'system', 'content': (
            'You are a helpful assistant. Answer based on the search results provided. '
            'Cite sources as [1], [2] etc. Mention which platform (Google, Reddit, YouTube) '
            'the information comes from. If results are insufficient, say so.'
        )},
        {'role': 'user', 'content': f'{context}\n\nQuestion: {question}'}
    ]
    resp = requests.post(LLM_URL, json={
        'model': 'llama3', 'messages': messages, 'max_tokens': 512
    })
    return resp.json()['choices'][0]['message']['content']

def grounded_answer(question: str) -> dict:
    context = build_context(question)
    answer = ask_local_llm(context, question)
    platforms = classify_intent(question)
    return {'question': question, 'answer': answer,
            'platforms': platforms, 'cost': len(platforms) * 0.005}

result = grounded_answer('best python web framework 2026')
print(f'Q: {result["question"]}')
print(f'A: {result["answer"]}')
print(f'Platforms: {result["platforms"]}, Cost: ${result["cost"]}')

Python Example

Python
import os, requests, time

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'}
LLM = 'http://localhost:11434/v1/chat/completions'

def multi_search(query):
    results = []
    for prefix in ['', 'site:reddit.com ', 'site:youtube.com ']:
        resp = requests.post(URL, headers=H,
            json={'query': f'{prefix}{query}', 'country_code': 'us', 'num_results': 3})
        results.extend(resp.json().get('organic_results', []))
        time.sleep(0.2)
    return results

def grounded_ask(question):
    results = multi_search(question)
    ctx = '\n'.join(f'[{i+1}] {r["title"]}: {r.get("snippet","")}' for i, r in enumerate(results))
    resp = requests.post(LLM, json={'model': 'llama3', 'messages': [
        {'role': 'system', 'content': 'Answer from search results. Cite [1],[2] etc.'},
        {'role': 'user', 'content': f'{ctx}\n\nQ: {question}'}], 'max_tokens': 512})
    return resp.json()['choices'][0]['message']['content']

print(grounded_ask('best python framework for APIs 2026'))

JavaScript Example

JavaScript
const SCAVIO_KEY = process.env.SCAVIO_API_KEY;
const URL = 'https://api.scavio.dev/api/v1/search';

async function multiSearch(query) {
  const results = [];
  for (const prefix of ['', 'site:reddit.com ', 'site:youtube.com ']) {
    const resp = await fetch(URL, {
      method: 'POST',
      headers: { 'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json' },
      body: JSON.stringify({ query: `${prefix}${query}`, country_code: 'us', num_results: 3 })
    });
    results.push(...((await resp.json()).organic_results || []));
  }
  return results;
}

async function groundedAsk(question) {
  const results = await multiSearch(question);
  const ctx = results.map((r, i) => `[${i+1}] ${r.title}: ${r.snippet || ''}`).join('\n');
  const resp = await fetch('http://localhost:11434/v1/chat/completions', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ model: 'llama3', messages: [
      { role: 'system', content: 'Answer from search results. Cite [1],[2].' },
      { role: 'user', content: `${ctx}\n\nQ: ${question}` }], max_tokens: 512 })
  });
  return (await resp.json()).choices[0].message.content;
}

groundedAsk('best python framework for APIs 2026').then(console.log);

Expected Output

JSON
Built context: 9 results from 3 platforms

Q: best python web framework 2026
A: Based on the search results across multiple platforms:

Google sources indicate FastAPI and Django remain the top choices [1][2].
Reddit discussions show strong community preference for FastAPI for new
API projects [4][5]. YouTube tutorials are heavily focused on FastAPI
deployment [7][8].

Platforms: ['google', 'reddit', 'youtube'], Cost: $0.015

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.

Ollama or llama.cpp running locally. 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

Feed Google, Reddit, and YouTube data into Ollama or llama.cpp to ground local LLM answers with real-time multi-platform context. Step-by-step guide.