Cómo crear un asistente de investigación con IA usando Firecrawl y el AI SDK
Crea un asistente de investigación completo con IA con capacidades de web scraping y búsqueda
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.
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.
- 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
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-firecrawlCuando 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í (@/*)
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 zodEstos paquetes ofrecen:
ai: SDK principal con streaming, invocación de herramientas y manejo de respuestas@ai-sdk/react: Hooks de React comouseChatpara crear interfaces de chatzod: 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@latestEsto 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/openaiConstruye 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.
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
Conversationgestiona 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 mensaje: Acciones de copiar y reintentar para los mensajes del asistente
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.
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:
"You are a helpful assistant that can answer questions and help with tasks.",
});
// 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
Configurar las variables de entorno
Crea un archivo .env.local en la raíz de tu proyecto:
touch .env.localAñade tu clave de la API de OpenAI:
OPENAI_API_KEY=sk-your-openai-api-keySe requiere la variable OPENAI_API_KEY para que el modelo de IA funcione.
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 devAbre 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.
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 firecrawlCrea el archivo de herramientas
Crea una carpeta lib y añade un archivo tools.ts dentro:
mkdir lib && touch lib/tools.tsAgrega el siguiente código para definir las herramientas de web scraping y búsqueda:
import { Firecrawl } from "firecrawl";
import { tool } from "ai";
import { z } from "zod";
const firecrawl = new Firecrawl({ apiKey: process.env.FIRECRAWL_API_KEY });
export const scrapeWebsiteTool = tool({
description: 'Scrape content from any website URL',
inputSchema: z.object({
url: z.string().url().describe('The URL to scrape')
}),
execute: async ({ url }) => {
console.log('Scraping:', url);
const result = await firecrawl.scrape(url, {
formats: ['markdown'],
onlyMainContent: true,
timeout: 30000
});
console.log('Scraped content preview:', result.markdown?.slice(0, 200) + '...');
return { content: result.markdown };
}
});
export const searchWebTool = tool({
description: 'Search the web using Firecrawl',
inputSchema: z.object({
query: z.string().describe('The search query'),
limit: z.number().optional().describe('Number of results'),
location: z.string().optional().describe('Location for localized results'),
tbs: z.string().optional().describe('Time filter (qdr:h, qdr:d, qdr:w, qdr:m, qdr:y)'),
sources: z.array(z.enum(['web', 'news', 'images'])).optional().describe('Result types'),
categories: z.array(z.enum(['github', 'research', 'pdf'])).optional().describe('Filter categories'),
}),
execute: async ({ query, limit, location, tbs, sources, categories }) => {
console.log('Searching:', 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 || 'Untitled',
url: item.url || '',
description: item.description || '',
}));
console.log('Search results:', 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
scrapede 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
searchde 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.
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.
Cambios clave respecto a la ruta básica:
- Importa
stepCountIsdel AI SDK - Importa las herramientas de Firecrawl desde
@/lib/tools - Agrega el objeto
toolscon las herramientasscrapeWebsiteysearchWeb - Agrega
stopWhen: stepCountIs(5)para limitar los pasos de ejecución - Establece
toolChoiceen “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.
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-keyObtén tu clave de la API de Firecrawl en firecrawl.dev.
Prueba la aplicación completa
Reinicia el servidor de desarrollo:
npm run devAbre localhost:3000 y prueba el asistente mejorado:
- Activa el botón “Search” para habilitar la búsqueda web
- Pregunta: “¿Cuáles son las funciones más recientes de firecrawl.dev?”
- Observa cómo la IA invoca la herramienta
searchWeboscrapeWebsite - Mira la ejecución de la herramienta en la interfaz con sus entradas y salidas
- Lee el análisis de la IA basado en los datos extraídos
- El usuario envía un mensaje: El usuario escribe una pregunta y hace clic en Enviar
- El frontend envía la solicitud:
useChatenvía el mensaje a/api/chatcon el modelo seleccionado y el ajuste de búsqueda web - El backend procesa el mensaje: La ruta de la API recibe el mensaje y llama a
streamText - La IA decide qué herramientas usar: El modelo analiza la pregunta y decide si usar
scrapeWebsiteosearchWeb(solo si la búsqueda web está habilitada) - Ejecución de herramientas: Si se invocan herramientas, Firecrawl hace scraping o busca en la web
- La IA genera la respuesta: El modelo analiza los resultados de las herramientas y genera una respuesta en lenguaje natural
- El frontend muestra los resultados: La interfaz muestra las llamadas a herramientas y la respuesta final en tiempo real
El sistema de llamadas a herramientas del AI SDK (ai-sdk.dev/docs/foundations/tools) funciona de la siguiente manera:
- El modelo recibe el mensaje del usuario y las descripciones de las herramientas disponibles
- Si el modelo determina que se necesita una herramienta, genera una llamada a la herramienta con parámetros
- El SDK ejecuta la función de la herramienta con esos parámetros
- El resultado de la herramienta se envía de vuelta al modelo
- 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.
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.
El botón Search controla si la IA puede usar las herramientas de Firecrawl:
- Enabled: la IA puede invocar las herramientas
scrapeWebsiteysearchWebsegú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.
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.
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.
Los componentes de AI Elements están basados en shadcn/ui, por lo 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
-
Usa las herramientas adecuadas: Elige
searchWebpara encontrar primero páginas relevantes,scrapeWebsitepara páginas individuales o deja que la IA decida -
Supervisa el uso de la API: Controla tu uso de las API de Firecrawl y OpenAI para evitar costos inesperados
-
Gestiona los errores con elegancia: Las herramientas incluyen manejo de errores, pero considera añadir mensajes de error visibles para el usuario
-
Optimiza el rendimiento: Usa streaming para ofrecer retroalimentación inmediata y considera cachear el contenido de acceso frecuente
-
Establece límites razonables:
stopWhen: stepCountIs(5)evita llamadas excesivas a herramientas y costos descontrolados