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.
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.
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.
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.
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
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
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
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