# LangGraph (/es/developer-guides/llm-sdks-and-frameworks/langgraph)

<!-- agent-signals: reading_time_min: 2 · est_tokens: 1083 · updated: 2026-07-30 -->
Related: [OpenAI](/es/developer-guides/llm-sdks-and-frameworks/openai.md), [Anthropic](/es/developer-guides/llm-sdks-and-frameworks/anthropic.md), [Gemini](/es/developer-guides/llm-sdks-and-frameworks/gemini.md), [Kit de desarrollo de agentes (ADK)](/es/developer-guides/llm-sdks-and-frameworks/google-adk.md), [Vercel AI SDK](/es/developer-guides/llm-sdks-and-frameworks/vercel-ai-sdk.md), [LangChain](/es/developer-guides/llm-sdks-and-frameworks/langchain.md)

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 [#configuración]
</div>

```bash
npm install @langchain/langgraph @langchain/openai firecrawl
```

Crea un archivo `.env`:

```bash
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 [#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
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 [#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
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/).
