Conectar un LLM con datos SERP en vivo significa obtener resultados de búsqueda actuales para un reclamo fáctico antes de generar una respuesta y luego inyectar los hechos extraídos en el mensaje como contexto. Esto evita alucinaciones sobre precios, fechas y disponibilidad.
Requisitos previos
- Python 3.9+
- Clave API de Scavio
- SDK openai o antrópico
Guia paso a paso
Paso 1: Busque en SERP el reclamo fáctico
Antes de solicitar el LLM, ejecute una búsqueda específica para recuperar datos actuales.
import requests
API_KEY = "your-scavio-api-key"
def fetch_grounding_context(claim_query: str, num_results: int = 5) -> str:
r = requests.post(
"https://api.scavio.dev/api/v1/search",
json={"query": claim_query, "num_results": num_results},
headers={"x-api-key": API_KEY},
timeout=15
)
r.raise_for_status()
results = r.json().get("organic_results", [])
lines = []
for i, res in enumerate(results, 1):
lines.append(f"{i}. {res.get('title')}\n {res.get('snippet')}\n Source: {res.get('link')}")
return "\n\n".join(lines)Paso 2: Inyecte contexto de conexión a tierra en el mensaje
Anteponga los fragmentos de SERP como un bloque [CONTEXTO] para que el LLM los use en lugar de los datos de entrenamiento.
def build_grounded_prompt(user_question: str, grounding_context: str) -> str:
return f"""[CONTEXT - Retrieved {__import__('datetime').date.today()}]
{grounding_context}
[INSTRUCTIONS]
Answer the question below using ONLY the context above. If the context does not contain the answer, say "I don't have current data on this."
Do not use information from your training data for prices, dates, or availability.
[QUESTION]
{user_question}"""
context = fetch_grounding_context("GPT-4o API pricing 2026")
prompt = build_grounded_prompt("What is the current price of GPT-4o per million tokens?", context)
print(prompt[:500])Paso 3: Llame al LLM con el mensaje fundamentado
Pase el mensaje fundamentado a cualquier LLM. La respuesta del modelo se limita a los hechos inyectados.
import anthropic
client = anthropic.Anthropic(api_key="your-anthropic-key")
def grounded_answer(question: str, search_query: str = None) -> str:
query = search_query or question
context = fetch_grounding_context(query)
prompt = build_grounded_prompt(question, context)
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=512,
messages=[{"role": "user", "content": prompt}]
)
return message.content[0].text
answer = grounded_answer(
"What does GPT-4o cost per million input tokens?",
"GPT-4o API pricing per million tokens 2026"
)
print(answer)Ejemplo en Python
import requests
import anthropic
from datetime import date
SCAVIO_KEY = "your-scavio-api-key"
ANTHROPIC_KEY = "your-anthropic-key"
def fetch_serp_context(query: str, n: int = 5) -> str:
r = requests.post(
"https://api.scavio.dev/api/v1/search",
json={"query": query, "num_results": n},
headers={"x-api-key": SCAVIO_KEY},
timeout=15
)
r.raise_for_status()
results = r.json().get("organic_results", [])
return "\n\n".join(
f"{i}. {r.get('title')}\n {r.get('snippet')}\n {r.get('link')}"
for i, r in enumerate(results, 1)
)
def grounded_answer(question: str, search_query: str | None = None) -> dict:
query = search_query or question
context = fetch_serp_context(query)
prompt = f"""[CONTEXT - {date.today()}]\n{context}\n\n[INSTRUCTIONS]\nAnswer using ONLY the context above. For prices, dates, or availability, cite the source number.\n\n[QUESTION]\n{question}"""
client = anthropic.Anthropic(api_key=ANTHROPIC_KEY)
msg = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=512,
messages=[{"role": "user", "content": prompt}]
)
return {"answer": msg.content[0].text, "context_used": context}
if __name__ == "__main__":
result = grounded_answer(
"How much does Firecrawl cost per month?",
"Firecrawl pricing 2026"
)
print(result["answer"])Ejemplo en JavaScript
const SCAVIO_KEY = 'your-scavio-api-key';
const ANTHROPIC_KEY = 'your-anthropic-key';
async function fetchSerpContext(query, n = 5) {
const res = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'x-api-key': SCAVIO_KEY },
body: JSON.stringify({ query, num_results: n })
});
const data = await res.json();
return (data.organic_results ?? [])
.map((r, i) => `${i+1}. ${r.title}\n ${r.snippet}\n ${r.link}`)
.join('\n\n');
}
async function groundedAnswer(question, searchQuery) {
const context = await fetchSerpContext(searchQuery ?? question);
const prompt = `[CONTEXT - ${new Date().toISOString().slice(0,10)}]\n${context}\n\n[QUESTION]\n${question}`;
const res = await fetch('https://api.anthropic.com/v1/messages', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': ANTHROPIC_KEY,
'anthropic-version': '2023-06-01'
},
body: JSON.stringify({
model: 'claude-sonnet-4-6',
max_tokens: 512,
messages: [{ role: 'user', content: prompt }]
})
});
const msg = await res.json();
return msg.content[0].text;
}
const answer = await groundedAnswer('How much does Firecrawl cost per month?', 'Firecrawl pricing 2026');
console.log(answer);Salida esperada
Based on the search results (source 2), Firecrawl offers:
- Free tier: 1,000 credits
- Starter: $16/month for 5,000 credits
- Scale: $83/month for 100,000 credits (annual billing)
These prices reflect annual billing rates as of 2026.