挑战
垂直领域 AI 初创公司通常在第二个月左右都会遇到相同的瓶颈。他们上线了客服 copilot、法律研究助手或合规机器人。最初的演示赢得了客户。随后数据老化,给出的回答开始偏离实际。
我们见过很多团队把 AI 架构做得很规范,却把数据摄取当作次要任务。数据采集流水线只是某台笔记本电脑上运行的一个 Python 脚本。它抓取 200 个源 URL 一次,把清洗后的 Markdown 导入向量数据库,随后全员庆祝上线。六周后,一半的回答都在引用已被删除的页面、废弃的 API,或是 3 月发布后又在 5 月变更的产品功能。
解决方案听起来很简单:每周重新爬取所有源。但现实更棘手。到 2026 年,约 60% 的知名站点会拦截 AI 爬虫(高于 2023 年底的 23%),而且防护策略不再只是简单的 User-Agent 检查。它们会分析会话行为、request 节奏以及握手层面的特征信号。1 月份还能正常运行的简陋脚本,到了 3 月份就会悄无声息地返回空页面。
更糟糕的是,一些站点现在会返回焦油坑内容(用马尔可夫链生成的看似真实的乱码),直到污染你的 embedding 数据。结果,你的工程师每周要花一半时间修补爬虫,而不是交付产品。检索质量下降,客户察觉到异常,你招聘来开发 AI 的团队最终沦为了爬虫维护团队。
解决方案
重新爬取的问题可以拆解为每次 request 都必须做出的三个具体决策:
- 是否渲染? 大多数文档门户提供干净的 HTML。但越来越多基于 Next.js 或包含客户端渲染的站点,需要完整的浏览器渲染才能返回有效内容。
- 使用哪种 proxy? 住宅、数据中心、移动、指定地理位置、特定 ISP。合适的选择因目标站点而异。
- 是否真正成功? 返回状态码 200 但 body 为空,或是返回了验证页面,这在 HTTP 层面是成功的 request,但在爬取层面则是失败的。
FourA 等平台将上述每个环节作为核心功能进行处理。
针对渲染决策,对于低成本、快速抓取的场景调用 Single,对于重度依赖 JS 的目标调用 Browser。调用的 body 结构保持一致,因此你的数据摄取代码只需根据每个数据源的配置做一次分支判断,而无需维护上百个针对特定站点的兼容逻辑。
针对 proxy 选择,Proxy Finder 会作为每次 Single、Browser 和 Auto 调用的一部分运行。平台会为每次 request 选择一个可用的出口节点,并在 response 中返回其不透明 id(在 Single/Browser 中位于顶层的 r.proxy,或在 Auto 中位于 r.session.proxy),当你需要保持同一出口时,可以在后续调用中复用该 id。你的爬虫无需自行实现 proxy 评分算法。(我们在 Why Proxy Pool Size Stopped Mattering in 2026 中分析了为什么代理池大小不再是决定性因素。)
针对“请求是否真正成功”的问题,每个 request 都支持 validate 配置块。你可以明确定义成功的判定标准:允许的 status codes、必须包含的 header values,以及必须出现或不得出现的 body 字符串。FourA 会返回七种结果之一,且仅对 success 计费。即使返回 200,只要未通过内容校验规则,就会被标记为 application_fail,绝不会写入你的数据集。
以下是针对需要 JS 渲染的文档站点的重新抓取调用示例。我们由 Auto 统一编排,它会自动选择合适的产品(Single、Proxy 或 Browser),处理反爬防护,并返回 session 三元组,以便下一次重新抓取时复用相同的出口节点:
import requests
r = requests.post(
"https://api.foura.ai/api/auto",
headers={"Authorization": "Bearer pk_live_..."},
json={
"url": "https://docs.example.com/changelog",
"validate": {
"status": {"accept": [200]},
"data": {"accept": ["<article"], "fail": ["captcha", "Just a moment"]},
},
},
).json()
# r["data"] or r["body"] — rendered content (Auto runs the right sub-product per host;
# Single populates "data", Browser populates "body")
# r["session"] — { "proxy": "<base36 id>", "cookies": [...], "userAgent": "..." }
# On the next recrawl, pass r["session"]["proxy"] back as `ignoreProxies: [<id>]` to avoid
# the same exit, or via /api/single with `proxy: <id>` to stick to it.
如果目标站点触发 Cloudflare 质询拦截页面,validate.data.fail 规则会捕获它。记入用量的结果为 application_fail。您无需为此付费,且数据接入代码会明确知道改用其他 proxy 重试,而不是将 "Just a moment..." 页面喂给 embeddings。
对于更大规模的语料库,您可以在现有作业队列中复用相同的模式。与我们交流过的团队通常会在夜间对比前一次抓取的差异,仅对实际变更的文档重新生成 embedding,在数小时内就能完成包含 500 个数据源的语料库更新。作业队列依然由您掌控。proxy 轮换、渲染决策以及成功判定则交给我们处理。
效果
当基础设施不再成为瓶颈时,新鲜度循环的实际表现如下(基于我们在垂直 AI 团队中观察到的典型场景):
- 每周重新抓取 500 个源 URL,而非上线时仅抓取一次 200 个 URL
- 抓取器的工程维护时间:每周低于 2 小时,低于原先的 1 到 2 天
- 检索过期间隔:5 到 7 天,而非无限期过期
- 向量数据库中的垃圾数据率接近零,因为 Cloudflare 质询页面和焦油坑页面在进入 embedding 模型前,就已被
validate层直接拦截 - 单个源的成本可预测,因为抓取失败不会计入账单
重点不在于这些有什么神奇之处。重点在于它们足够平淡可靠。而平淡可靠正是生产环境 AI 所需要的。(关于托管 LLM 提取何时在成本上不再划算,请参阅 When LLM Extraction Stops Paying for Itself。)
核心结论
多数构建垂直 AI 的团队认为护城河在于 prompt、模型选择或检索算法。其实不然。真正的护城河是新鲜度循环:即周复一周保持知识库真实有效的基础设施。
到 2026 年,在垂直 AI 领域胜出的团队不会是那些拥有最巧妙 prompt 的团队。而是那些用户从未察觉到数据是否最新,因为数据始终保持最新的团队。