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

# LangGraph

> Integra Firecrawl con LangGraph para crear flujos de trabajo de agentes

Esta guía explica cómo integrar Firecrawl con LangGraph para crear flujos de trabajo de agentes de IA que puedan rastrear y procesar contenido web.

<div id="setup">
  ## Configuración
</div>

```bash theme={null}
npm install @langchain/langgraph @langchain/openai firecrawl
```

Crea un archivo `.env`:

```bash theme={null}
FIRECRAWL_API_KEY=your_firecrawl_key
OPENAI_API_KEY=your_openai_key
```

> **Nota:** Si usas Node \< 20, instala `dotenv` y añade `import 'dotenv/config'` a tu código.

<div id="basic-workflow">
  ## Flujo de trabajo básico
</div>

Este ejemplo muestra un flujo de trabajo básico de LangGraph que realiza scraping de un sitio web y analiza el contenido.

```typescript theme={null}
import { Firecrawl } from 'firecrawl';
import { ChatOpenAI } from '@langchain/openai';
import { StateGraph, MessagesAnnotation, START, END } from '@langchain/langgraph';

// Inicializar Firecrawl
const firecrawl = new Firecrawl({ apiKey: process.env.FIRECRAWL_API_KEY });

// Inicializar LLM
const llm = new ChatOpenAI({
    model: "gpt-5-nano",
    apiKey: process.env.OPENAI_API_KEY
});

// Definir el nodo de scraping
async function scrapeNode(state: typeof MessagesAnnotation.State) {
    console.log('Scraping...');
    const result = await firecrawl.scrape('https://firecrawl.dev', { formats: ['markdown'] });
    return {
        messages: [{
            role: "system",
            content: `Scraped content: ${result.markdown}`
        }]
    };
}

// Definir el nodo de análisis
async function analyzeNode(state: typeof MessagesAnnotation.State) {
    console.log('Analyzing...');
    const response = await llm.invoke(state.messages);
    return { messages: [response] };
}

// Construir el grafo
const graph = new StateGraph(MessagesAnnotation)
    .addNode("scrape", scrapeNode)
    .addNode("analyze", analyzeNode)
    .addEdge(START, "scrape")
    .addEdge("scrape", "analyze")
    .addEdge("analyze", END);

// Compilar el grafo
const app = graph.compile();

// Ejecutar el flujo de trabajo
const result = await app.invoke({
    messages: [{ role: "user", content: "Summarize the website" }]
});

console.log(JSON.stringify(result, null, 2));
```

<div id="multi-step-workflow">
  ## Flujo de trabajo de varios pasos
</div>

Este ejemplo muestra un flujo de trabajo más complejo que hace scraping de varias URL y las procesa.

```typescript theme={null}
import { Firecrawl } from 'firecrawl';
import { ChatOpenAI } from '@langchain/openai';
import { StateGraph, Annotation, START, END } from '@langchain/langgraph';

const firecrawl = new Firecrawl({ apiKey: process.env.FIRECRAWL_API_KEY });
const llm = new ChatOpenAI({ model: "gpt-5-nano", apiKey: process.env.OPENAI_API_KEY });

// Definir estado personalizado
const WorkflowState = Annotation.Root({
    urls: Annotation<string[]>(),
    scrapedData: Annotation<Array<{ url: string; content: string }>>(),
    summary: Annotation<string>()
});

// Hacer scraping de múltiples URLs
async function scrapeMultiple(state: typeof WorkflowState.State) {
    const scrapedData = [];
    for (const url of state.urls) {
        const result = await firecrawl.scrape(url, { formats: ['markdown'] });
        scrapedData.push({ url, content: result.markdown || '' });
    }
    return { scrapedData };
}

// Resumir todo el contenido obtenido mediante scraping
async function summarizeAll(state: typeof WorkflowState.State) {
    const combinedContent = state.scrapedData
        .map(item => `Content from ${item.url}:\n${item.content}`)
        .join('\n\n');

    const response = await llm.invoke([
        { role: "user", content: `Summarize these websites:\n${combinedContent}` }
    ]);

    return { summary: response.content as string };
}

// Construir el grafo del flujo de trabajo
const workflow = new StateGraph(WorkflowState)
    .addNode("scrape", scrapeMultiple)
    .addNode("summarize", summarizeAll)
    .addEdge(START, "scrape")
    .addEdge("scrape", "summarize")
    .addEdge("summarize", END);

const app = workflow.compile();

// Ejecutar flujo de trabajo
const result = await app.invoke({
    urls: ["https://firecrawl.dev", "https://firecrawl.dev/pricing"]
});

console.log(result.summary);
```

Para ver más ejemplos, consulta la [documentación de LangGraph](https://langchain-ai.github.io/langgraphjs/).
