jevcrawl

为 AI 智能体打造的网页爬虫,找到的是答案,而不只是页面。

一个小型决策模型挑选每一个链接和每一段内容,因此你的智能体的 LLM 只读取能回答其问题的内容只需每次爬取几美分。

PyPI CI License Python MCP server Benchmark Cost

快速开始·基准测试·工具·工作原理·配置

Demo: jevcrawl crawls docs.python.org for 'What does the walrus operator := do and which Python version added it?' and returns the What's New In Python 3.8 passage. 6 pages, 80,034 tokens reduced to 1,873, $0.0069, 8.3 seconds.

On 50 WebWalkerQA tasks jevcrawl answered 40% correctly and found the answer page 54% of the time for $0.025 per task, against 30%, 33% and $0.194 when Claude picks every link and 8%, 11% and $0.228 for a breadth-first crawl.

为什么选择 jevcrawl

浏览网站的智能体有两个糟糕的选择。它们可以读取所有内容爬虫抓取到的内容,这会把答案淹没在导航和样板文字中,并消耗大量 token。或者它们可以让 LLM 挑选每个链接,这既慢又每个问题要花费数美元。jevcrawl 两者都不做:

  • 🎯更常找到答案页面。54% 的任务成功,而由 Claude 挑选链接时为 33%,并且是Crawl4AI目标导向爬取的 2 倍。
  • 💸每个任务约便宜 8 倍,每个正确答案便宜 10 倍。爬取决策的成本约为 1 美分。
  • ⚡比 LLM 驱动的爬取快 2 倍。一次处理四个页面,每个页面一次决策请求。
  • 📜逐字引用,附带来源。每一段内容都从页面复制,并附带其 URL、标题路径和字符偏移量。决策模型只进行评分,因此无法编造文本。
  • 🛡️从设计上防范提示注入。页面文本只会被评分,绝不会被遵循。
  • 🔌在所有支持 MCP 的地方都能用:Claude Code、Claude Desktop、Cursor 或 CLI。

快速开始

你需要一个 Jev API 密钥,来自console.typesafe.ai以及uv。

Claude Code

claude mcp add jevcrawl -e TYPESAFE_API_KEY=<your key> -- uvx jevcrawl

Claude Desktop、Cursor 和其他 MCP 客户端(mcpServers在客户端的配置文件中)

{
  "mcpServers": {
    "jevcrawl": {
      "command": "uvx",
      "args": ["jevcrawl"],
      "env": { "TYPESAFE_API_KEY": "<your key>" }
    }
  }
}

然后向你的智能体提出类似这样的请求"使用 jevcrawl 从 docs.python.org 开始,查找是哪个 Python 版本引入了海象运算符"。用以下方式检查设置uvx jevcrawl doctor。加载技能的智能体也可以使用skills/jevcrawl/SKILL.md。

基准测试

每个系统都从网站首页开始,使用相同的 30 页预算和相同的问题。每个系统收集到的内容都交给同一个回答 LLM,并且由同一个评判者为答案评分,因此爬虫是唯一变化的因素。

Cost of one correct answer: jevcrawl $0.06, Claude picking every link $0.65, breadth-first crawl $2.85.

jevcrawl 对比 Crawl4AI

Crawl4AI是最受欢迎的面向 LLM 的开源爬虫之一。其BestFirstCrawlingStrategy配合关键词评分器的方式,是在不使用 LLM 的情况下朝问题方向爬取,因此我们比较了两者是否能抓取到包含答案的页面。

On 20 tasks jevcrawl found an answer page 10 times and Crawl4AI 5 times; every answer page 5 vs 2; median crawl time 29 s vs 43 s; sites that failed to load 0 vs 3. jevcrawl found 6 answer pages Crawl4AI missed, Crawl4AI found 1 jevcrawl missed.

这些数字从何而来

任务 WebWalkerQA来自WebWalker:在网页遍历中对 LLM 进行基准测试(Wu et al., Alibaba Tongyi Lab,ACL 2025):答案藏在真实网站(会议、大学、组织、游戏)中需要点击数次才能到达的深处的问题,涵盖英文和中文。
任务选择 每个任务在运行前都经过实时复查:网站和答案页面仍能加载,且仍包含参考答案。开发过程中查看过的任务被排除(bench/tasks/seen-ids.txt)。
准确率运行 50 个任务,2026-10-12。作答模型claude-opus-5-5,评判claude-sonnet-5-5。
Crawl4AI 运行 20 个不同任务,2026-10-13,Crawl4AI 0.9.4。仅爬取,不使用 LLM:爬虫是否抓取到了金标页面?在准确率运行中,系统是否抓取到金标页面与它是否回答正确密切相关。
基线 Claude 选择每个链接:Claude 阅读每个页面并选择下一个链接。广度优先:每个页面到深度 2。所有系统共享 jevcrawl 的抓取器,并移除导航和页脚。
成本 Jev 成本按实际计费,精确。LLM 成本按 token 数量以标价计算。
注意事项 50 和 20 个任务是小样本:成本差距大且稳定,准确率差距则不那么稳定。Crawl4AI 驱动真实浏览器,jevcrawl 不运行 JavaScript。

基准测试代码及如何复现每个数字:bench/。

工具

工具 用于
crawl(goal, start_url, max_pages=30, max_seconds=120, return_tokens=4000, max_decision_usd=0.05) 答案可能在数页深处。返回相关段落。
scrape(url, goal=None) 一个已知页面。有目标时,只返回相关段落;无目标时,返回所有内容且不调用 Jev。
map(start_url, goal, limit=50, max_pages=10) 仅返回排序后的 URL,用于决定要scrape。
一个真实结果(docs.python.org,“海象运算符 := 是做什么的,哪个 Python 版本引入的?”)
{"blocks": [{"url": "https://docs.python.org/3/whatsnew/3.8.html",
             "heading_path": "What’s New In Python 3.8 > New Features > Assignment expressions",
             "text": "There is new syntax := that assigns values to variables as part of a larger expression. ...",
             "char_start": 307, "char_end": 580, "relevance": 0.97}],
 "uncertain": [],
 "pages": [{"url": "https://docs.python.org/3/", "title": "3.15.0 Documentation", "lang": "en",
            "text_sha256": "b624ce93..."}],
 "stats": {"pages_fetched": 6, "tokens_raw": 80034, "tokens_returned": 1873, "jev_calls": 11,
           "cache_hits": 0, "jev_input_tokens": 164139, "jev_cost_usd": 0.0069,
           "model": "jev-1.13.0", "degraded": false, "degraded_reason": null,
           "needs_js_urls": [], "stopped_because": "answered", "elapsed_seconds": 8.3}}

裁剪为一个块和一个页面。80,034 tokens 的页面变成了 1,873 tokens 的答案,花费 $0.0069,用时 8.3 秒。

  • blocks是相关段落,最相关的在前;uncertain是边缘的、值得在断定某些内容缺失之前一读的。
  • char_start/char_end索引进页面文本,其 sha256 位于pages,因此引用之后可以核对。
  • stopped_because是answered,frontier_empty,max_pages,max_seconds,budget或auth_error。
  • 预期内的失败会以{"error": "<code>", "message": "<what to do>"}返回;这些工具永远不会向智能体的会话抛出异常。

同样的操作可以从命令行使用(uv tool install jevcrawl或pip install jevcrawl将jevcrawl放到你的 path 中):

jevcrawl crawl https://docs.python.org/3/ --goal "海象运算符是做什么的?" [--json]
jevcrawl scrape https://example.com/help/returns [--goal "..."] [--json]
jevcrawl map https://example.com --goal "..." [--limit 20]
jevcrawl doctor

工作原理

A crawl in six steps: seed from the sitemap, fetch the best 4 pages, segment them into passages, filter boilerplate for free, Jev scores every passage and link in one request per page, Jev checks whether the kept passages answer the goal. If not, it follows the next best links. The docs.python.org example turned 80,034 tokens of pages into 1,873 tokens for $0.0069 in 8.3 s.
  • Jev 做判断,它不写作。 Jev对每个是/否问题返回一个概率,因此它无法生成文本。你得到的一切都是从页面复制来的。
  • 页面文本是数据,永远不是指令。它只出现在问题的数据字段中;每个问题句子都是 jevcrawl 编写的固定字符串。注入的 "ignore previous instructions" 最多只能影响某个分数。
  • 低于优先级下限的链接会被保留备用,而不是被丢弃,因此爬取在仍有页面预算时永远不会提前停止。
  • 失败会降级,不会隐藏。在三次 Jev 请求失败后,爬取会继续按广度优先进行,在uncertain中返回每个未评分的块,并设置stats.degraded。
  • 重复是免费的。Jev 的答案会缓存在本地(~/.jevcrawl/cache),因此在相同页面上针对相同目标不产生任何费用。

配置

环境变量 含义 默认值
TYPESAFE_API_KEY Jev API key(必填) 无
JEVCRAWL_BASE_URL Jev 兼容端点 https://api.typesafe.ai
JEVCRAWL_MODEL 模型 id jev-1.13.0(固定:阈值按版本校准)
JEVCRAWL_CACHE_DIR 答案缓存 ~/.jevcrawl/cache

其他一切(阈值、每页链接数、并发数)在jevcrawl/config.py中都有经过测量的默认值,Python 调用方可以传入自己的Config。

成本与隐私

Jev 仅对输入 tokens 收费,每百万 $0.042,用于jev-1.13.0;在基准测试中一次爬取平均花费 $0.011。max_decision_usd是硬性限制:可能超过它的请求永远不会被发送,爬取会以budget停止。每个结果都会报告jev_cost_usd,以及tokens_raw(普通爬取会交给你的 LLM 的内容)对比tokens_returned。

页面文本会发送到 TypeSafe(块、链接标签和 URL)进行评分。API key 从环境中读取,永远不会写入磁盘或日志。

负责任地爬取

jevcrawl 不读取robots.txt并且除了每次抓取四个页面之外,不会对自身进行速率限制。你需要对你抓取的网站、其服务条款以及适用于你的法律负责。它从不登录,不会试图绕过付费墙或 CAPTCHA,也不运行 JavaScript(需要 JavaScript 的页面列在stats.needs_js_urls中)。每次调用都受限于max_pages,max_seconds,max_decision_usd以及return_tokens。

贡献

uv sync
uv run ruff check 。 && uv run ruff format --check 。 && uv run mypy --strict jevcrawl
uv run pytest                                    #离线:所有 HTTP 均被模拟
TYPESAFE_API_KEY=... uv run pytest -m live -s    #一次极小的真实请求,花费不到一美分

测试从不接触网络或花钱;任何会这样做的都被标记为live。README 中的图表由assets/build.py根据实测数字绘制。欢迎提交 issue 和 pull request;请按照SECURITY.md中所述报告安全问题。

致谢

许可证

Apache-2.0