Large language models produce higher quality answers when grounded in current web data rather than relying solely on training data. This tutorial builds a pipeline that fetches live Google results for a user question, formats the top results as context, and sends them to GPT with instructions to answer using only the provided sources. The result is a cited, up-to-date answer similar to Perplexity or Bing Chat, built with under 50 lines of Python.
Prerequisites
- Python 3.10 or higher
- pip install requests openai
- A Scavio API key
- An OpenAI API key
Walkthrough
Step 1: Fetch search results for the question
Use the Scavio API to get the top organic results for the user's question. These will serve as the grounding context.
import os
import requests
API_KEY = os.environ.get("SCAVIO_API_KEY", "your_scavio_api_key")
def fetch_context(question: str, n: int = 5) -> list[dict]:
r = requests.post(
"https://api.scavio.dev/api/v1/search",
headers={"x-api-key": API_KEY},
json={"query": question, "country_code": "us"}
)
r.raise_for_status()
return r.json().get("organic_results", [])[:n]Step 2: Format results as context
Convert the search results into a numbered context block that the LLM can reference by source number.
def format_context(results: list[dict]) -> str:
lines = []
for i, r in enumerate(results, 1):
lines.append(f"[{i}] {r.get('title', '')}")
lines.append(f" URL: {r.get('link', '')}")
lines.append(f" {r.get('snippet', '')}")
return "\n".join(lines)Step 3: Send to GPT with grounding instructions
Pass the context and question to GPT with a system prompt that requires citing sources by number.
from openai import OpenAI
client = OpenAI()
def ask_with_context(question: str, context: str) -> str:
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": "Answer the question using ONLY the provided search results. Cite sources using [n] notation. If the results do not contain the answer, say so."},
{"role": "user", "content": f"Search results:\n{context}\n\nQuestion: {question}"}
],
temperature=0
)
return response.choices[0].message.contentStep 4: Run the full pipeline
Chain the fetch, format, and answer steps together for any user question.
def answer(question: str) -> str:
results = fetch_context(question)
context = format_context(results)
return ask_with_context(question, context)
print(answer("What are the best Python testing frameworks in 2026?"))Python Example
import os
import requests
from openai import OpenAI
SCAVIO_KEY = os.environ.get("SCAVIO_API_KEY", "your_scavio_api_key")
client = OpenAI()
def fetch_context(question: str) -> list[dict]:
r = requests.post("https://api.scavio.dev/api/v1/search",
headers={"x-api-key": SCAVIO_KEY},
json={"query": question, "country_code": "us"})
r.raise_for_status()
return r.json().get("organic_results", [])[:5]
def format_context(results: list[dict]) -> str:
return "\n".join(f"[{i}] {r['title']}\n {r.get('snippet', '')}\n {r['link']}" for i, r in enumerate(results, 1))
def answer(question: str) -> str:
ctx = format_context(fetch_context(question))
resp = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": "Answer using ONLY the search results. Cite with [n]."},
{"role": "user", "content": f"Results:\n{ctx}\n\nQuestion: {question}"}
], temperature=0)
return resp.choices[0].message.content
if __name__ == "__main__":
print(answer("What are the best Python testing frameworks in 2026?"))JavaScript Example
const SCAVIO_KEY = process.env.SCAVIO_API_KEY || "your_scavio_api_key";
const { OpenAI } = require("openai");
const client = new OpenAI();
async function fetchContext(question) {
const res = 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: question, country_code: "us" })
});
const data = await res.json();
return (data.organic_results || []).slice(0, 5);
}
async function answer(question) {
const results = await fetchContext(question);
const ctx = results.map((r, i) => `[${i + 1}] ${r.title}\n ${r.snippet || ""}\n ${r.link}`).join("\n");
const resp = await client.chat.completions.create({
model: "gpt-4o",
messages: [
{ role: "system", content: "Answer using ONLY the search results. Cite with [n]." },
{ role: "user", content: `Results:\n${ctx}\n\nQuestion: ${question}` }
], temperature: 0
});
console.log(resp.choices[0].message.content);
}
answer("Best Python testing frameworks 2026").catch(console.error);Expected Output
Based on search results, the top Python testing frameworks in 2026 are:
1. **pytest** - The most popular framework with extensive plugin support [1]
2. **Hypothesis** - Property-based testing gaining rapid adoption [2]
3. **Playwright for Python** - Leading choice for end-to-end browser testing [3]
Sources:
[1] https://example.com/python-testing-2026
[2] https://example.com/hypothesis-testing
[3] https://example.com/playwright-python