このガイドでは、Firecrawl を LangGraph と連携し、Web コンテンツをスクレイピングおよび処理できる 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'を追加してください。
基本的なワークフロー#
この例では、Web サイトをスクレイピングしてコンテンツを解析する基本的な LangGraph ワークフローを紹介します。
import { Firecrawl } from 'firecrawl';import { ChatOpenAI } from '@langchain/openai';import { StateGraph, MessagesAnnotation, START, END } from '@langchain/langgraph';// Firecrawl を初期化するconst firecrawl = new Firecrawl({ apiKey: process.env.FIRECRAWL_API_KEY });// LLM を初期化するconst llm = new ChatOpenAI({ model: "gpt-5-nano", apiKey: process.env.OPENAI_API_KEY});// スクレイピングノードを定義する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}` }] };}// 解析ノードを定義するasync function analyzeNode(state: typeof MessagesAnnotation.State) { console.log('Analyzing...'); const response = await llm.invoke(state.messages); return { messages: [response] };}// グラフを構築するconst graph = new StateGraph(MessagesAnnotation) .addNode("scrape", scrapeNode) .addNode("analyze", analyzeNode) .addEdge(START, "scrape") .addEdge("scrape", "analyze") .addEdge("analyze", END);// グラフをコンパイルするconst app = graph.compile();// ワークフローを実行するconst 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 });// Define custom stateconst WorkflowState = Annotation.Root({ urls: Annotation<string[]>(), scrapedData: Annotation<Array<{ url: string; content: string }>>(), summary: Annotation<string>()});// Scrape multiple URLsasync 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 };}// Build the workflow graphconst workflow = new StateGraph(WorkflowState) .addNode("scrape", scrapeMultiple) .addNode("summarize", summarizeAll) .addEdge(START, "scrape") .addEdge("scrape", "summarize") .addEdge("summarize", END);const app = workflow.compile();// Execute workflowconst result = await app.invoke({ urls: ["https://firecrawl.dev", "https://firecrawl.dev/pricing"]});console.log(result.summary);より多くの例については、LangGraph のドキュメントを参照してください。

