Saltar al contenido principal
Crea un asistente de investigación completo con IA que pueda extraer datos de sitios web y buscar en la web para responder preguntas. El asistente decide automáticamente cuándo usar herramientas de web scraping o de búsqueda para recopilar información y luego ofrece respuestas completas basadas en los datos recopilados. Interfaz de chatbot de asistente de investigación con IA que muestra web scraping en tiempo real con Firecrawl y respuestas conversacionales generadas por OpenAI

Qué vas a construir

Una interfaz de chat con IA donde los usuarios pueden hacer preguntas sobre cualquier tema. El asistente decide automáticamente cuándo usar scraping web o herramientas de búsqueda para recopilar información y luego ofrece respuestas completas basadas en los datos obtenidos.

Requisitos previos

  • Node.js 18 o posterior instalado
  • Una clave de la API de OpenAI de platform.openai.com
  • Una clave de la API de Firecrawl de firecrawl.dev
  • Conocimientos básicos de React y Next.js
1

Crear un nuevo proyecto de Next.js

Empieza creando una nueva aplicación de Next.js y navega al directorio del proyecto:
npx create-next-app@latest ai-sdk-firecrawl && cd ai-sdk-firecrawl
Cuando se te solicite, selecciona las siguientes opciones:
  • TypeScript: Sí
  • ESLint: Sí
  • Tailwind CSS: Sí
  • App Router: Sí
  • Usar directorio src/: No
  • Alias de importación: Sí (@/*)
2

Instalar las dependencias

Instalar paquetes del AI SDK

El AI SDK es un conjunto de herramientas de TypeScript que proporciona una API unificada para trabajar con distintos proveedores de LLM:
npm i ai @ai-sdk/react zod
Estos paquetes ofrecen:
  • ai: SDK principal con streaming, invocación de herramientas y manejo de respuestas
  • @ai-sdk/react: Hooks de React como useChat para crear interfaces de chat
  • zod: Validación de esquemas para entradas de herramientas
Más información en ai-sdk.dev/docs.

Instalar AI Elements

AI Elements proporciona componentes de UI prediseñados para aplicaciones de IA. Ejecuta el siguiente comando para generar todos los componentes necesarios:
npx ai-elements@latest
Esto configura AI Elements en tu proyecto, incluidos componentes de conversación, visualización de mensajes, campos de entrada de prompts y representaciones de llamadas a herramientas.Documentación: ai-sdk.dev/elements/overview.

Instalar el proveedor de OpenAI

Instala el proveedor de OpenAI para conectarte con los modelos de OpenAI:
npm install @ai-sdk/openai
3

Construye la interfaz de chat del frontend

Crea la página principal en app/page.tsx y copia el código de la pestaña Code que aparece a continuación. Esta será la interfaz de chat donde los usuarios interactúan con el asistente de IA.
  • Previsualización
  • Código
Interfaz de chatbot asistente de investigación en IA que muestra scraping web en tiempo real con Firecrawl y respuestas conversacionales impulsadas por OpenAI

Entendiendo el Frontend

El frontend usa componentes de AI Elements para proporcionar una interfaz de chat completa:Características principales:
  • Visualización de la conversación: El componente Conversation gestiona automáticamente el desplazamiento y la presentación de los mensajes
  • Representación de mensajes: Cada parte del mensaje se representa según su tipo (texto, razonamiento, llamadas a herramientas)
  • Visualización de herramientas: Las llamadas a herramientas se muestran con secciones plegables que muestran entradas y salidas
  • Controles interactivos: Los usuarios pueden activar o desactivar la búsqueda web, elegir modelos y adjuntar archivos
  • Acciones de mensajes: Copiar y reintentar en mensajes del asistente
4

Agregar compatibilidad con el renderizado de Markdown

Para asegurarte de que el markdown del LLM se renderice correctamente, añade la siguiente importación a tu archivo app/globals.css:
@source "../node_modules/streamdown/dist/index.js";
Esto importa los estilos necesarios para mostrar contenido Markdown en las respuestas de los mensajes.
5

Crear la ruta básica de API

Crea el endpoint de la API de chat en app/api/chat/route.ts. Esta ruta gestionará los mensajes entrantes y transmitirá respuestas de la IA.
import { streamText, UIMessage, convertToModelMessages } from "ai";
import { createOpenAI } from "@ai-sdk/openai";

const openai = createOpenAI({
  apiKey: process.env.OPENAI_API_KEY!,
});

// Permitir respuestas de streaming hasta por 5 minutos
export const maxDuration = 300;

export async function POST(req: Request) {
  const {
    messages,
    model,
    webSearch,
  }: {
    messages: UIMessage[];
    model: string;
    webSearch: boolean;
  } = await req.json();

  const result = streamText({
    model: openai(model),
    messages: convertToModelMessages(messages),
    system:
      "Eres un asistente útil que puede responder preguntas y ayudar con tareas.",
  });

  // enviar fuentes y razonamiento de vuelta al cliente
  return result.toUIMessageStreamResponse({
    sendSources: true,
    sendReasoning: true,
  });
}
Esta ruta básica:
  • Recibe mensajes del frontend
  • Usa el modelo de OpenAI seleccionado por el usuario
  • Transmite respuestas al cliente
  • Aún no incluye herramientas; las añadiremos a continuación
6

Configurar las variables de entorno

Crea un archivo .env.local en la raíz de tu proyecto:
touch .env.local
Añade tu clave de la API de OpenAI:
OPENAI_API_KEY=sk-your-openai-api-key
Se requiere la variable OPENAI_API_KEY para que el modelo de IA funcione.
7

Prueba el chat básico

Ahora puedes probar el chatbot del SDK de IA sin la integración con Firecrawl. Inicia el servidor de desarrollo:
npm run dev
Abre localhost:3000 en tu navegador y prueba la funcionalidad básica del chat. El asistente debería responder a los mensajes, pero aún no tendrá capacidades de scraping web ni de búsqueda.Chatbot de IA básico sin capacidades de scraping web
8

Agregar herramientas de Firecrawl

Ahora vamos a mejorar el asistente con capacidades de scraping web y búsqueda usando Firecrawl.

Instalar el SDK de Firecrawl

Firecrawl convierte sitios web en formatos listos para LLM con funciones de scraping y búsqueda:
npm i @mendable/firecrawl-js

Crea el archivo de herramientas

Crea una carpeta lib y agrega un archivo tools.ts dentro:
mkdir lib && touch lib/tools.ts
Agrega el siguiente código para definir las herramientas de web scraping y búsqueda:
lib/tools.ts
import FirecrawlApp from "@mendable/firecrawl-js";
import { tool } from "ai";
import { z } from "zod";

const firecrawl = new FirecrawlApp({ apiKey: process.env.FIRECRAWL_API_KEY });

export const scrapeWebsiteTool = tool({
  description: 'Extraer contenido de cualquier URL de sitio web',
  inputSchema: z.object({
    url: z.string().url().describe('La URL a extraer')
  }),
  execute: async ({ url }) => {
    console.log('Extrayendo:', url);
    const result = await firecrawl.scrape(url, {
      formats: ['markdown'],
      onlyMainContent: true,
      timeout: 30000
    });
    console.log('Vista previa del contenido extraído:', result.markdown?.slice(0, 200) + '...');
    return { content: result.markdown };
  }
});

export const searchWebTool = tool({
  description: 'Buscar en la web usando Firecrawl',
  inputSchema: z.object({
    query: z.string().describe('La consulta de búsqueda'),
    limit: z.number().optional().describe('Número de resultados'),
    location: z.string().optional().describe('Ubicación para resultados localizados'),
    tbs: z.string().optional().describe('Filtro de tiempo (qdr:h, qdr:d, qdr:w, qdr:m, qdr:y)'),
    sources: z.array(z.enum(['web', 'news', 'images'])).optional().describe('Tipos de resultados'),
    categories: z.array(z.enum(['github', 'research', 'pdf'])).optional().describe('Categorías de filtro'),
  }),
  execute: async ({ query, limit, location, tbs, sources, categories }) => {
    console.log('Buscando:', query);
    const response = await firecrawl.search(query, {
      ...(limit && { limit }),
      ...(location && { location }),
      ...(tbs && { tbs }),
      ...(sources && { sources }),
      ...(categories && { categories }),
    }) as { web?: Array<{ title?: string; url?: string; description?: string }> };

    const results = (response.web || []).map((item) => ({
      title: item.title || item.url || 'Sin título',
      url: item.url || '',
      description: item.description || '',
    }));

    console.log('Resultados de búsqueda:', results.length);
    return { results };
  },
});

Entender las herramientas

Herramienta de extracción de sitios web:
  • Acepta una URL como entrada (validada por un esquema de Zod)
  • Usa el método scrape de Firecrawl para obtener la página en Markdown
  • Extrae solo el contenido principal para reducir el uso de tokens
  • Devuelve el contenido extraído para que la IA lo analice
Herramienta de búsqueda web:
  • Acepta una consulta de búsqueda con filtros opcionales
  • Usa el método search de Firecrawl para encontrar páginas web relevantes
  • Admite filtros avanzados como ubicación, rango de tiempo y categorías de contenido
  • Devuelve resultados estructurados con títulos, URL y descripciones
Más información sobre las herramientas: ai-sdk.dev/docs/foundations/tools.
9

Actualiza la ruta de la API con las herramientas de Firecrawl

Ahora actualiza tu app/api/chat/route.ts para incluir las herramientas de Firecrawl que acabamos de crear.
import { streamText, UIMessage, stepCountIs, convertToModelMessages } from "ai";
import { createOpenAI } from "@ai-sdk/openai";
import { scrapeWebsiteTool, searchWebTool } from "@/lib/tools";

const openai = createOpenAI({
  apiKey: process.env.OPENAI_API_KEY!,
});

export const maxDuration = 300;

export async function POST(req: Request) {
  const {
    messages,
    model,
    webSearch,
  }: {
    messages: UIMessage[];
    model: string;
    webSearch: boolean;
  } = await req.json();

  const result = streamText({
    model: openai(model),
    messages: convertToModelMessages(messages),
    system:
      "You are a helpful assistant that can answer questions and help with tasks.",
    // Agrega aquí las herramientas de Firecrawl
    tools: {
      scrapeWebsite: scrapeWebsiteTool,
      searchWeb: searchWebTool,
    },
    stopWhen: stepCountIs(5),
    toolChoice: webSearch ? "auto" : "none",
  });

  return result.toUIMessageStreamResponse({
    sendSources: true,
    sendReasoning: true,
  });
}
Cambios clave respecto a la ruta básica:
  • Importa stepCountIs del AI SDK
  • Importa las herramientas de Firecrawl desde @/lib/tools
  • Agrega el objeto tools con las herramientas scrapeWebsite y searchWeb
  • Agrega stopWhen: stepCountIs(5) para limitar los pasos de ejecución
  • Establece toolChoice en “auto” cuando la búsqueda web esté habilitada; en “none” en caso contrario
Más información sobre streamText: ai-sdk.dev/docs/reference/ai-sdk-core/stream-text.
10

Añade tu clave de API de Firecrawl

Actualiza tu archivo .env.local para incluir tu clave de la API de Firecrawl:
OPENAI_API_KEY=sk-your-openai-api-key
FIRECRAWL_API_KEY=fc-your-firecrawl-api-key
Obtén tu clave de la API de Firecrawl en firecrawl.dev.
11

Probar la aplicación completa

Reinicia el servidor de desarrollo:
npm run dev
Chatbot de IA con herramientas activas de FirecrawlAbre localhost:3000 y prueba el asistente mejorado:
  1. Activa el botón “Search” para habilitar la búsqueda en la web
  2. Pregunta: “¿Cuáles son las funciones más recientes de firecrawl.dev?”
  3. Observa cómo la IA invoca la herramienta searchWeb o scrapeWebsite
  4. Mira la ejecución de la herramienta en la interfaz con sus entradas y salidas
  5. Lee el análisis de la IA basado en los datos extraídos

Cómo funciona

Flujo de mensajes

  1. El usuario envía un mensaje: El usuario escribe una pregunta y hace clic en Enviar
  2. El frontend envía la solicitud: useChat envía el mensaje a /api/chat con el modelo seleccionado y el ajuste de búsqueda web
  3. El backend procesa el mensaje: La ruta de la API recibe el mensaje y llama a streamText
  4. La IA decide qué herramientas usar: El modelo analiza la pregunta y decide si usar scrapeWebsite o searchWeb (solo si la búsqueda web está habilitada)
  5. Ejecución de herramientas: Si se invocan herramientas, Firecrawl hace scraping o busca en la web
  6. La IA genera la respuesta: El modelo analiza los resultados de las herramientas y genera una respuesta en lenguaje natural
  7. El frontend muestra los resultados: La interfaz muestra las llamadas a herramientas y la respuesta final en tiempo real

Proceso de llamada a herramientas

El sistema de llamadas a herramientas del AI SDK (ai-sdk.dev/docs/foundations/tools) funciona de la siguiente manera:
  1. El modelo recibe el mensaje del usuario y las descripciones de las herramientas disponibles
  2. Si el modelo determina que se necesita una herramienta, genera una llamada a la herramienta con parámetros
  3. El SDK ejecuta la función de la herramienta con esos parámetros
  4. El resultado de la herramienta se envía de vuelta al modelo
  5. El modelo usa el resultado para generar su respuesta final
Todo esto ocurre automáticamente dentro de una única llamada a streamText, con los resultados transmitiéndose al frontend en tiempo real.

Características clave

Selección de modelo

La aplicación admite varios modelos de OpenAI:
  • GPT-5 Mini (Thinking): Modelo reciente de OpenAI con capacidades avanzadas de razonamiento
  • GPT-4o Mini: Modelo rápido y rentable
Los usuarios pueden alternar entre modelos usando el selector desplegable.

Interruptor de búsqueda web

El botón Search controla si la IA puede usar las herramientas de Firecrawl:
  • Enabled: la IA puede invocar las herramientas scrapeWebsite y searchWeb según sea necesario
  • Disabled: la IA responde solo con el conocimiento de su entrenamiento
Esto les da a los usuarios control sobre cuándo usar datos de la web frente al conocimiento incorporado del modelo.

Ideas de personalización

Agregar más herramientas

Amplía el asistente con herramientas adicionales:
  • Consultas a la base de datos para datos internos de la empresa
  • Integración con el CRM para obtener información de clientes
  • Envío de correos electrónicos
  • Generación de documentos
Cada herramienta sigue el mismo patrón: define un esquema con Zod, implementa la función execute y regístrala en el objeto tools.

Cambiar el modelo de IA

Sustituye OpenAI por otro proveedor:
import { anthropic } from "@ai-sdk/anthropic";

const result = streamText({
  model: anthropic("claude-4.5-sonnet"),
  // ... resto de config
});
El SDK de IA es compatible con más de 20 proveedores con la misma API. Más información: ai-sdk.dev/docs/foundations/providers-and-models.

Personaliza la UI

Los componentes de AI Elements están basados en shadcn/ui, así que puedes:
  • Modificar los estilos de los componentes en sus archivos
  • Añadir nuevas variantes a los componentes existentes
  • Crear componentes personalizados que se ajusten al sistema de diseño

Mejores prácticas

  1. Usa las herramientas adecuadas: Elige searchWeb para encontrar primero páginas relevantes, scrapeWebsite para páginas individuales o deja que la IA decida
  2. Supervisa el uso de la API: Controla tu uso de las API de Firecrawl y OpenAI para evitar costos inesperados
  3. Gestiona los errores con elegancia: Las herramientas incluyen manejo de errores, pero considera añadir mensajes de error visibles para el usuario
  4. Optimiza el rendimiento: Usa streaming para ofrecer retroalimentación inmediata y considera cachear el contenido de acceso frecuente
  5. Establece límites razonables: stopWhen: stepCountIs(5) evita llamadas excesivas a herramientas y costos descontrolados