Crawl4AI 自适应爬取(AdaptiveCrawler)实战:三层评分、统计/嵌入双策略与从查询到自动停止的完整机制
本文以 Crawl4AI 的 AdaptiveCrawler 为核心,完整讲解自适应爬取如何判断“信息已足够”并自动停止:从三层评分体系(Coverage/Consistency/Saturation)、链接期望增益排序,到统计策略与嵌入策略的取舍、全部 AdaptiveConfig 参数、断点续爬与知识库导入导出。读完后,你可以为研究问答、知识库构建、API 文档抓取等场景配置出“不多爬、不漏爬”的采集流程,并能读懂源码中每一处停止判定的依据。
1. 它解决什么问题:不足爬取与过度爬取
传统爬虫按预定模式(BFS/DFS)盲目翻页,不知道何时已经收集到足够信息。Crawl4AI 的文档把这个场景类比为做研究:你不会读完图书馆里的每一本书,而是在找到足够回答问题的信息时就停下来(docs/md_v2/core/adaptive-crawling.md)。具体地,定向爬取面临两个极端:
- 不足爬取(Under-crawling):停得太早,漏掉关键信息;
- 过度爬取(Over-crawling):浪费资源爬取无关页面。
Adaptive Crawling 的解法是引入一个信息充分度评估循环:每爬一批页面,就重新计算“信息是否足够”,并据此决定下一个该爬哪些链接、是否收手。
从源码结构看,这个循环的入口是 digest()(crawl4ai/adaptive_crawler.py)。其主循环逻辑为:
- 先用
start_url抓取首屏(带链接预览),把内链放入待爬队列; - 每轮迭代(注意是按“批”计数,由
max_depth限制批次数,默认 5)依次执行:strategy.calculate_confidence(state):计算当前置信度;strategy.should_stop(state, config):判断停止条件(置信度达标、页数上限、无待爬链接、饱和等);strategy.rank_links(state, config):对候选链接按期望信息增益打分排序;- 若最高分低于
min_gain_threshold,直接停止; - 取前
top_k_links个未爬链接,通过_crawl_batch()用asyncio.gather并行抓取(_crawl_batch);
- 新结果并入知识库(
state.knowledge_base),新链接并入待爬队列,循环继续; - 若配置了
save_state=True,每轮批处理后自动把状态写盘,最终再保存一次。
每个页面抓取时都会启用链接预览(_crawl_with_preview,_crawl_with_preview):内部构造 CrawlerRunConfig,其中 LinkPreviewConfig(include_internal=True, include_external=False, query=query, concurrency=5, max_links=50, timeout=link_preview_timeout),并开启 score_links=True。也就是说,爬虫在决定访问某条链接之前,先并行抓取这些链接页面的 head 数据(title/description 等)做 BM25 式打分,链接对象上的 contextual_score 会直接参与后续相关性评分——这是自适应爬取“先预览、再决定”的关键工程细节。
2. 快速上手:最小可用示例
AdaptiveCrawler、AdaptiveConfig 均已从包顶层导出(见 crawl4ai/init.py),官方示例脚本位于 docs/examples/adaptive_crawling/basic_usage.py:
from crawl4ai import AsyncWebCrawler, AdaptiveCrawler
async def main():
async with AsyncWebCrawler() as crawler:
# 创建自适应爬虫(config 可选,缺省为统计策略 + 默认参数)
adaptive = AdaptiveCrawler(crawler)
# 携带查询开始爬取,返回 CrawlState
result = await adaptive.digest(
start_url="https://docs.python.org/3/",
query="async context managers"
)
# 查看统计(rich 可用时输出表格,否则输出纯文本)
adaptive.print_stats()
# 获取最相关内容
relevant_pages = adaptive.get_relevant_content(top_k=5)
for page in relevant_pages:
print(f"- {page['url']} (score: {page['score']:.2f})")
几个使用要点(以源码为准):
digest(start_url, query, resume_from=None)返回CrawlState,因此你可以直接访问result.crawled_urls、result.metrics、result.knowledge_base、result.crawl_order、result.new_terms_history等字段;AdaptiveCrawler(crawler)也支持不传 crawler(crawler=None),此时它内部自建AsyncWebCrawler并在结束时负责关闭(_owns_crawler逻辑,crawl4ai/adaptive_crawler.py#L1295-L1313);print_stats(detailed=False/True)会按当前策略输出不同指标:统计策略展示 Coverage/Consistency/Saturation 与查询词覆盖明细;嵌入策略展示验证分数、平均最小距离等(print_stats 实现);get_relevant_content(top_k)目前采用查询词与页面分词的词重叠度排序,返回包含url、score、content、index的字典列表(get_relevant_content);- 常用属性:
adaptive.confidence(当前置信度)、adaptive.is_sufficient(是否充分;嵌入策略下等价于“验证通过”)、adaptive.coverage_stats(页数、词频统计、三类分数等)。
3. AdaptiveConfig 全参数说明
AdaptiveConfig 是一个 dataclass(crawl4ai/adaptive_crawler.py#L153-L274),AdaptiveCrawler 构造时会调用 config.validate() 做断言校验。默认值以源码为准:
3.1 核心控制参数
| 参数 | 默认值 | 说明 |
|---|---|---|
confidence_threshold |
0.7 |
置信度达到该值即停止(0–1) |
max_depth |
5 |
主循环最多迭代批次数 |
max_pages |
20 |
最多爬取页数(安全上限) |
top_k_links |
3 |
每批选取排名前 K 的链接并行抓取 |
min_gain_threshold |
0.1 |
候选链接最高分低于该值则停止(期望增益下限) |
strategy |
"statistical" |
策略名:statistical 或 embedding |
save_state |
False |
是否每轮自动保存状态 |
state_path |
None |
状态文件路径(JSON) |
文档中给出的典型配置(docs/md_v2/core/adaptive-crawling.md):
from crawl4ai import AdaptiveConfig
config = AdaptiveConfig(
confidence_threshold=0.8, # 80% 置信即停(源码默认 0.7)
max_pages=30, # 最多 30 页(源码默认 20)
top_k_links=5, # 每批跟随 5 条链接(源码默认 3)
min_gain_threshold=0.05 # 期望增益低于 0.05 即停(源码默认 0.1)
)
adaptive = AdaptiveCrawler(crawler, config)
仓库中的 advanced_configuration.py 还给出三套对照配置:高精度(0.9/50 页/5 链接/0.02)、均衡(0.7/20 页/3 链接/0.05)、快速探索(0.5/10 页/2 链接/0.1),可用于理解每个旋钮的方向性影响。
3.2 评分权重参数(需各自和为 1,validate 强制校验)
| 参数 | 默认值 | 用途 |
|---|---|---|
coverage_weight |
0.4 |
置信度中 Coverage 的权重 |
consistency_weight |
0.3 |
Consistency 权重 |
saturation_weight |
0.3 |
Saturation 权重 |
relevance_weight |
0.5 |
链接排序中相关性的权重 |
novelty_weight |
0.3 |
新颖度权重 |
authority_weight |
0.2 |
权威性权重(统计策略中 authority 目前固定为 1.0,见下文说明) |
saturation_threshold |
0.8 |
饱和分达到该值即停止 |
consistency_threshold |
0.7 |
一致性阈值 |
3.3 嵌入策略专属参数
| 参数 | 默认值 | 说明 |
|---|---|---|
embedding_model |
"sentence-transformers/all-MiniLM-L6-v2" |
本地嵌入模型(未配置 embedding_llm_config 时使用) |
embedding_llm_config |
None |
嵌入模型配置,LLMConfig 或 dict,二者均支持 |
query_llm_config |
None |
查询扩展(chat completion)模型配置;未设置时回退到 embedding_llm_config |
n_query_variations |
10 |
生成的查询变体数量 |
coverage_threshold |
0.85 |
覆盖率阈值 |
alpha_shape_alpha |
0.5 |
覆盖形状计算参数 |
embedding_min_confidence_threshold |
0.1 |
置信度低于该值判定查询与内容完全无关并停止 |
embedding_coverage_radius |
0.2 |
覆盖判定距离阈值:查询点到最近文档余弦距离小于该值才算“被覆盖”,越小越严格 |
embedding_k_exp |
1.0 |
距离到分数的指数衰减系数,越大越强调极近距离匹配 |
embedding_nearest_weight |
0.7 |
混合打分中最近邻权重(与 top_k 权重和为 1) |
embedding_top_k_weight |
0.3 |
top-k 均值权重 |
embedding_overlap_threshold |
0.85 |
与知识库相似度超过该值的链接会被惩罚(去冗余) |
link_preview_timeout |
5.0 |
链接预览抓取超时(秒) |
embedding_min_relative_improvement |
0.1 |
相对提升低于 该值 × 当前置信度 视为收敛 |
embedding_validation_min_score |
0.3 |
留出验证集分数下限,低于它不信任收敛结论 |
embedding_quality_min_confidence |
0.7 |
验证通过后对外展示置信度的下界 |
embedding_quality_max_confidence |
0.95 |
展示置信度上界 |
embedding_quality_scale_factor |
0.833 |
展示置信度的线性映射斜率 |
注意一点容易混淆的地方:文档示例与 embedding_configuration.py 的注释中常把 embedding_k_exp=3.0 当作“严格模式推荐值”演示,但源码默认值是 1.0,调参时请以源码为准。
4. 统计策略(默认):三层评分的源码解读
statistical 策略对应 StatisticalStrategy:纯信息论 + 词频分析,无 API 调用、可离线运行,适合术语明确的技术文档类查询。
4.1 置信度 = 0.4×Coverage + 0.3×Consistency + 0.3×Saturation
calculate_confidence 将三类分数加权合并(calculate_confidence):
coverage = self._calculate_coverage(state) # 查询词覆盖
consistency = self._calculate_consistency(state) # 页面间术语一致性
saturation = self._calculate_saturation(state) # 新信息递减程度
confidence = 0.4 * coverage + 0.3 * consistency + 0.3 * saturation
从源码结构看,这里的权重是写死的 0.4/0.3/0.3(源码注释注明 config 权重尚未接入,但数值与 AdaptiveConfig 默认权重一致)。三类分数的算法:
- Coverage(覆盖):对每个查询词,计算
doc_coverage × (1 + 0.5 × freq_signal),其中doc_coverage = df / total_documents(多少比例页面含该词),freq_signal是对数归一化词频;所有查询词取均值后再开方(sqrt)使分数更直观。未出现的查询词计 0,直接拉低整体覆盖。 - Consistency(一致性):对知识库中任意两页做分词,计算 Jaccard 相似度,取所有词对的均值。文档少于 2 页时直接返回 1.0(单一文档天然自洽)。
- Saturation(饱和):记录每页带来的“新词数”历史
new_terms_history,饱和分 =1 − 最近新词率 / 初始新词率。新页带来的新词越少,饱和分越高,意味着“边际收益递减”。
should_stop 的统计版停止条件(should_stop):置信度 ≥ confidence_threshold、页数达到 max_pages、待爬队列清空、或饱和分 ≥ saturation_threshold,任一成立即停。
4.2 链接排序:相关性 + 新颖度
rank_links 对每条未爬链接打分:score = 0.5×relevance + 0.3×novelty + 0.2×authority(权重来自 config):
- Relevance:优先采用链接预览阶段产生的
contextual_score(BM25 上下文分);没有则退化为查询词与链接文本(text/title/head 中 title、description、keywords)的词重叠率(_calculate_relevance); - Novelty:链接预览词中“知识库尚不存在”的词占比,衡量这条链接能带来多少新信息(_calculate_novelty);
- Authority:源码中存在基于 URL 结构(
/docs/、/api/、/guide/、文件扩展名等)的启发式实现_calculate_authority,但当前rank_links中 authority 固定取 1.0,即该因子暂未参与实际计算——这是“从源码结构看”可以确认的实现现状。
5. 嵌入策略:语义空间覆盖、缺口驱动选链与验证式停止
embedding 策略对应 EmbeddingStrategy,在语义空间里回答“我离答完这个问题还有多远”,适合模糊主题、概念性研究类查询。核心机制有四块:
5.1 查询扩展:把一个问题展开成一个“点云”
digest 启动时(非恢复场景)会调用 map_query_semantic_space(query, n_query_variations)(map_query_semantic_space):
- 用 chat 模型生成查询变体(实际生成
n × 1.3条,多出的 30% 留作验证集); - 提示词要求“生成用户可能问的、探索不同侧面的问题变体”,返回 JSON 数组;
- 原始查询恒定保留在训练集,其余变体洗牌后按 80/20 拆分:80% 用于覆盖计算,20% 作为留出验证集(
_validation_queries); - 默认模型为
openai/gpt-4o-mini,通过query_llm_config可换(带指数退避的重试封装perform_completion_with_backoff)。
这就是为什么嵌入策略涉及两类 API 调用、需要两个不同的模型配置:
- Embedding 调用(文本→向量):用
embedding_llm_config,例如openai/text-embedding-3-small;不配置则回退到本地sentence-transformers/all-MiniLM-L6-v2(经 get_text_embeddings 路由); - 查询扩展(chat completion):用
query_llm_config,例如openai/gpt-4o-mini。
源码中的回退链很明确(_get_query_llm_config_dict):显式 query_llm_config → config 中的 query_llm_config → 旧版单一 llm_config → 调用方默认值。两种写法都受支持,LLMConfig 对象或 dict 均可(见 llm_config_example.py 与 embedding_strategy.py):
from crawl4ai import AdaptiveConfig, LLMConfig
# 推荐:LLMConfig 对象
config = AdaptiveConfig(
strategy="embedding",
embedding_llm_config=LLMConfig(
provider='openai/text-embedding-3-small',
api_token='your-api-key'
),
query_llm_config=LLMConfig(
provider='openai/gpt-4o-mini',
api_token='your-api-key'
)
)
# 等价写法:字典格式(向后兼容)
config = AdaptiveConfig(
strategy="embedding",
embedding_llm_config={'provider': 'openai/text-embedding-3-small', 'api_token': '...'},
query_llm_config={'provider': 'openai/gpt-4o-mini', 'api_token': '...'}
)
5.2 覆盖度量与“语义缺口”
每页新内容会被截断到 5000 字符后做向量化,并与已有知识库向量做去重:与任意已有向量余弦相似度 ≥ 0.95 的页面不入库(update_state,内部阈值 _kb_similarity_threshold = 0.95)。
置信度计算(calculate_confidence)对每个查询变体取它与知识库的“最佳余弦相似度”(向量归一化后矩阵乘法,全向量化实现),再做均值:confidence = mean(best_similarities),并顺带记录 coverage_score、avg_best_similarity、median_best_similarity 等指标。
选链阶段(find_coverage_gaps + select_links_for_expansion)则反过来找缺口:对每个查询变体计算到知识库的最小距离,距离超过 embedding_coverage_radius 的算“待填补缺口”;每条候选链接按“它能让这些缺口缩小多少”得分(缩小量 ×2 放大信号),再除以需填补缺口数得到均值分;若链接与知识库最大相似度超过 embedding_overlap_threshold,还要乘以 1 − (max_sim − threshold) × 2 的冗余惩罚;最后若有 contextual_score,做 score × 0.8 + contextual × 0.2 的混合。链接向量本身也带 md5 缓存,避免重复嵌入。
5.3 验证式停止与“无关查询”快速识别
should_stop(should_stop)实现了三档判定,全部写入 state.metrics:
- 无关查询短路:置信度 <
embedding_min_confidence_threshold(默认 0.1)且已爬过页面 → 标记is_irrelevant=True、stopped_reason='below_minimum_relevance_threshold',立即停止。例如拿 “how to cook pasta” 去爬 Python 文档,会很快以低置信度收场; - 收敛检查:维护
confidence_history,平均提升量 <embedding_min_relative_improvement × 当前置信度时视为学习曲线收敛; - 验证集把关:收敛后必须过
validate_coverage——对留出验证集查询计算到知识库的最小距离,换算得分取均值(验证向量只嵌入一次并缓存)。验证分 >embedding_validation_min_score才真正停止(stopped_reason='converged_validated');否则记low_validation并继续爬,防止“局部收敛但覆盖不足”时过早收手。
最终展示的置信度还经过一层“质量映射”(get_quality_confidence):验证通过时把学习分(0.4–0.7 区间)线性映射到 embedding_quality_min_confidence–embedding_quality_max_confidence(默认 0.7–0.95);未验证时只给 learning_score × 0.8 的保守分。digest 结束时会把这个质量分写回 metrics['confidence'](digest 尾部),同时写入 pages_crawled 与 depth_reached。
5.4 无关查询检测的代码验证
# 查询与内容完全无关 → 快速低置信停止
result = await adaptive.digest(
start_url="https://docs.python.org/3/",
query="how to cook pasta"
)
if result.metrics.get('is_irrelevant', False):
print("Query is unrelated to the content!")
print("Stopped after", len(result.crawled_urls), "pages")
仓库示例 embedding_strategy.py 用 “how to bake chocolate chip cookies” 做了同款验证,并演示了 result.semantic_gaps、result.expanded_queries 等嵌入策略特有字段。
6. 两种策略如何选
官方对比表(docs/md_v2/core/adaptive-crawling.md):
| 维度 | Statistical | Embedding |
|---|---|---|
| 速度 | 很快 | 中等(有 API/模型调用) |
| 成本 | 免费(离线可跑) | 取决于模型供应商 |
| 精度 | 精确词匹配场景好 | 概念理解场景优秀 |
| 依赖 | 无 | 嵌入模型 / API |
| 查询理解 | 字面 | 语义 |
| 最佳场景 | 技术文档、明确术语 | 研究、宽泛主题 |
经验法则:术语明确的技术站点选 statistical(零成本、快);主题模糊、需要同义词/概念泛化的研究型任务选 embedding。仓库里还有 embedding_vs_statistical.py 的对照脚本,测试用例则集中在 tests/adaptive/ 目录(如 test_adaptive_crawler.py、test_embedding_strategy.py)。
嵌入策略的完整调参空间见 docs/examples/adaptive_crawling/embedding_configuration.py,它给出“严格覆盖(科研)/快速探索/无关检测/高质量知识库/自定义供应商”五组配置,并附调参指南,例如:embedding_k_exp 低(1–2)更宽松收敛快、高(4–5)更严;embedding_coverage_radius 越低要求匹配越近;n_query_variations 5–7 快、15–20 覆盖更全但更慢。
7. 适用与不适用场景
官方文档给出的边界判断(docs/md_v2/core/adaptive-crawling.md):
适合:
- 研究任务:围绕某主题找全信息;
- 问答检索:为特定问题收集足够上下文;
- 知识库构建:为 AI/ML 应用产出聚焦数据集;
- 竞争情报:完整收集某产品/功能的信息。
不适合:
- 全站归档:需要每一页时请直接用全站爬取;
- 结构化抽取:目标页面模式已知时,用 CSS/LLM 抽取策略更直接;
- 实时监测:需要持续更新的场景不属于单次 digest 的范畴。
另外,AdaptiveCrawler 建立在 AsyncWebCrawler 之上,JavaScript 渲染、hooks、截图等底层能力全部继承(FAQ 中官方也确认了这一点)。
8. 输出解读:置信度、统计与停止原因
8.1 置信度区间含义
官方对置信度(0–1)的解释:
- 0.0–0.3:信息不足,需要更多爬取;
- 0.3–0.6:部分信息,可回答基础问题;
- 0.6–0.7:较好覆盖,可回答多数问题;
- 0.7–1.0:覆盖优秀,信息全面。
8.2 统计输出
adaptive.print_stats(detailed=False) # 摘要表:页数、词表规模、三类分数
adaptive.print_stats(detailed=True) # 明细:Top20 词频、爬取顺序、每页新词数
detailed=True 时,统计策略会逐个查询词打印“出现在 x/y 页、共 n 次”,并给出 Top 20 高频词、按 crawl_order 排列的爬取路径(每页新增词数);嵌入策略则输出嵌入模型名、查询变体数量、知识库向量形状、语义缺口数与示例变体(print_stats)。
8.3 值得留意的 metrics 键
result.metrics 中的关键键(均可从源码确认):confidence、coverage、consistency、saturation(统计策略);coverage_score、avg_best_similarity、validation_confidence、is_irrelevant、stopped_reason(取值如 converged_validated、below_minimum_relevance_threshold、low_validation);以及 pages_crawled、depth_reached。这些字段是判断“为什么停了”的第一手证据。
9. 持久化与断点续爬
CrawlState 是完整的可序列化状态对象:已爬 URL 集合、知识库、待爬链接、查询词、指标、词频/文档频率、新词历史、爬取顺序,以及嵌入策略的向量与语义缺口(CrawlState)。save() 将其转为纯 JSON(numpy 向量转 list,CrawlResult 抽为 url/content/links/metadata 四元组),load() 逆向还原。
config = AdaptiveConfig(
save_state=True,
state_path="my_crawl_state.json"
)
# 爬取过程中每轮批次后自动保存,结束时再保存一次
result = await adaptive.digest(start_url, query)
# 之后随时从断点恢复(注意:resume 时不会重新做查询扩展,直接复用已存向量)
result = await adaptive.digest(start_url, query, resume_from="my_crawl_state.json")
一个贴近生产的用法见 advanced_configuration.py:先用 max_pages=5 的 config 跑“模拟中断”,再换 max_pages=20 的 config + resume_from 续爬并抬升页数上限——状态文件里保留了已爬页面、词频与向量,续爬无需重来。
10. 知识库导出与跨会话导入
# 导出为 JSONL(每行一个文档)
adaptive.export_knowledge_base("knowledge_base.jsonl")
# 在另一个会话中导入
new_adaptive = AdaptiveCrawler(crawler)
await new_adaptive.import_knowledge_base("knowledge_base.jsonl")
从 export_knowledge_base / import_knowledge_base 的源码看,导出行包含:url、timestamp、success、query、content(raw markdown)、metadata、links,外加 crawl_metadata(crawl_order 序号、爬取时置信度、当时文档总数)。导入时通过 strategy.update_state 重建词频/向量状态,因此导入后可以继续用新查询扩展同一知识库。完整工作流(构建 → 导出 → 导入扩展 → 多项目合并)见 export_import_kb.py。
11. 典型实战配方
以下配方均继承自官方文档(docs/md_v2/core/adaptive-crawling.md):
研究助手——收集某编程概念的资料并取最相关摘录:
result = await adaptive.digest(
start_url="https://realpython.com",
query="python decorators implementation patterns"
)
for doc in adaptive.get_relevant_content(top_k=3):
print(f"\nFrom: {doc['url']}")
print(f"Relevance: {doc['score']:.2%}")
print(doc['content'][:500] + "...")
知识库构建——多查询累积后统一导出:
queries = [
"supervised learning algorithms",
"neural network architectures",
"model evaluation metrics"
]
for query in queries:
await adaptive.digest(start_url="https://scikit-learn.org/stable/", query=query)
adaptive.export_knowledge_base("ml_knowledge.jsonl")
API 文档爬虫——完整性优先的高阈值配置:
config = AdaptiveConfig(
confidence_threshold=0.85, # 更高阈值保证完整
max_pages=30
)
adaptive = AdaptiveCrawler(crawler, config)
result = await adaptive.digest(
start_url="https://api.example.com/docs",
query="authentication endpoints rate limits"
)
分领域调参(技术文档 0.85/低增益阈值、新闻 0.6/高增益阈值、电商 0.7/窄链接、学术研究 0.9/50 页等)可参考进阶文档 docs/md_v2/advanced/adaptive-strategies.md。
12. 最佳实践(官方建议)
- 查询构造:具体、描述性强,包含你预期会找到的关键词,避免过宽查询;
- 阈值调优:通用场景从默认 0.7 起步;探索性爬取降到 0.5–0.6;要求全覆盖时升到 0.8+;
- 性能:合理设置
max_pages上限;按站点结构调整top_k_links;重复爬取场景启用缓存; - 链接选择:理解爬虫按“查询相关性 + 期望信息增益 + URL 结构/深度”的优先级选链,再据此调整
relevance_weight/novelty_weight。
13. 扩展自定义策略
从源码结构看,正式的扩展点是 CrawlStrategy 抽象基类(crawl4ai/adaptive_crawler.py#L277-L299),四个抽象方法:
class CrawlStrategy(ABC):
@abstractmethod
async def calculate_confidence(self, state: CrawlState) -> float: ...
@abstractmethod
async def rank_links(self, state: CrawlState, config: AdaptiveConfig) -> List[Tuple[Link, float]]: ...
@abstractmethod
async def should_stop(self, state: CrawlState, config: AdaptiveConfig) -> bool: ...
@abstractmethod
async def update_state(self, state: CrawlState, new_results: List[CrawlResult]) -> None: ...
AdaptiveCrawler(crawler, config, strategy=MyStrategy()) 即可注入自定义实现(构造函数支持第三个 strategy 参数,_create_strategy 仅在你不传时按 config.strategy 名字选择内置策略)。仓库示例 custom_strategies.py 演示了“API 文档策略”(按 URL 模式加权、按 endpoint/示例/参数三类覆盖率打分)与“学术策略”(引用模式、章节关键词)的实现思路,可以作为自研策略的模板;更深入的调优内容见 docs/md_v2/advanced/adaptive-strategies.md。
14. FAQ(官方文档问答)
问:与传统爬取有何不同? 答:传统爬取按固定模式(BFS/DFS)走;自适应爬取基于信息增益智能决定“跟哪条链接”和“何时停止”。
问:能用于 JS 重度渲染的网站吗?
答:可以。AdaptiveCrawler 继承 AsyncWebCrawler 的全部能力,包括 JS 执行。
问:大型网站如何处理?
答:算法天然把爬取限制在相关区域内;max_pages 作为安全上限兜底。
问:能自定义评分算法吗?
答:可以,高级用户可实现自定义 CrawlStrategy,见第 13 节与 docs/md_v2/advanced/adaptive-strategies.md。
15. 延伸阅读(仓库内路径)
- 核心实现:crawl4ai/adaptive_crawler.py(
CrawlState、AdaptiveConfig、StatisticalStrategy、EmbeddingStrategy、AdaptiveCrawler) - 本文对应文档:docs/md_v2/core/adaptive-crawling.md
- 进阶策略与调参:docs/md_v2/advanced/adaptive-strategies.md
- API 参考:docs/md_v2/api/adaptive-crawler.md、docs/md_v2/api/digest.md
- 可运行示例目录:docs/examples/adaptive_crawling/(basic_usage / embedding_strategy / advanced_configuration / embedding_configuration / llm_config_example / export_import_kb / custom_strategies / embedding_vs_statistical)
- 测试:tests/adaptive/
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python07
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00