本指南介绍如何将 Firecrawl 与 LangGraph 集成,以构建可抓取和处理网页内容的 AI 智能体工作流。
安装与配置#
npm install @langchain/langgraph @langchain/openai firecrawl创建一个 .env 文件:
FIRECRAWL_API_KEY=your_firecrawl_keyOPENAI_API_KEY=your_openai_key注意: 如果使用 Node 版本低于 20,请安装
dotenv并在代码中添加import 'dotenv/config'。
基本工作流#
此示例演示了一个基本的 LangGraph 工作流,用于抓取网站并分析其内容。
import { Firecrawl } from 'firecrawl';import { ChatOpenAI } from '@langchain/openai';import { StateGraph, MessagesAnnotation, START, END } from '@langchain/langgraph';// Initialize Firecrawlconst firecrawl = new Firecrawl({ apiKey: process.env.FIRECRAWL_API_KEY });// Initialize LLMconst llm = new ChatOpenAI({ model: "gpt-5-nano", apiKey: process.env.OPENAI_API_KEY});// Define the scrape nodeasync 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}` }] };}// Define the analyze nodeasync function analyzeNode(state: typeof MessagesAnnotation.State) { console.log('Analyzing...'); const response = await llm.invoke(state.messages); return { messages: [response] };}// Build the graphconst graph = new StateGraph(MessagesAnnotation) .addNode("scrape", scrapeNode) .addNode("analyze", analyzeNode) .addEdge(START, "scrape") .addEdge("scrape", "analyze") .addEdge("analyze", END);// Compile the graphconst app = graph.compile();// Run the workflowconst result = await app.invoke({ messages: [{ role: "user", content: "Summarize the website" }]});console.log(JSON.stringify(result, null, 2));多步骤工作流#
此示例演示了一个更复杂的工作流,它会抓取多个 URL 并对其进行处理。
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 });// 定义自定义状态const WorkflowState = Annotation.Root({ urls: Annotation<string[]>(), scrapedData: Annotation<Array<{ url: string; content: string }>>(), summary: Annotation<string>()});// 抓取多个 URLasync 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 };}// 汇总所有已抓取的内容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 };}// 构建工作流图const workflow = new StateGraph(WorkflowState) .addNode("scrape", scrapeMultiple) .addNode("summarize", summarizeAll) .addEdge(START, "scrape") .addEdge("scrape", "summarize") .addEdge("summarize", END);const app = workflow.compile();// 执行工作流const result = await app.invoke({ urls: ["https://firecrawl.dev", "https://firecrawl.dev/pricing"]});console.log(result.summary);更多示例,请查阅 LangGraph 文档。

