Las canalizaciones RAG estándar recuperan contexto de un almacén de vectores, pero ese contexto queda obsoleto en el momento en que se indexan sus documentos. Para consultas sobre precios, eventos recientes o clasificaciones actuales, el contexto obsoleto conduce a respuestas seguramente incorrectas. El aumento SERP soluciona este problema agregando una ruta de recuperación paralela: cuando la consulta parece urgente, obtenga resultados de búsqueda en vivo y combínelos con resultados vectoriales antes de pasar al LLM. Este tutorial muestra cómo agregar aumento SERP a cualquier canal RAG existente. Cada llamada de búsqueda cuesta $0,005 a través de la API de Scavio.
Requisitos previos
- Python 3.9+ instalado
- Una tubería RAG existente (cualquier almacén de vectores)
- solicita biblioteca instalada
- Una clave API de Scavio de scavio.dev
Guia paso a paso
Paso 1: Detectar consultas urgentes
Cree un clasificador que determine si una consulta necesita datos en vivo. Las consultas sobre precios, fechas, versiones o eventos actuales deberían activar el aumento de SERP.
import re
TIME_SIGNALS = [
r'\b202[4-9]\b', r'\blatest\b', r'\bcurrent\b', r'\bprice\b',
r'\bpricing\b', r'\btoday\b', r'\brecent\b', r'\bnew\b',
r'\bversion\b', r'\brelease\b', r'\bupdate\b'
]
def needs_live_data(query: str) -> bool:
query_lower = query.lower()
return any(re.search(p, query_lower) for p in TIME_SIGNALS)
# Examples:
for q in ['What is a transformer?', 'Latest Python version 2026', 'Semrush pricing today']:
print(f'{q}: live_data={needs_live_data(q)}')Paso 2: Construya la función de recuperación SERP
Cree un recuperador que devuelva documentos en el mismo formato que su almacén de vectores, para que puedan fusionarse sin problemas.
import requests, os
API_KEY = os.environ['SCAVIO_API_KEY']
def serp_retrieve(query: str, k: int = 5) -> list:
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': API_KEY, 'Content-Type': 'application/json'},
json={'query': query, 'country_code': 'us'})
resp.raise_for_status()
results = resp.json().get('organic_results', [])[:k]
return [{
'content': f'{r["title"]}\n{r.get("snippet", "")}',
'source': r['link'],
'retriever': 'serp',
'position': r['position']
} for r in results]Paso 3: Fusionar resultados vectoriales y SERP
Combine los resultados de ambos recuperadores, deduplicando por URL y dando a los resultados SERP un impulso de frescura en el ranking.
def merge_results(vector_docs: list, serp_docs: list) -> list:
seen_urls = set()
merged = []
# SERP results first (fresh data priority)
for doc in serp_docs:
url = doc.get('source', '')
if url not in seen_urls:
seen_urls.add(url)
merged.append(doc)
# Then vector results
for doc in vector_docs:
url = doc.get('source', '')
if url not in seen_urls:
seen_urls.add(url)
merged.append(doc)
return merged[:10] # cap at 10 context docs
# Example:
vector_results = [{'content': 'Old pricing data...', 'source': 'https://example.com/old', 'retriever': 'vector'}]
serp_results = serp_retrieve('Semrush pricing 2026')
merged = merge_results(vector_results, serp_results)
for doc in merged:
print(f'[{doc["retriever"]}] {doc["content"][:60]}...')Paso 4: Intégrelo en su canal RAG
Incluya la lógica de aumento en su paso de recuperación existente. Solo llame a la API SERP cuando la consulta sea urgente para mantener los costos al mínimo.
def augmented_retrieve(query: str, vector_store) -> list:
# Always get vector results
vector_docs = vector_store.similarity_search(query, k=5)
vector_formatted = [{'content': d.page_content, 'source': d.metadata.get('source', ''),
'retriever': 'vector'} for d in vector_docs]
# Conditionally add SERP results
if needs_live_data(query):
serp_docs = serp_retrieve(query, k=5)
return merge_results(vector_formatted, serp_docs)
return vector_formatted
# Usage in your chain:
# docs = augmented_retrieve(user_query, my_vector_store)
# context = '\n\n'.join(d['content'] for d in docs)
# answer = llm(f'Context:\n{context}\n\nQuestion: {user_query}')Ejemplo en Python
import os, re, requests
API_KEY = os.environ['SCAVIO_API_KEY']
TIME_SIGNALS = [r'\b202[4-9]\b', r'\blatest\b', r'\bprice\b', r'\bcurrent\b']
def needs_live_data(query: str) -> bool:
return any(re.search(p, query.lower()) for p in TIME_SIGNALS)
def serp_retrieve(query: str, k: int = 5) -> list:
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': API_KEY, 'Content-Type': 'application/json'},
json={'query': query, 'country_code': 'us'})
return [{'content': f'{r["title"]}\n{r.get("snippet", "")}',
'source': r['link'], 'retriever': 'serp'}
for r in resp.json().get('organic_results', [])[:k]]
def augmented_rag(query: str, vector_docs: list) -> list:
if needs_live_data(query):
serp_docs = serp_retrieve(query)
return serp_docs + vector_docs
return vector_docs
query = 'Semrush pricing 2026'
result = augmented_rag(query, [{'content': 'old data', 'retriever': 'vector'}])
for r in result:
print(f'[{r["retriever"]}] {r["content"][:60]}')Ejemplo en JavaScript
const API_KEY = process.env.SCAVIO_API_KEY;
const TIME_SIGNALS = [/\b202[4-9]\b/i, /\blatest\b/i, /\bprice\b/i, /\bcurrent\b/i];
function needsLiveData(query) {
return TIME_SIGNALS.some(p => p.test(query));
}
async function serpRetrieve(query, k = 5) {
const resp = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST',
headers: { 'x-api-key': API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ query, country_code: 'us' })
});
const data = await resp.json();
return (data.organic_results || []).slice(0, k)
.map(r => ({ content: `${r.title}\n${r.snippet || ''}`, source: r.link, retriever: 'serp' }));
}
async function augmentedRag(query, vectorDocs) {
if (needsLiveData(query)) {
const serp = await serpRetrieve(query);
return [...serp, ...vectorDocs];
}
return vectorDocs;
}
augmentedRag('Semrush pricing 2026', [{ content: 'old', retriever: 'vector' }])
.then(docs => docs.forEach(d => console.log(`[${d.retriever}] ${d.content.slice(0, 60)}`)));Salida esperada
What is a transformer?: live_data=False
Latest Python version 2026: live_data=True
Semrush pricing today: live_data=True
[serp] Semrush Pricing Plans 2026 - Complete Breakdown...
[serp] Semrush Review: Is the $139.95/mo Pro Plan Worth It?...
[serp] Semrush vs Ahrefs Pricing Comparison (May 2026)...
[vector] old data