Conecte un LLM local (Ollama, LM Studio, vLLM) con búsqueda web enrutando consultas a través de una API SERP estructurada en lugar de una búsqueda web sin formato. JSON estructurado utiliza entre 600 y 800 tokens frente a 4000-8000 para HTML sin formato, lo que se adapta mejor a ventanas de contexto de modelo local limitadas.
Requisitos previos
- Ollama o LM Studio ejecutándose localmente
- Clave API de Scavio
- Python 3.8+
- Un modelo con soporte de llamada a funciones (por ejemplo, llama3, mistral)
Guia paso a paso
Paso 1: Crear una función de búsqueda
Cree una herramienta de búsqueda que arroje resultados estructurados.
import requests, os
def web_search(query, platform='google'):
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': os.environ['SCAVIO_API_KEY'],
'Content-Type': 'application/json'},
json={'query': query, 'country_code': 'us', 'platform': platform})
data = resp.json()
return [{'title': r.get('title', ''), 'snippet': r.get('snippet', ''),
'url': r.get('link', '')}
for r in data.get('organic_results', [])[:5]]Paso 2: Integrarse con Ollama
Utilice la función de búsqueda como herramienta en las conversaciones de Ollama.
import ollama
def grounded_query(question):
search_results = web_search(question)
context = '\n'.join([f"- {r['title']}: {r['snippet']}" for r in search_results])
response = ollama.chat(model='llama3', messages=[{
'role': 'user',
'content': f'Based on these search results:\n{context}\n\nAnswer: {question}'
}])
return response['message']['content']
answer = grounded_query('What is the latest Next.js version?')
print(answer)Ejemplo en Python
import requests, os, ollama
def web_search(query):
r = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': os.environ['SCAVIO_API_KEY'],
'Content-Type': 'application/json'},
json={'query': query, 'country_code': 'us'}).json()
return [{'title': r.get('title', ''), 'snippet': r.get('snippet', '')}
for r in r.get('organic_results', [])[:5]]
def grounded_chat(question, model='llama3'):
results = web_search(question)
context = '\n'.join([f'- {r["title"]}: {r["snippet"]}' for r in results])
response = ollama.chat(model=model, messages=[{
'role': 'system',
'content': 'Answer based on the provided search results. Cite sources.'
}, {
'role': 'user',
'content': f'Search results:\n{context}\n\nQuestion: {question}'
}])
return response['message']['content']
print(grounded_chat('What is the current Stripe API version?'))Ejemplo en JavaScript
const H = {'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json'};
async function webSearch(query) {
const r = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST', headers: H,
body: JSON.stringify({query, country_code: 'us'})
}).then(r => r.json());
return (r.organic_results || []).slice(0, 5).map(r => ({
title: r.title, snippet: r.snippet || ''
}));
}
async function groundedChat(question) {
const results = await webSearch(question);
const context = results.map(r => `- ${r.title}: ${r.snippet}`).join('\n');
// Pass context + question to your local LLM via its API
console.log(`Grounding context (${context.length} chars) for: ${question}`);
return context;
}
groundedChat('What is the current Next.js version?');Salida esperada
Local LLM responses grounded in current web data. The model cites search results instead of relying on potentially outdated training data.