> ## Documentation Index
> Fetch the complete documentation index at: https://novita.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Respuestas fundamentadas en la web

Un modelo por sí solo no puede responder preguntas sobre eventos posteriores a su fecha de corte de entrenamiento, ni citar una fuente. La solución es el *grounding*: recuperar contenido web relevante en el momento de la solicitud y pasarlo al modelo como contexto. Esta guía muestra el patrón usando Novita [AI Search](/docs/es/guides/ai-search-quickstart) para recuperación y la [API de LLM](/docs/es/guides/llm-api) para la síntesis — todo detrás de una sola clave de API.

## ¿Qué es RAG?

La generación aumentada por recuperación (RAG) es el patrón detrás de cada respuesta fundamentada aquí: en lugar de depender de lo que el modelo memorizó durante el entrenamiento, *recuperas* documentos relevantes en el momento de la solicitud y *aumentas* el prompt con ellos, para que el modelo *genere* su respuesta a partir de ese contexto reciente y verificable.

Ese paso de recuperación es exactamente lo que proporciona AI Search. La web se convierte en tu base de conocimiento, y no tienes que crear ni mantener una base de datos vectorial para empezar — una llamada de búsqueda devuelve los pasajes, y el LLM hace el resto. Cuando más adelante quieras recuperar información de tus *propios* documentos privados, se aplica el mismo esquema de tres pasos; simplemente cambias la búsqueda web por un almacén vectorial.

RAG te aporta tres cosas que un modelo sin más no puede ofrecer:

* **Actualidad** — las respuestas reflejan contenido publicado después de la fecha de corte de entrenamiento del modelo.
* **Atribución** — cada afirmación puede remitir a una URL de origen que el usuario puede comprobar.
* **Menos alucinaciones** — fundamentar el modelo en texto recuperado evita que invente hechos.

## Cómo funciona la fundamentación

Un único turno de RAG sigue tres pasos:

1. **Buscar** (recuperar) en la web páginas relevantes para la pregunta.
2. **Extraer** (aumentar) el contenido que necesitas — fragmentos o texto completo de páginas — e incorporarlo al prompt.
3. **Sintetizar** (generar) una respuesta pasando ese contenido a un LLM y pidiéndole que cite las fuentes.

Puedes hacerlo con dos llamadas (búsqueda + LLM) o incluso con una, ya que tanto Exa como Tavily pueden sintetizar una respuesta por ti. Elige según cuánto control necesites sobre la redacción final y las citas.

## Deja que el proveedor escriba la respuesta

El camino más rápido. Search de Tavily devuelve una respuesta generada por un LLM cuando configuras `include_answer`, y Exa ofrece una [Answer](/docs/es/api-reference/model-apis-exa-answer) endpoint. Una llamada, sin orquestación.

<CodeGroup>
  ```bash Tavily theme={"system"}
  curl -X POST 'https://api.novita.ai/v3/tavily/search' \
    -H "Authorization: Bearer ${NOVITA_API_KEY}" \
    -H 'Content-Type: application/json' \
    -d '{
      "query": "What changed in the latest Python release?",
      "include_answer": "advanced",
      "max_results": 5
    }'
  ```

  ```bash Exa theme={"system"}
  curl -X POST 'https://api.novita.ai/v3/exa/answer' \
    -H "Authorization: Bearer ${NOVITA_API_KEY}" \
    -H 'Content-Type: application/json' \
    -d '{
      "query": "What changed in the latest Python release?",
      "text": true
    }'
  ```
</CodeGroup>

Usa esto cuando quieras una buena respuesta con código mínimo. Recurre al enfoque de recuperar y luego sintetizar que se muestra a continuación cuando necesites control sobre el modelo, el tono, el formato de salida o cómo se presentan las citas.

## Recuperar, luego sintetizar con un LLM

Esto te da control total. Busca fuentes y luego pasa los resultados a la [API de LLM](/docs/es/guides/llm-api) con instrucciones para responder usando únicamente ese contexto y citar cada afirmación.

```python theme={"system"}
import os
import requests
from openai import OpenAI

NOVITA_KEY = os.environ["NOVITA_API_KEY"]
QUESTION = "What changed in the latest Python release?"

# 1. Retrieve relevant web content.
search = requests.post(
    "https://api.novita.ai/v3/tavily/search",
    headers={"Authorization": f"Bearer {NOVITA_KEY}"},
    json={
        "query": QUESTION,
        "max_results": 5,
        "include_raw_content": "text",
    },
).json()

# 2. Build a compact, numbered context block the model can cite.
sources = []
for i, r in enumerate(search["results"], start=1):
    body = (r.get("raw_content") or r.get("content") or "")[:1500]
    sources.append(f"[{i}] {r['title']} ({r['url']})\n{body}")
context = "\n\n".join(sources)

# 3. Synthesize a grounded, cited answer.
client = OpenAI(base_url="https://api.novita.ai/openai", api_key=NOVITA_KEY)
completion = client.chat.completions.create(
    model="deepseek/deepseek-v4-flash",
    messages=[
        {
            "role": "system",
            "content": (
                "Answer using ONLY the provided sources. "
                "Cite claims with [n] referring to the source number. "
                "If the sources don't contain the answer, say so."
            ),
        },
        {"role": "user", "content": f"Question: {QUESTION}\n\nSources:\n{context}"},
    ],
)
print(completion.choices[0].message.content)
```

El mismo flujo funciona con Exa Search — cambia la ruta a `/v3/exa/search` y leer `text` de cada resultado en lugar de `raw_content`.

## Ajustar la calidad de la recuperación

La calidad de una respuesta fundamentada depende mucho más de *lo que recuperas* que del modelo. Algunos controles de alto impacto:

* **Actualidad.** Para preguntas sensibles al tiempo, restringe por fecha. Tavily expone `time_range` y `start_date`/`end_date`; Exa expone `startPublishedDate`/`endPublishedDate`. Esto mantiene las páginas desactualizadas fuera del contexto.
* **Confianza en la fuente.** Usa `include_domains`/`excludeDomains` para restringir la recuperación a fuentes de confianza (documentación oficial, editoriales de buena reputación) y excluir sitios de baja calidad.
* **Pistas de temas.** Tavily's `topic` (`news`, `finance`, `general`) y de Exa `category` dirigir el motor hacia el tipo correcto de resultado.
* **Dimensionamiento adecuado del contexto.** Limita el texto extraído (Tavily `chunks_per_source`, Exa `maxCharacters`) para que pases suficiente señal sin desbordar la ventana de contexto del modelo ni tu presupuesto de tokens.

## Search vs. extract vs. crawl

Elige la primitiva de recuperación que se ajuste a tu necesidad:

* **Search** — tienes una pregunta y necesitas *descubrir* páginas relevantes. El punto de partida predeterminado.
* **Extract / Contents** — ya conoces las URLs y quieres texto limpio de ellas. Bueno para fundamentarse en un conjunto fijo de documentos. Consulta [Tavily Extract](/docs/es/api-reference/model-apis-tavily-extract) y [Contenidos de Exa](/docs/es/api-reference/model-apis-exa-contents).
* **Crawl / Map** — quieres ingerir un sitio o una sección completos, siguiendo enlaces. Ideal para crear una base de conocimiento sin conexión. Consulta [Tavily Crawl](/docs/es/api-reference/model-apis-tavily-crawl) y [Tavily Map](/docs/es/api-reference/model-apis-tavily-map).

<Tip>
  Para un agente más completo que busque de forma iterativa y razone sobre muchas fuentes, consulta la [integración de DeepSearcher](/docs/es/guides/deepsearcher).
</Tip>

## Llevarlo a producción

* **Gestiona los resultados vacíos.** Si la búsqueda no devuelve nada relevante, haz que el modelo diga que no puede responder en lugar de inventar una respuesta. El prompt del sistema anterior hace esto.
* **Usa caché cuando puedas.** Las consultas idénticas devuelven resultados similares; almacenar en caché la recuperación reduce el coste y la latencia.
* **Ten en cuenta los límites de tasa.** Las llamadas de recuperación y al LLM están limitadas por separado — una solicitud de búsqueda no consume tu cuota del LLM. Reduce la frecuencia en `429` para cualquiera de los dos. Consulta [límites de tasa de LLM](/docs/es/guides/llm-rate-limits) para el lado del LLM.
* **Mantén las claves en el servidor.** Tu clave de Novita autentica cada llamada aquí — nunca la incluyas en código del lado del cliente.
