Overview
Ground content generated by local LLMs (Llama, Mistral, Qwen) with live search data. Before generating, pull current search results as context. After generating, verify claims against search. Eliminate hallucination in LLM-generated content without sending data to cloud providers.
Trigger
On content generation request (event-driven)
Schedule
On content request (event-driven)
Workflow Steps
Receive content request
Accept a topic and content type (blog post, report, analysis). Extract the primary keyword and subtopics for search grounding.
Pre-generation search
Search Google via Scavio for the topic. Collect organic results, AI Overview, and People Also Ask as grounding context for the local LLM.
Generate with grounding context
Pass the search results as context to the local LLM alongside the content request. Instruct the model to cite only information present in the search context.
Post-generation verification
Extract factual claims from the generated content. Search for each claim to verify accuracy. Flag unverifiable claims for human review.
Output with citations
Attach source URLs from the search results as citations. Mark verified facts and flagged claims. Output the final grounded content with a verification report.
Python Implementation
import requests, os, json
H = {'x-api-key': os.environ['SCAVIO_API_KEY']}
def search_grounding(topic, subtopics=None):
"""Gather search context for LLM grounding."""
context = {}
# Main topic search
r = requests.post('https://api.scavio.dev/api/v1/search', headers=H,
json={'platform': 'google', 'query': topic, 'ai_overview': True},
timeout=10).json()
context['main'] = {
'organic': [{'title': o['title'], 'snippet': o.get('snippet', ''),
'url': o.get('link', '')} for o in r.get('organic', [])[:5]],
'ai_overview': (r.get('ai_overview', {}) or {}).get('text', ''),
'paa': [q.get('question', '') for q in r.get('people_also_ask', [])[:5]],
}
# Subtopic searches
for sub in (subtopics or []):
sr = requests.post('https://api.scavio.dev/api/v1/search', headers=H,
json={'platform': 'google', 'query': sub}, timeout=10).json()
context[sub] = [{'title': o['title'], 'snippet': o.get('snippet', '')}
for o in sr.get('organic', [])[:3]]
return context
def verify_claim(claim):
"""Verify a factual claim against search results."""
r = requests.post('https://api.scavio.dev/api/v1/search', headers=H,
json={'platform': 'google', 'query': claim}, timeout=10).json()
organic = r.get('organic', [])[:3]
snippets = ' '.join(o.get('snippet', '').lower() for o in organic)
keywords = [w.lower() for w in claim.split() if len(w) > 4]
matches = sum(1 for kw in keywords if kw in snippets)
return {
'claim': claim, 'verified': matches >= len(keywords) * 0.5,
'confidence': min(matches / max(len(keywords), 1), 1.0),
'sources': [o.get('link', '') for o in organic[:2]],
}
# Example: ground a blog post
topic = 'best local LLM models for code generation 2026'
ctx = search_grounding(topic, ['llama 3 code performance', 'mistral code generation'])
print(f"Grounding context gathered: {len(ctx['main']['organic'])} results, {len(ctx['main']['paa'])} PAA")
print(f"AI Overview: {ctx['main']['ai_overview'][:100]}")JavaScript Implementation
const H = {"x-api-key": process.env.SCAVIO_API_KEY, "Content-Type": "application/json"};
async function searchGrounding(topic, subtopics = []) {
const r = await fetch("https://api.scavio.dev/api/v1/search", {
method: "POST", headers: H,
body: JSON.stringify({platform: "google", query: topic, ai_overview: true})
}).then(r => r.json());
const context = {
main: {
organic: (r.organic || []).slice(0, 5).map(o => ({
title: o.title, snippet: o.snippet || "", url: o.link || ""
})),
aiOverview: ((r.ai_overview || {}).text || ""),
paa: (r.people_also_ask || []).slice(0, 5).map(q => q.question || ""),
}
};
for (const sub of subtopics) {
const sr = await fetch("https://api.scavio.dev/api/v1/search", {
method: "POST", headers: H,
body: JSON.stringify({platform: "google", query: sub})
}).then(r => r.json());
context[sub] = (sr.organic || []).slice(0, 3).map(o => ({
title: o.title, snippet: o.snippet || ""
}));
}
return context;
}
async function verifyClaim(claim) {
const r = await fetch("https://api.scavio.dev/api/v1/search", {
method: "POST", headers: H,
body: JSON.stringify({platform: "google", query: claim})
}).then(r => r.json());
const organic = (r.organic || []).slice(0, 3);
const snippets = organic.map(o => (o.snippet || "").toLowerCase()).join(" ");
const keywords = claim.split(" ").filter(w => w.length > 4).map(w => w.toLowerCase());
const matches = keywords.filter(kw => snippets.includes(kw)).length;
return {
claim, verified: matches >= keywords.length * 0.5,
confidence: Math.min(matches / Math.max(keywords.length, 1), 1),
sources: organic.slice(0, 2).map(o => o.link || ""),
};
}
(async () => {
const ctx = await searchGrounding("best local LLM models for code generation 2026",
["llama 3 code performance", "mistral code generation"]);
console.log(`Grounding: ${ctx.main.organic.length} results, ${ctx.main.paa.length} PAA`);
console.log(`AIO: ${ctx.main.aiOverview.slice(0, 100)}`);
})();Platforms Used
Web search with knowledge graph, PAA, and AI overviews