CrawlForge
首页Playground应用场景集成价格文档博客
在 LangChain 中使用 CrawlForge 的 5 种方式:AI web scraping 教程
Tutorials
返回博客
教程

在 LangChain 中使用 CrawlForge 的 5 种方式:AI web scraping 教程

C
CrawlForge Team
工程团队
2026年1月8日
阅读时长 12 分钟
更新于 2026年4月14日

本页内容

LangChain 是构建 LLM 应用的首选框架。CrawlForge MCP 则提供了 LangChain 应用常常需要的网络数据层。两者结合,是 AI 工程师手中的强大组合。

本教程将向你展示 5 种实用的集成模式,并附带可运行的代码示例。

前置条件

Bash
npm install langchain @anthropic-ai/sdk dotenv
Bash
# .env
ANTHROPIC_API_KEY=sk-ant-xxxxx
CRAWLFORGE_API_KEY=cf_live_xxxxx

在 crawlforge.dev/signup 获取你的 CrawlForge API key——已包含 1,000 个免费 credits。

1. 网络增强的 RAG 流水线

最常见的使用场景:用新鲜的网络数据增强你的 RAG 系统。

问题所在

静态 RAG 系统无法回答有关以下内容的问题:

  • 时事
  • 更新后的文档
  • 实时价格
  • 最新发布

解决方案

使用 CrawlForge 按需获取并索引网络内容。

Typescript
import { ChatAnthropic } from "@langchain/anthropic";
import { RecursiveCharacterTextSplitter } from "langchain/text_splitter";
import { MemoryVectorStore } from "langchain/vectorstores/memory";
import { OpenAIEmbeddings } from "@langchain/openai";

// CrawlForge client helper
async function fetchWebContent(url: string): Promise<string> {
  const response = await fetch('https://crawlforge.dev/api/v1/tools/extract_content', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.CRAWLFORGE_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ url })
  });

  const data = await response.json();
  return data.content || '';
}

// Web-augmented RAG
async function webAugmentedRAG(query: string, urls: string[]) {
  // 1. Fetch web content (2 credits per URL)
  const contents = await Promise.all(urls.map(fetchWebContent));

  // 2. Split into chunks
  const splitter = new RecursiveCharacterTextSplitter({
    chunkSize: 1000,
    chunkOverlap: 200
  });

  const docs = await splitter.createDocuments(contents);

  // 3. Create vector store
  const vectorStore = await MemoryVectorStore.fromDocuments(
    docs,
    new OpenAIEmbeddings()
  );

  // 4. Retrieve relevant chunks
  const relevantDocs = await vectorStore.similaritySearch(query, 4);

  // 5. Generate answer with context
  const llm = new ChatAnthropic({
    modelName: "claude-3-5-sonnet-20241022"
  });

  const context = relevantDocs.map(d => d.pageContent).join("\n\n");

  const response = await llm.invoke([
    {
      role: "system",
      content: "Answer based on the provided context. Cite sources when possible."
    },
    {
      role: "user",
      content: `Context:\n${context}\n\nQuestion: ${query}`
    }
  ]);

  return response.content;
}

// Usage
const answer = await webAugmentedRAG(
  "What are the new features in Next.js 15?",
  [
    "https://nextjs.org/blog/next-15",
    "https://nextjs.org/docs/app/building-your-application/upgrading"
  ]
);

credits 成本: 每获取一个 URL 收取 2 credits

2. 带工具调用的研究 agent

构建一个能够自主搜索和研究主题的 agent。

Typescript
import { ChatAnthropic } from "@langchain/anthropic";
import { DynamicStructuredTool } from "@langchain/core/tools";
import { AgentExecutor, createOpenAIFunctionsAgent } from "langchain/agents";
import { z } from "zod";

// Define CrawlForge tools for the agent
const searchTool = new DynamicStructuredTool({
  name: "search_web",
  description: "Search the web for information on a topic",
  schema: z.object({
    query: z.string().describe("The search query"),
    limit: z.number().optional().describe("Number of results (default 5)")
  }),
  func: async ({ query, limit = 5 }) => {
    const response = await fetch('https://crawlforge.dev/api/v1/tools/search_web', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${process.env.CRAWLFORGE_API_KEY}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ query, limit })
    });

    const data = await response.json();
    return JSON.stringify(data.results);
  }
});

const extractTool = new DynamicStructuredTool({
  name: "extract_content",
  description: "Extract the main content from a webpage URL",
  schema: z.object({
    url: z.string().describe("The URL to extract content from")
  }),
  func: async ({ url }) => {
    const response = await fetch('https://crawlforge.dev/api/v1/tools/extract_content', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${process.env.CRAWLFORGE_API_KEY}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ url })
    });

    const data = await response.json();
    return data.content || 'Failed to extract content';
  }
});

// Create the research agent
async function createResearchAgent() {
  const llm = new ChatAnthropic({
    modelName: "claude-3-5-sonnet-20241022"
  });

  const tools = [searchTool, extractTool];

  // Agent will autonomously decide when to search vs extract
  const agent = await createOpenAIFunctionsAgent({
    llm,
    tools,
    prompt: ChatPromptTemplate.fromMessages([
      ["system", "You are a research assistant. Use search_web to find sources, then extract_content to read them in detail."],
      ["human", "{input}"],
      ["placeholder", "{agent_scratchpad}"]
    ])
  });

  return new AgentExecutor({ agent, tools });
}

// Usage
const agent = await createResearchAgent();
const result = await agent.invoke({
  input: "Research the current state of WebAssembly for AI inference"
});

credits 成本: 每次搜索 5 credits + 每次提取 2 credits

3. 竞争情报流水线

监控竞争对手并提取结构化数据。

Typescript
interface CompetitorData {
  name: string;
  pricing: string[];
  features: string[];
  lastUpdated: Date;
}

async function analyzeCompetitor(url: string): Promise<CompetitorData> {
  // Use structured scraping (2 credits)
  const scrapeResponse = await fetch('https://crawlforge.dev/api/v1/tools/scrape_structured', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.CRAWLFORGE_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      url,
      selectors: {
        name: 'h1, .company-name, [data-company]',
        pricing: '.pricing-tier, .plan-price',
        features: '.feature-list li, .features li'
      }
    })
  });

  const scraped = await scrapeResponse.json();

  // Use LLM to structure the data
  const llm = new ChatAnthropic({ modelName: "claude-3-5-sonnet-20241022" });

  const structured = await llm.invoke([
    {
      role: "system",
      content: "Extract competitor data into structured JSON format."
    },
    {
      role: "user",
      content: `Analyze this competitor data: ${JSON.stringify(scraped)}`
    }
  ]);

  return JSON.parse(structured.content as string);
}

// Monitor multiple competitors
async function competitiveIntelligence(competitors: string[]) {
  const results = await Promise.all(
    competitors.map(url => analyzeCompetitor(url))
  );

  // Compare and summarize
  const llm = new ChatAnthropic({ modelName: "claude-3-5-sonnet-20241022" });

  const comparison = await llm.invoke([
    {
      role: "user",
      content: `Compare these competitors and identify market gaps: ${JSON.stringify(results)}`
    }
  ]);

  return { competitors: results, analysis: comparison.content };
}

credits 成本: 每个竞争对手 2 credits

4. 文档处理链

处理来自网络的 PDF 和文档。

Typescript
async function processDocuments(documentUrls: string[]) {
  const documents = [];

  for (const url of documentUrls) {
    // Process document (2 credits)
    const response = await fetch('https://crawlforge.dev/api/v1/tools/process_document', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${process.env.CRAWLFORGE_API_KEY}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        source: url,
        sourceType: url.endsWith('.pdf') ? 'pdf_url' : 'url'
      })
    });

    const data = await response.json();
    documents.push({
      url,
      content: data.content,
      metadata: data.metadata
    });
  }

  // Split and index documents
  const splitter = new RecursiveCharacterTextSplitter({
    chunkSize: 1500,
    chunkOverlap: 300
  });

  const chunks = await splitter.createDocuments(
    documents.map(d => d.content),
    documents.map(d => ({ source: d.url, ...d.metadata }))
  );

  return chunks;
}

// Use with LangChain vector store
const chunks = await processDocuments([
  'https://example.com/whitepaper.pdf',
  'https://example.com/technical-spec.pdf'
]);

const vectorStore = await MemoryVectorStore.fromDocuments(
  chunks,
  new OpenAIEmbeddings()
);

credits 成本: 每个文档 2 credits

5. 实时监控链

跟踪变化并对更新做出响应。

Typescript
import { RunnableSequence } from "@langchain/core/runnables";

async function checkForChanges(url: string, lastHash: string) {
  const response = await fetch('https://crawlforge.dev/api/v1/tools/track_changes', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.CRAWLFORGE_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      url,
      operation: 'compare'
    })
  });

  return response.json();
}

// Create a monitoring chain
const monitoringChain = RunnableSequence.from([
  // Check for changes
  async (input: { url: string }) => {
    const changes = await checkForChanges(input.url, '');
    return { ...input, changes };
  },
  // Analyze changes if found
  async (input) => {
    if (!input.changes.hasChanges) {
      return { ...input, analysis: "No changes detected" };
    }

    const llm = new ChatAnthropic({ modelName: "claude-3-5-sonnet-20241022" });
    const analysis = await llm.invoke([
      {
        role: "user",
        content: `Analyze these website changes: ${JSON.stringify(input.changes)}`
      }
    ]);

    return { ...input, analysis: analysis.content };
  },
  // Generate alert if significant
  async (input) => {
    if (input.analysis === "No changes detected") {
      return null;
    }

    return {
      url: input.url,
      timestamp: new Date(),
      analysis: input.analysis,
      raw: input.changes
    };
  }
]);

// Usage
const alert = await monitoringChain.invoke({
  url: "https://competitor.com/pricing"
});

if (alert) {
  console.log("Change detected:", alert);
}

credits 成本: 每次检查 2-5 credits

最佳实践

1. 积极使用缓存

Typescript
const cache = new Map<string, { content: string; timestamp: number }>();

async function cachedFetch(url: string, ttl = 3600000) {
  const cached = cache.get(url);
  if (cached && Date.now() - cached.timestamp < ttl) {
    return cached.content;
  }

  const content = await fetchWebContent(url);
  cache.set(url, { content, timestamp: Date.now() });
  return content;
}

2. 尽可能批量处理

Typescript
// Instead of multiple extract_content calls
const urls = ['url1', 'url2', 'url3'];

// Use batch_scrape (1 credit per URL vs 2 per URL)
const response = await fetch('https://crawlforge.dev/api/v1/tools/batch_scrape', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.CRAWLFORGE_API_KEY}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ urls })
});

3. 优雅地处理速率限制

Typescript
async function fetchWithRetry(url: string, retries = 3) {
  for (let i = 0; i < retries; i++) {
    const response = await fetch(url);

    if (response.status === 429) {
      const retryAfter = response.headers.get('Retry-After') || 60;
      await new Promise(r => setTimeout(r, Number(retryAfter) * 1000));
      continue;
    }

    return response;
  }
  throw new Error('Max retries exceeded');
}

开始使用

  1. 在 crawlforge.dev/signup 注册
  2. 获取你的 API key(1,000 个免费 credits)
  3. 安装 LangChain JS 并开始构建

需要帮助? 查看我们的 API 文档,或在 GitHub 上联系我们。

亲自试一试——无需注册

在 Playground 中运行 CrawlForge 的 27 个抓取与提取工具中的任意一个,然后免费开始,获取 1,000 credits。

1,000 免费 credits • 每月补充 • 无需信用卡

标签

LangChainTutorialAI EngineeringRAGPython

关于作者

C

CrawlForge Team

工程团队

我们正在打造功能最全面的 Web 抓取 MCP server。我们开发的工具帮助开发者为 AI 应用提取、分析和转换 Web 数据。

及时获取最新洞察

将教程、产品更新与 Web 抓取技巧直接发送到你的收件箱。

拒绝垃圾邮件,随时可取消订阅。

付诸实践

在任意 URL 上测试 CrawlForge 的工具——免费,无需注册。

本页内容

Frequently Asked Questions

如何在 LangChain 中使用 CrawlForge?+

安装 LangChain 和 Anthropic SDK,设置你的 CRAWLFORGE_API_KEY 环境变量,然后在 LangChain 的链或 agent 内部调用 CrawlForge 工具(extract_content、deep_research、search_web)。本文介绍了五种集成模式,包括网络增强的 RAG、带工具调用的研究 agent 以及实时监控链。

我可以用 CrawlForge 和 LangChain 构建网络增强的 RAG 流水线吗?+

可以。使用 CrawlForge 的 extract_content 工具获取 URL(每个 2 credits),用 LangChain 的 RecursiveCharacterTextSplitter 拆分内容,将文本块嵌入到 MemoryVectorStore 这样的向量存储中,并在查询时检索相关的文本块。这样你的 RAG 系统就能回答有关时事、更新文档和实时价格的问题,而不必依赖陈旧的训练数据。

如何将 CrawlForge 暴露为可供 agent 使用的 LangChain 工具?+

将每个 CrawlForge endpoint 封装成一个带 Zod 输入 schema 的 LangChain `DynamicStructuredTool`。agent 会根据用户查询选择合适的工具(search_web、extract_content、deep_research),并通过 CrawlForge 的 API 运行它们。本文给出了一个研究 agent 的完整代码,它将搜索与内容提取串联起来。

在 LangChain 工作流中使用 CrawlForge 的成本是多少?+

定价按工具计费:extract_content 为 2 credits,search_web 为 5 credits,deep_research 为 10 credits。免费套餐包含 1,000 个 credits,足够获取约 500 个页面或运行约 100 次搜索加提取的工作流。付费套餐起价为每月 $19,可获得 5,000 个 credits。

相关文章

LlamaIndex web scraping 指南:搭配 CrawlForge MCP
Tutorials

LlamaIndex web scraping 指南:搭配 CrawlForge MCP

为 LlamaIndex 提供实时网页数据。将 CrawlForge 用作 LlamaIndex 读取器,服务于 RAG pipeline、agent 工具和实时 LLM 知识库。

C
CrawlForge Team
|
4月14日
|
11 分钟
如何安装 CrawlForge MCP 并在 Claude Code 中使用:新手指南
Tutorials

如何安装 CrawlForge MCP 并在 Claude Code 中使用:新手指南

通过 npm 安装 CrawlForge MCP 并在 Claude Code 中配置的分步教程。一份对新手友好的指南,帮你添加 web scraping 工具。

C
CrawlForge Team
|
1月10日
|
10 分钟
如何用 TypeScript 构建一个 web scraping MCP server(2026)
Tutorials

如何用 TypeScript 构建一个 web scraping MCP server(2026)

用 TypeScript 和官方 SDK 构建一个可用的 web scraping MCP server:一台最小化服务器、一个真实的 cheerio 抓取工具、测试,以及 Claude Desktop 配置。

C
CrawlForge Team
|
6月16日
|
12 分钟

页脚

CrawlForge

面向 AI Agent 的企业级网页抓取。27 个专业 MCP 工具,专为构建智能系统的现代开发者而设计。

产品

  • 功能
  • Playground
  • 价格
  • 应用场景
  • 集成
  • 替代方案
  • 更新日志

资源

  • 快速上手
  • API 参考
  • 模板
  • 指南
  • 博客
  • 术语表
  • 常见问题
  • 网站地图

开发者

  • MCP 协议
  • Claude Desktop
  • Cursor IDE
  • LangChain
  • LlamaIndex

公司

  • 关于我们
  • 联系我们
  • 隐私政策
  • 服务条款
  • 可接受使用政策
  • Cookie

保持更新

获取新工具和新功能的最新动态。

基于 Next.js 和 MCP 协议构建

© 2025-2026 CrawlForge。保留所有权利。