CrawlForge
InicioPlaygroundCasos de usoIntegracionesPreciosDocumentaciónBlog
Cómo crear un pipeline de RAG con datos web
AI Engineering
Volver al blog
Ingeniería de IA

Cómo crear un pipeline de RAG con datos web

C
CrawlForge Team
Equipo de Ingeniería
14 de abril de 2026
11 min de lectura

En esta página

Respuesta rápida

Un pipeline de RAG en producción construido sobre datos web tiene seis etapas: rastrear los sitios objetivo, extraer contenido limpio, fragmentar el texto para embedding, generar vectores, almacenarlos en una base de datos vectorial y consultar en el momento de la inferencia. CrawlForge se encarga de las dos primeras etapas (crawl_deep + extract_content) para que tu sistema de RAG se mantenga anclado en datos web en vivo en lugar de PDF obsoletos.

La generación aumentada por recuperación (RAG) es tan buena como los datos que le aportas. La mayoría de los tutoriales de RAG usan colecciones de documentos estáticos: PDF o archivos markdown reposando en una carpeta. Los sistemas de RAG en producción necesitan datos web en vivo: documentación que se actualiza semanalmente, precios de la competencia que cambian cada mes, artículos de investigación publicados a diario.

Esta guía recorre la creación de un pipeline de RAG completo que usa CrawlForge para rastrear y extraer contenido web, y luego lo introduce en una base de datos vectorial para la generación aumentada por recuperación. Cada paso incluye código TypeScript funcional.

Tabla de contenidos

  • ¿Qué es RAG y por qué usar datos web?
  • Arquitectura del pipeline de RAG
  • Paso 1: Rastrea los sitios web objetivo
  • Paso 2: Extrae y limpia el contenido
  • Paso 3: Fragmenta el texto para el embedding
  • Paso 4: Genera los embeddings
  • Paso 5: Almacena en una base de datos vectorial
  • Paso 6: Consulta y recupera
  • Juntándolo todo
  • Consejos de optimización del rendimiento
  • Preguntas frecuentes

¿Qué es RAG y por qué usar datos web?

La generación aumentada por recuperación es una técnica en la que la respuesta de un LLM se ancla en documentos relevantes recuperados de una base de conocimiento externa. En lugar de depender únicamente de los datos de entrenamiento (que tienen una fecha de corte de conocimiento), los sistemas de RAG obtienen contexto actual y relevante antes de generar una respuesta.

Por qué los datos web mejoran el RAG:

  • Actualidad -- el contenido web se actualiza en tiempo real; los datos de entrenamiento no
  • Amplitud -- la web cubre todos los temas, sectores y nichos
  • Especificidad -- haz scraping exactamente de las páginas relevantes para tu dominio
  • Autoridad -- extrae de documentación oficial, artículos de investigación y fuentes de confianza

Casos de uso habituales de RAG con datos web:

  • Bots de atención al cliente anclados en documentación en vivo
  • Sistemas de inteligencia competitiva que rastrean los cambios de la competencia
  • Asistentes de investigación que obtienen de bases de datos académicas y noticias
  • Bases de conocimiento internas enriquecidas con datos externos del sector

Arquitectura del pipeline de RAG

Un pipeline de RAG con datos web tiene seis etapas:

Crawl --> Extract --> Chunk --> Embed --> Store --> Retrieve | | | | | | URLs Clean Text Vectors Vector Context text segments DB + LLM
EtapaHerramientaPropósito
RastreoCrawlForge crawl_deep / batch_scrapeDescubrir y obtener páginas
ExtracciónCrawlForge extract_contentLimpiar el HTML en texto legible
FragmentaciónLógica personalizadaDividir el texto en segmentos del tamaño de embedding
EmbeddingOpenAI / Cohere / modelo localConvertir el texto en representaciones vectoriales
AlmacenamientoPinecone / Weaviate / QdrantIndexar los vectores para búsqueda por similitud
RecuperaciónConsulta a la base de datos vectorial + LLMEncontrar fragmentos relevantes, generar la respuesta

Paso 1: Rastrea los sitios web objetivo

Primero, descubre y obtén todas las páginas relevantes de tu dominio objetivo. La herramienta crawl_deep de CrawlForge gestiona la paginación, el descubrimiento de enlaces y la obtención en paralelo.

Typescript
import { CrawlForge } from '@crawlforge/sdk';

const cf = new CrawlForge({ apiKey: process.env.CRAWLFORGE_API_KEY });

// Crawl a documentation site up to 3 levels deep
const crawlResult = await cf.crawlDeep({
  url: 'https://docs.example.com',
  max_depth: 3,
  max_pages: 200,
  include_patterns: ['/docs/', '/guides/', '/api/'],
  exclude_patterns: ['/changelog', '/blog'],
  extract_content: true, // Get clean text during crawl
  concurrency: 10
});

console.log(`Crawled ${crawlResult.pages.length} pages`);
// Crawled 147 pages

Para hacer scraping de una lista conocida de URLs (como un sitemap), usa batch_scrape en su lugar:

Typescript
// Scrape a specific list of URLs in parallel
const batchResult = await cf.batchScrape({
  urls: [
    'https://docs.example.com/auth',
    'https://docs.example.com/billing',
    'https://docs.example.com/webhooks',
    'https://docs.example.com/rate-limits',
    // ... up to 50 URLs per batch
  ],
  formats: ['text'],
  maxConcurrency: 10
});

Coste en credits: crawl_deep cuesta 5 credits por invocación. batch_scrape cuesta 5 credits por lote (hasta 50 URLs). Para 200 páginas, una sola llamada a crawl_deep es más rentable que varias llamadas a batch_scrape.

Paso 2: Extrae y limpia el contenido

El HTML en bruto contiene navegación, anuncios, pies de página y texto repetitivo que contaminará tus embeddings. La herramienta extract_content de CrawlForge usa algoritmos de legibilidad para aislar el contenido principal.

Si usaste extract_content: true durante el paso de rastreo, tu contenido ya está limpio. Para páginas individuales:

Typescript
// Extract clean content from a single page
const page = await cf.extractContent({
  url: 'https://docs.example.com/authentication'
});

console.log(page.content);
// Returns: "Authentication\n\nAll API requests require..."
// No nav bars, no footers, no cookie banners

Consejos de posprocesamiento:

  • Elimina el contenido duplicado (muchos sitios repiten cabeceras/pies de página en el texto extraído)
  • Quita los enlaces de navegación interna ("Siguiente: Facturación" / "Anterior: Configuración")
  • Normaliza los espacios en blanco y elimina las líneas vacías
  • Conserva los encabezados: aportan estructura para la fragmentación

Paso 3: Fragmenta el texto para el embedding

Los modelos de embedding tienen límites de tokens (normalmente entre 512 y 8.192 tokens). Los documentos largos deben dividirse en fragmentos más pequeños que preserven el significado semántico.

Typescript
interface TextChunk {
  content: string;
  metadata: {
    source: string;
    title: string;
    heading: string;
    chunkIndex: number;
  };
}

function chunkByHeading(
  text: string,
  source: string,
  title: string,
  maxChunkSize: number = 1000 // characters
): TextChunk[] {
  const chunks: TextChunk[] = [];
  // Split on markdown headings (## or ###)
  const sections = text.split(/(?=^#{2,3}\s)/m);

  let chunkIndex = 0;
  for (const section of sections) {
    // Extract heading from section
    const headingMatch = section.match(/^#{2,3}\s+(.+)/);
    const heading = headingMatch ? headingMatch[1].trim() : title;
    const content = section.trim();

    if (content.length <= maxChunkSize) {
      chunks.push({
        content,
        metadata: { source, title, heading, chunkIndex: chunkIndex++ }
      });
    } else {
      // Split large sections by paragraph
      const paragraphs = content.split('\n\n');
      let currentChunk = '';

      for (const para of paragraphs) {
        if ((currentChunk + para).length > maxChunkSize && currentChunk) {
          chunks.push({
            content: currentChunk.trim(),
            metadata: { source, title, heading, chunkIndex: chunkIndex++ }
          });
          currentChunk = para;
        } else {
          currentChunk += (currentChunk ? '\n\n' : '') + para;
        }
      }
      if (currentChunk.trim()) {
        chunks.push({
          content: currentChunk.trim(),
          metadata: { source, title, heading, chunkIndex: chunkIndex++ }
        });
      }
    }
  }

  return chunks;
}

// Usage with crawled pages
const allChunks: TextChunk[] = [];
for (const page of crawlResult.pages) {
  const pageChunks = chunkByHeading(
    page.content,
    page.url,
    page.title || 'Untitled',
    1000
  );
  allChunks.push(...pageChunks);
}

console.log(`Created ${allChunks.length} chunks from ${crawlResult.pages.length} pages`);
// Created 892 chunks from 147 pages

Estrategias de fragmentación comparadas:

EstrategiaProsContrasIdeal para
Tamaño fijoSencilla, predecibleCorta a mitad de fraseContenido general
Basada en encabezadosPreserva la estructuraTamaños de fragmento desigualesDocumentación
Basada en frasesLímites naturalesPuede ser demasiado pequeñaDatos conversacionales
RecursivaTamaños equilibrados + estructuraMás complejaSistemas en producción

Paso 4: Genera los embeddings

Convierte cada fragmento de texto en una representación vectorial usando un modelo de embedding.

Typescript
import OpenAI from 'openai';

const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

interface EmbeddedChunk extends TextChunk {
  embedding: number[];
}

async function embedChunks(
  chunks: TextChunk[],
  batchSize: number = 100
): Promise<EmbeddedChunk[]> {
  const embeddedChunks: EmbeddedChunk[] = [];

  for (let i = 0; i < chunks.length; i += batchSize) {
    const batch = chunks.slice(i, i + batchSize);
    const texts = batch.map(c => c.content);

    const response = await openai.embeddings.create({
      model: 'text-embedding-3-small', // 1536 dimensions, $0.02/1M tokens
      input: texts
    });

    for (let j = 0; j < batch.length; j++) {
      embeddedChunks.push({
        ...batch[j],
        embedding: response.data[j].embedding
      });
    }

    console.log(`Embedded ${Math.min(i + batchSize, chunks.length)}/${chunks.length} chunks`);
  }

  return embeddedChunks;
}

const embeddedChunks = await embedChunks(allChunks);

Opciones de modelo de embedding:

ModeloDimensionesCosteCalidad
OpenAI text-embedding-3-small1.536$0.02/1M tokensBuena
OpenAI text-embedding-3-large3.072$0.13/1M tokensMejor
Cohere embed-english-v3.01.024$0.10/1M tokensBuena
Local (all-MiniLM-L6-v2)384GratisAdecuada

Paso 5: Almacena en una base de datos vectorial

Indexa los fragmentos con embedding en una base de datos vectorial para una búsqueda por similitud rápida.

Ejemplo con Pinecone

Typescript
import { Pinecone } from '@pinecone-database/pinecone';

const pinecone = new Pinecone({ apiKey: process.env.PINECONE_API_KEY });
const index = pinecone.Index('rag-web-data');

// Upsert chunks in batches of 100
async function storeChunks(chunks: EmbeddedChunk[]) {
  const batchSize = 100;

  for (let i = 0; i < chunks.length; i += batchSize) {
    const batch = chunks.slice(i, i + batchSize);
    const vectors = batch.map((chunk, j) => ({
      id: `${chunk.metadata.source}-${chunk.metadata.chunkIndex}`,
      values: chunk.embedding,
      metadata: {
        content: chunk.content,
        source: chunk.metadata.source,
        title: chunk.metadata.title,
        heading: chunk.metadata.heading
      }
    }));

    await index.upsert(vectors);
    console.log(`Stored ${Math.min(i + batchSize, chunks.length)}/${chunks.length} vectors`);
  }
}

await storeChunks(embeddedChunks);

Ejemplo con Weaviate

Typescript
import weaviate from 'weaviate-ts-client';

const client = weaviate.client({
  scheme: 'https',
  host: process.env.WEAVIATE_HOST || 'localhost:8080'
});

// Create collection schema
await client.schema.classCreator().withClass({
  class: 'WebDocument',
  vectorizer: 'none', // We provide our own vectors
  properties: [
    { name: 'content', dataType: ['text'] },
    { name: 'source', dataType: ['string'] },
    { name: 'title', dataType: ['string'] },
    { name: 'heading', dataType: ['string'] }
  ]
}).do();

// Store chunks
for (const chunk of embeddedChunks) {
  await client.data.creator()
    .withClassName('WebDocument')
    .withProperties({
      content: chunk.content,
      source: chunk.metadata.source,
      title: chunk.metadata.title,
      heading: chunk.metadata.heading
    })
    .withVector(chunk.embedding)
    .do();
}

Paso 6: Consulta y recupera

Ahora consulta la base de datos vectorial con una pregunta del usuario, recupera los fragmentos relevantes y pásalos a un LLM como contexto.

Typescript
async function ragQuery(question: string): Promise<string> {
  // 1. Embed the question
  const questionEmbedding = await openai.embeddings.create({
    model: 'text-embedding-3-small',
    input: question
  });

  // 2. Query Pinecone for the 5 most relevant chunks
  const queryResult = await index.query({
    vector: questionEmbedding.data[0].embedding,
    topK: 5,
    includeMetadata: true
  });

  // 3. Build context from retrieved chunks
  const context = queryResult.matches
    .map(match => {
      const meta = match.metadata as Record<string, string>;
      return `Source: ${meta.source}\nSection: ${meta.heading}\n\n${meta.content}`;
    })
    .join('\n\n---\n\n');

  // 4. Generate answer with context
  const completion = await openai.chat.completions.create({
    model: 'gpt-4o',
    messages: [
      {
        role: 'system',
        content: `Answer the user's question based on the provided context.
Cite sources when possible. If the context does not contain enough
information, say so.`
      },
      {
        role: 'user',
        content: `Context:\n${context}\n\nQuestion: ${question}`
      }
    ]
  });

  return completion.choices[0].message.content || 'No answer generated';
}

// Example usage
const answer = await ragQuery('How does authentication work?');
console.log(answer);

Juntándolo todo

Aquí tienes el pipeline completo en una única función de orquestación:

Typescript
async function buildRAGPipeline(config: {
  targetUrl: string;
  maxPages: number;
  indexName: string;
}) {
  const cf = new CrawlForge({ apiKey: process.env.CRAWLFORGE_API_KEY });

  // 1. Crawl
  console.log('Crawling...');
  const crawled = await cf.crawlDeep({
    url: config.targetUrl,
    max_depth: 3,
    max_pages: config.maxPages,
    extract_content: true,
    concurrency: 10
  });
  console.log(`Crawled ${crawled.pages.length} pages`);

  // 2. Chunk
  console.log('Chunking...');
  const chunks = crawled.pages.flatMap(page =>
    chunkByHeading(page.content, page.url, page.title || 'Untitled')
  );
  console.log(`Created ${chunks.length} chunks`);

  // 3. Embed
  console.log('Embedding...');
  const embedded = await embedChunks(chunks);

  // 4. Store
  console.log('Storing...');
  await storeChunks(embedded);

  console.log('RAG pipeline complete. Ready for queries.');
}

// Run it
await buildRAGPipeline({
  targetUrl: 'https://docs.example.com',
  maxPages: 200,
  indexName: 'rag-web-data'
});

Coste total de credits de CrawlForge para 200 páginas: 5 credits (una sola llamada a crawl_deep con extract_content: true).

Consejos de optimización del rendimiento

  • Procesa los embeddings por lotes -- genera el embedding de 100 fragmentos por llamada a la API en lugar de uno a uno (10 veces más rápido, mismo coste)
  • Usa fragmentación basada en encabezados para documentación, y basada en frases para artículos de noticias
  • Establece un solapamiento adecuado -- un solapamiento del 10-15% entre fragmentos evita la pérdida de contexto en los límites
  • Filtra durante el rastreo -- usa include_patterns y exclude_patterns para evitar rastrear páginas irrelevantes
  • Cachea de forma agresiva -- almacena el contenido rastreado localmente para volver a rastrear solo cuando el contenido cambie
  • Monitoriza la actualidad -- usa el seguimiento de cambios de CrawlForge para detectar cuándo se actualizan las páginas de origen, y luego vuelve a rastrear y a generar embeddings solo del contenido que cambió

Preguntas frecuentes

¿Cuántos credits cuesta crear un pipeline de RAG con CrawlForge?

Una sola llamada a crawl_deep cuesta 5 credits y puede rastrear hasta 1.000 páginas. Para un sitio de documentación de 200 páginas, el coste total de CrawlForge es de 5 credits. El plan gratuito (1.000 credits) te permite crear 200 pipelines de RAG antes de pagar nada. Consulta los detalles de precios.

¿Qué base de datos vectorial debería usar para RAG?

Pinecone es la más fácil para empezar (totalmente gestionada, sin infraestructura). Weaviate ofrece más flexibilidad con la búsqueda híbrida (vector + palabra clave). Qdrant es la mejor opción autoalojada. ChromaDB funciona bien para prototipos y desarrollo local.

¿Con qué frecuencia debería volver a rastrear y actualizar mis datos de RAG?

Depende de la frecuencia con la que cambie tu contenido de origen. Sitios de documentación: semanalmente. Noticias e investigación: a diario. Catálogos de productos: cada hora. Usa el seguimiento de cambios de CrawlForge para detectar actualizaciones y procesar de nuevo solo las páginas que cambiaron.

¿Puedo usar CrawlForge con LangChain o LlamaIndex?

Sí. CrawlForge se integra con ambos frameworks. Usa el SDK para obtener el contenido y luego pásalo a los cargadores de documentos de LangChain o a los conectores de datos de LlamaIndex. Consulta nuestra guía de integración con LangChain para ver ejemplos.


Crea tu primer pipeline de RAG en menos de 10 minutos. Empieza gratis con 1.000 credits y rastrea tu primer sitio hoy.

Pruébalo tú mismo — sin necesidad de registrarte

Ejecuta cualquiera de las 27 herramientas de scraping y extracción de CrawlForge en el playground y luego empieza gratis con 1,000 credits.

1,000 credits gratis • Se recargan cada mes • No se requiere tarjeta de crédito

Etiquetas

ragai-engineeringvector-databasepineconeweb-scrapingembeddingstutorial

Sobre el autor

C

CrawlForge Team

Equipo de Ingeniería

Construimos el MCP server de web scraping más completo. Creamos herramientas que ayudan a los desarrolladores a extraer, analizar y transformar datos web para aplicaciones de IA.

Mantente al día con los últimos artículos

Recibe tutoriales, novedades del producto y consejos de web scraping en tu bandeja de entrada.

Sin spam. Cancela tu suscripción cuando quieras.

Ponlo en práctica

Prueba las herramientas de CrawlForge en cualquier URL — gratis, sin registro.

En esta página

Frequently Asked Questions

¿Cuántos credits cuesta crear un pipeline de RAG con datos web?+

Una sola llamada a crawl_deep cuesta 5 credits y puede rastrear hasta 1.000 páginas. Para un sitio de documentación de 200 páginas, el coste total de CrawlForge es de 5 credits. El plan gratuito de 1.000 credits te permite crear 200 pipelines de RAG antes de pagar nada.

¿Qué base de datos vectorial debería usar para RAG?+

Pinecone es la más fácil para empezar (totalmente gestionada, sin infraestructura). Weaviate ofrece más flexibilidad con la búsqueda híbrida (vector + palabra clave). Qdrant es la mejor opción autoalojada. ChromaDB funciona bien para prototipos y desarrollo local.

¿Con qué frecuencia debería volver a rastrear y actualizar mis datos de RAG?+

Depende de la frecuencia con la que cambie tu contenido de origen. Sitios de documentación: semanalmente. Noticias e investigación: a diario. Catálogos de productos: cada hora. Usa el seguimiento de cambios de CrawlForge para detectar actualizaciones y procesar de nuevo solo las páginas que cambiaron.

¿Puedo usar CrawlForge con LangChain o LlamaIndex para RAG?+

Sí. CrawlForge se integra con ambos frameworks. Usa el SDK para obtener el contenido y luego pásalo a los cargadores de documentos de LangChain o a los conectores de datos de LlamaIndex. Esto mantiene tu sistema de RAG anclado en datos web en vivo en lugar de en PDF obsoletos.

Artículos relacionados

El protocolo MCP explicado: una guía para desarrolladores en 2026
AI Engineering

El protocolo MCP explicado: una guía para desarrolladores en 2026

Aprende cómo funciona el Model Context Protocol, por qué importa para los agentes de IA y cómo construir MCP servers y clientes con diagramas de arquitectura y código.

C
CrawlForge Team
|
27 abr
|
10m
Las mejores herramientas de web scraping para agentes de IA en 2026
AI Engineering

Las mejores herramientas de web scraping para agentes de IA en 2026

Las mejores herramientas de web scraping para agentes de IA en 2026, clasificadas por su preparación para agentes: descubrimiento de herramientas nativo de MCP, esquemas tipados y salida eficiente en tokens.

C
CrawlForge Team
|
9 jun
|
11m
Extrae datos web con LLMs locales (Ollama + CrawlForge)
AI Engineering

Extrae datos web con LLMs locales (Ollama + CrawlForge)

Sin API keys, sin nube, sin que tus datos salgan de tu máquina. Usa extract_with_llm con Ollama local para extraer datos estructurados de cualquier sitio.

C
CrawlForge Team
|
24 may
|
9m

Pie de página

CrawlForge

Web scraping empresarial para agentes de IA. 27 herramientas MCP especializadas diseñadas para desarrolladores modernos que crean sistemas inteligentes.

Producto

  • Funciones
  • Playground
  • Precios
  • Casos de uso
  • Integraciones
  • Alternativas
  • Registro de cambios

Recursos

  • Primeros pasos
  • Referencia de la API
  • Plantillas
  • Guías
  • Blog
  • Glosario
  • Preguntas frecuentes
  • Mapa del sitio

Desarrolladores

  • Protocolo MCP
  • Claude Desktop
  • Cursor IDE
  • LangChain
  • LlamaIndex

Empresa

  • Acerca de
  • Contacto
  • Privacidad
  • Términos
  • Uso aceptable
  • Cookies

Mantente al día

Recibe las últimas novedades sobre nuevas herramientas y funciones.

Creado con Next.js y el protocolo MCP

© 2025-2026 CrawlForge. Todos los derechos reservados.