Crawl4AI LLMExtractionStrategy 实战:用任意 LLM 从网页提取结构化 JSON

发布时间:2026/9/7 15:13:45
Crawl4AI LLMExtractionStrategy 实战:用任意 LLM 从网页提取结构化 JSON Crawl4AI LLMExtractionStrategy 实战用任意 LLM 从网页提取结构化 JSON【免费下载链接】crawl4ai Crawl4AI: Open-source LLM Friendly Web Crawler Scraper. Dont be shy, join here: https://discord.gg/jP8KfhDhyN项目地址: https://gitcode.com/GitHub_Trending/craw/crawl4ai当你需要从网页中提取复杂、非结构化的信息——例如自然语言描述、分类标签、摘要或知识图谱——简单的 CSS/XPath 选择器往往无能为力。Crawl4AI 为此提供了 LLM 提取策略LLMExtractionStrategy通过 LiteLLM 抽象层接入任意大语言模型OpenAI、Ollama、Claude、Gemini 等自动分块应对 token 限制并支持基于 Pydantic 的 schema 约束提取。读完本文你将掌握 LLM 提取的完整配置参数、分块机制的源码级原理、token 用量监控方法以及可直接运行的完整示例含知识图谱构建。需要先明确一点LLM 提取比基于 schema 的确定式方案更慢、成本更高。如果你的页面结构规整应优先使用JsonCssExtractionStrategy或JsonXPathExtractionStrategy参见 无 LLM 提取策略只有当数据需要 AI 理解、解释或重组时本文的方案才是合适选择。1. 为什么选择 LLM 提取复杂推理站点数据非结构化、分散在多处、充满自然语言上下文时规则匹配无法覆盖语义提取摘要、知识图谱、关系型数据等需要理解而非匹配的任务灵活性可以通过instruction参数向模型下达任意转换、分类指令无需为每种新任务改写选择器。2. 供应商无关通过 LLMConfig 接入任意模型Crawl4AI 使用 LiteLLM 作为底层调用抽象通过provider 字符串如openai/gpt-4o、ollama/llama3、gemini/gemini-2.0-flash来标识模型。LiteLLM 支持的任何模型都可以直接使用。核心配置对象是LLMConfig定义于 async_configs.py可以方便地创建多组配置、实验不同模型以找到最优解更多参数说明见 LLMConfig 参数参考llm_config LLMConfig(provideropenai/gpt-4o-mini, api_tokenos.getenv(OPENAI_API_KEY))LLMConfig的完整参数源码确认参数类型说明providerstrprovider/model_name标识默认openai/gpt-4oDEFAULT_PROVIDER见 config.pyapi_tokenstrAPI 密钥支持env:VAR_NAME前缀从环境变量解析本地模型如 Ollama可省略base_urlstr自定义 API 端点如自建 OpenAI 兼容网关temperature/top_p/max_tokens—采样与长度控制也可通过策略的extra_args传入frequency_penalty/presence_penalty/stop/n—其余 OpenAI 风格采样参数backoff_base_delayint失败重试基础等待秒数默认 2backoff_max_attemptsint最大重试次数默认 3backoff_exponential_factorint指数退避因子默认 2两个值得注意的源码细节API key 自动解析如果你不显式传api_tokenLLMConfig会按 provider 前缀查找PROVIDER_MODELS_PREFIXES表config.py 中维护了openai、groq、anthropic、gemini、deepseek、bedrock等前缀与对应环境变量的映射。例如provideropenai/gpt-4o会自动读取OPENAI_API_KEYollama/*则被标记为no-token-needed。重试与退避每次 LLM 调用都通过perform_completion_with_backoff同步/aperform_completion_with_backoff异步见 utils.py发起网络抖动或限流会按backoff_base_delay * backoff_exponential_factor^n的策略自动重试最多backoff_max_attempts次。这意味着你不会被锁定在单一 LLM 供应商更换provider即可切换模型、对比效果与成本。3. LLM 提取的完整工作流程3.1 端到端流程LLMExtractionStrategy的提取流程实现位于 extraction_strategy.py 的LLMExtractionStrategy类内容选择与分块爬虫主流程根据input_format选取内容先用 chunking 策略切成 sections策略内部再按chunk_token_threshold与overlap合并/切分为 LLM 分块提示词构造为每个分块填充模板变量{URL}、{HTML}、{REQUEST}instruction、{SCHEMA}生成最终 promptLLM 推理异步路径用asyncio.gather对全部分块并行请求arun同步路径用ThreadPoolExecutor(max_workers4)并行run但对groq/前缀的 provider 采用串行 每块 0.5 秒间隔以规避速率限制结果解析与合并从blocks标签或force_json_response模式下的纯 JSON中解析出 block 列表追加错误标记后合并为最终 JSON。3.2 提示词模板的四种模式aextract/extract方法会根据参数组合选择 prompts.py 中的不同模板条件使用的模板行为无 instruction、无 schemaPROMPT_EXTRACT_BLOCKS让模型将页面拆成语义块并打标签block模式有 instruction、无 schemaPROMPT_EXTRACT_BLOCKS_WITH_INSTRUCTION按用户指令拆分语义块extraction_typeschema且有schemaPROMPT_EXTRACT_SCHEMA_WITH_INSTRUCTION将 JSON Schema 嵌入 prompt要求模型按 schema 提取并附带质量反思 1~5 分自评分的元认知约束显著降低格式错误率extraction_typeschema但未提供schemaPROMPT_EXTRACT_INFERRED_SCHEMA让模型自行推断最合理的 JSON 结构日期用 ISO 格式、价格不带货币符号等规范写在模板里3.3extraction_type参数schema默认值模型返回符合你 Pydantic schema 的 JSON。你传入schemaYourPydanticModel.model_json_schema()即可block模型返回自由文本块或小的 JSON 结构由库收集。注意一个源码细节__init__中有一行if schema: self.extract_type schema——只要提供了 schema即使你显式写了extraction_typeblock也会被强制切回schema模式。因此对结构化数据推荐始终使用schema并传入model_json_schema()。3.4 调用链与input_format的选择在爬虫主流程 async_webcrawler.py 中提取发生在 markdown 生成之后。主流程从config.extraction_strategy.input_format读取格式并在以下候选内容中取值content { markdown: markdown_result.raw_markdown, html: html, fit_html: fit_html, cleaned_html: cleaned_html, fit_markdown: markdown_result.fit_markdown, }.get(content_format, markdown_result.raw_markdown)markdown默认markdown_generator输出的原始 markdownfit_markdown内容过滤器如PruningContentFilter产出的精简版 markdown。若过滤器没有产出页面未触发过滤源码会自动回退到markdown而不是报错。如果你信任过滤器这可以大幅减少喂给 LLM 的 token 数html清洗后的 HTML 交给模型。若你的 instruction 依赖 HTML 标签结构选它。另一个细节当content_format是 HTML 类格式时主流程使用IdentityChunking()即整页作为单段由策略内部的merge_chunks统一负责切块而 markdown 类格式会先走config.chunking_strategy预切分再进入策略内的合并切块。4. 关键参数详解以下参数在LLMExtractionStrategy(...)中设置然后把策略挂到CrawlerRunConfig(..., extraction_strategy...)上。默认值均以源码config.py 常量与 extraction_strategy.py 构造签名为准llm_configLLMConfig模型与密钥配置如LLMConfig(provideropenai/gpt-4, api_token...)。若不传默认回落到openai/gpt-4o 环境变量OPENAI_API_KEYschemadict描述目标字段的 JSON Schema通常由YourModel.model_json_schema()生成extraction_typestrschema或block默认schemainstructionstr写给模型的提取指令如 Extract these fields as a JSON arraychunk_token_thresholdint每个 LLM 分块的目标 token 上限默认2**112048overlap_ratefloat相邻分块的重叠比例默认0.1即每块尾部约 10% 的内容会复制到下一块开头防止目标信息被切在边界上word_token_ratefloat词→token 换算系数默认1.3源码常量WORD_TOKEN_RATE注意这与部分早期文档提到的 0.75 不同以当前源码为准。merge_chunks用字数 × 该系数估算 token 数apply_chunkingbool默认True。设为False时源码会把chunk_token_threshold置为1e9等效于整页单次请求input_formatstr见上文 3.4markdown默认/fit_markdown/html及fit_html/cleaned_htmlforce_json_responsebool默认False。设为True时通过 LiteLLM 请求结构化输出并直接json.loads剥离 markdown 围栏后跳过blocks标签解析extra_argsdict经**kwargs传入透传给 LLM 的额外参数如temperature、max_tokens、top_pverbosebool打印每次 LLM 调用的分块索引与解析块数日志show_usage()方法打印 token 用量汇总与逐请求历史。弃用警告provider、api_token、base_url、api_base这四个旧参数已被标记为弃用源码中_UNWANTED_PROPS会在你试图设置它们时抛出AttributeError并提示改用llm_configLLMConfig(...)请不要再在新代码中使用。完整参数示例extraction_strategy LLMExtractionStrategy( llm_configLLMConfig(provideropenai/gpt-4, api_tokenYOUR_OPENAI_KEY), schemaMyModel.model_json_schema(), extraction_typeschema, instructionExtract a list of items from the text with name and price fields., chunk_token_threshold1200, overlap_rate0.1, apply_chunkingTrue, input_formathtml, extra_args{temperature: 0.1, max_tokens: 1000}, verboseTrue )5. 完整示例把策略挂进 CrawlerRunConfig重要在 Crawl4AI 中所有策略定义都应放进CrawlerRunConfig而不是直接作为arun()的参数。完整可运行示例import os import asyncio import json from pydantic import BaseModel, Field from typing import List from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig, CacheMode, LLMConfig from crawl4ai import LLMExtractionStrategy class Product(BaseModel): name: str price: str async def main(): # 1. 定义 LLM 提取策略 llm_strategy LLMExtractionStrategy( llm_configLLMConfig(provideropenai/gpt-4o-mini, api_tokenos.getenv(OPENAI_API_KEY)), schemaProduct.model_json_schema(), # 由 Pydantic 模型生成 JSON Schema extraction_typeschema, instructionExtract all product objects with name and price from the content., chunk_token_threshold1000, overlap_rate0.0, apply_chunkingTrue, input_formatmarkdown, # 或 html、fit_markdown extra_args{temperature: 0.0, max_tokens: 800} ) # 2. 构建爬虫运行配置 crawl_config CrawlerRunConfig( extraction_strategyllm_strategy, cache_modeCacheMode.BYPASS ) # 3. 按需创建浏览器配置 browser_cfg BrowserConfig(headlessTrue) async with AsyncWebCrawler(configbrowser_cfg) as crawler: # 4. 爬取单个页面 result await crawler.arun( urlhttps://example.com/products, configcrawl_config ) if result.success: # 5. 提取结果是 JSON 字符串 data json.loads(result.extracted_content) print(Extracted items:, data) # 6. 打印 token 用量 llm_strategy.show_usage() else: print(Error:, result.error_message) if __name__ __main__: asyncio.run(main())执行链路为crawler.arun()→ 主流程按input_format选内容 →strategy.arun(url, sections)→ 每块并行调用 LLM → block 列表json.dumps后写入result.extracted_content。6. 分块机制源码解析6.1chunk_token_threshold如何生效策略内部的_merge方法调用 utils.py 中的merge_chunks将 sections 合并为不超过target_size的分块。其核心逻辑对每个 section 按空白分词str.splittoken 数估算为词数 × word_token_rate默认 1.3预分配ceil(total_tokens / target_size)个分桶将词依次装入当前桶当当前桶达到target_size且overlap 0时把上一桶末尾的overlap个词复制到新桶开头——这就是overlap_rate的实现方式overlap int(chunk_token_threshold × overlap_rate)。所以调小chunk_token_threshold会得到更多分块、更高并行度与更大重叠开销估算偏保守1 词 ≈ 1.3 token意味着实际分块往往略短于上下文窗口这是有意为之的安全边际。6.2overlap_rate的作用overlap_rate0.1表示每个后续分块包含前一分块尾部约 10% 的文本。当目标信息可能横跨分块边界时例如一条产品描述被切开重叠能避免漏提取代价是重复 token 的额外成本。如果你的页面结构块与分块边界天然对齐可设为0.0。6.3 并行与串行从源码看arun异步用asyncio.gather并发处理所有分块同步run用 4 线程的线程池并行唯独groq/*provider 被特殊处理为串行 500ms 间隔规避其速率限制。分块并行确实能显著缩短大页面总耗时但要注意各供应商的并发/速率限制——重试退避backoff_*参数会兜底但高并发下仍可能触顶。6.4 响应解析与错误容错解析逻辑extract/aextract分三条路径force_json_responseTruejson.loads(_strip_markdown_fences(content))。若结果是 dict单键且值为 list 时解包为该 list如{news: [...]}→[...]否则包装成[dict]默认路径extract_xml_data([blocks], content)从blocks.../blocks标签中提取 JSON 数组——这也是为什么 schema 模板要求模型把结果包在blocks标签里兜底任一步解析失败时用split_and_parse_json_objects做尽力解析无法解析的残留文本会被追加为一个带error: True标记的块而不是抛出异常中断整个爬取。因此在CrawlResult.extracted_content中偶尔看到{error: true, tags: [error], ...}条目属于正常的部分失败信号生产代码应过滤这类块。7. Token 用量监控show_usage()每次 LLM 调用返回后策略都会记录一条TokenUsagecompletion_tokens、prompt_tokens、total_tokens及明细追加到self.usages并累加进self.total_usage。show_usage()会打印如下报告Completion/Prompt/Total 三项合计 逐请求历史表llm_strategy LLMExtractionStrategy(...) # ... 爬取完成后 ... llm_strategy.show_usage()如果你的模型供应商不返回 usage 字段这些数值可能部分缺失或为零。用量数据可用于成本核算与瓶颈定位若prompt_tokens远大于completion_tokens说明分块过大或input_format选了冗余格式应调低chunk_token_threshold或改用fit_markdown。提示JsonCssExtractionStrategy.generate_schema()也支持通过可选usage参数跟踪 token 用量参见 无 LLM 策略文档。8. 实战示例构建知识图谱下面展示用嵌套 Pydantic schema LLM 提取从新闻页面构建知识图谱的完整片段。注意instruction如何引导模型解析实体与关系import os import json import asyncio from typing import List from pydantic import BaseModel, Field from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig, CacheMode, LLMConfig from crawl4ai import LLMExtractionStrategy class Entity(BaseModel): name: str description: str class Relationship(BaseModel): entity1: Entity entity2: Entity description: str relation_type: str class KnowledgeGraph(BaseModel): entities: List[Entity] relationships: List[Relationship] async def main(): # LLM 提取策略 llm_strat LLMExtractionStrategy( llm_configLLMConfig(provideropenai/gpt-4, api_tokenos.getenv(OPENAI_API_KEY)), schemaKnowledgeGraph.model_json_schema(), extraction_typeschema, instructionExtract entities and relationships from the content. Return valid JSON., chunk_token_threshold1400, apply_chunkingTrue, input_formathtml, extra_args{temperature: 0.1, max_tokens: 1500} ) crawl_config CrawlerRunConfig( extraction_strategyllm_strat, cache_modeCacheMode.BYPASS ) async with AsyncWebCrawler(configBrowserConfig(headlessTrue)) as crawler: # 示例页面 url https://www.nbcnews.com/business result await crawler.arun(urlurl, configcrawl_config) print(--- LLM RAW RESPONSE ---) print(result.extracted_content) print(--- END LLM RAW RESPONSE ---) if result.success: with open(kb_result.json, w, encodingutf-8) as f: f.write(result.extracted_content) llm_strat.show_usage() else: print(Crawl failed:, result.error_message) if __name__ __main__: asyncio.run(main())关键观察extraction_typeschema保证输出是符合KnowledgeGraph的 JSONinput_formathtml意味着模型看到的是 HTML关系型信息往往藏在链接结构中instruction引导模型输出结构化知识图谱嵌套模型Relationship引用Entity通过model_json_schema()自动展开为完整 JSON Schema。9. 最佳实践与注意事项成本与延迟LLM 调用可能慢且贵。如果只需要部分数据考虑分块或缩小覆盖范围模型上下文限制页面 instruction 超出上下文窗口时apply_chunkingTrue是必需的并应根据模型窗口调整chunk_token_threshold指令工程精心编写的instruction能显著提升输出可靠性。schema 模板自带质量反思 自评分约束但你的指令越具体字段语义、取值格式、空值处理结果越稳定Schema 严格性schema模式会把模型输出解析为 JSON。模型返回非法 JSON 时解析器会尽力兜底未解析部分以error块形式出现——不要假设extracted_content总能json.loads出干净结构并行与速率限制异步路径全分块并发注意供应商限流。groq/*已被源码特殊处理为串行其他供应商如遇限流可调整backoff_*参数输出后校验LLM 可能遗漏字段或夹带多余文本。建议用 Pydantic 模型对每个 block 做二次校验Model.model_validate并妥善处理解析错误。10. 总结与后续步骤Crawl4AI 的LLM 提取是供应商无关的通过 LiteLLM 可从数百个模型中挑选非常适合语义复杂的任务摘要、分类、知识图谱。代价是更慢、更贵。记住四个要点把 LLM 策略放进CrawlerRunConfig用input_format决定 LLM 看到 markdown、HTML 还是精简 markdown调chunk_token_threshold、overlap_rate、apply_chunking处理大内容用show_usage()监控 token 消耗。后续方向实验不同供应商切换providerollama/llama3、openai/gpt-4o等对比速度、准确率与成本用extra_args微调temperature、top_p、max_tokens性能调优大页面场景下调节分块参数优化吞吐用show_usage()定位 token 瓶颈输出校验extraction_typeschema时用 Pydantic 模型做最终校验优雅处理偶发的畸形 JSON组合 Hooks 与自动化将 LLM 提取与 hooks 机制 结合做复杂前后处理构建爬取 → 过滤 → LLM 提取 → 存储/索引的多步流水线。如果你的站点数据规整、重复性强先用JsonCssExtractionStrategy追求速度与确定性当你需要AI 驱动的理解与重组时LLMExtractionStrategy提供了灵活的多供应商结构化 JSON 提取能力。【免费下载链接】crawl4ai Crawl4AI: Open-source LLM Friendly Web Crawler Scraper. Dont be shy, join here: https://discord.gg/jP8KfhDhyN项目地址: https://gitcode.com/GitHub_Trending/craw/crawl4ai创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考