关于 codearia-sieve
codearia-sieve 是供 Agent 开发者使用的网页解析 MCP 服务,将网页整理为带来源锚点的日期、数值事实和预算内文本块。它用普通代码处理,不调用模型,并提供用量与警告信息。
主要功能
- 01提取并规范化日期
- 02识别带单位的数值事实
- 03按预算切分文本块
- 04记录来源区块与页面锚点
- 05提供用量、警告和清理追踪
适用场景
- 01为决策模型准备网页输入
- 02核验提取事实在页面中的出处
- 03按需读取特定网页文本块
MCP 相关
通过 `sieve_page` 接收 URL 或 HTML 并返回结构化页面状态;`sieve_chunk` 可读取上次结果中的单个文本块。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
2收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| url | string | 否 | 要获取的页面。必须提供 url 或 html 之一。 |
| html | string | 否 | 要处理的原始 HTML,不通过抓取获取。为生成锚点,请同时提供 url。 |
| mode | enum | 否 | summary:不含分块文本的状态数据(开销低,默认值)。full:包含分块文本。markdown:返回易读文本,而非状态数据。summary | full | markdown |
| task | string | 否 | 你打算做出什么决策;配置了选择器时,此项可启用相关性筛选。 |
| trace | boolean | 否 | 包含被丢弃的内容以及日期的来源。 |
| maxChars | integer | 否 | 分块的字符数预算。 |
| maxTokens | integer | 否 | 分块的令牌数预算。 |
详细介绍
codearia-sieve
将网页解析为决策模型所需的精确格式。
日期就是日期。数字附带单位。文本拆分为适合模型上下文窗口的块,每块都指向其来源。
一次调用——调用前后的令牌开销一目了然。
npx codearia-sieve # MCP server for Claude Code, Cursor and any agent
npm i codearia-sieve # or the library
实测所得,绝非承诺。 我们在同一天随机选取网页进行了实时测试——包括来自多种语言 RSS 源的最新新闻、随机维基百科词条、文档、博客、政府网站、食谱和商店。每条结果都记录在 bench/analytics/ 中,运行 npm run analytics 即可重做全部测试。随后,我们将输出交给决策模型进行评估:请参阅 由评审验证。
它的作用
需要网页的 Agent 会获取整个页面:导航栏、Cookie 横幅、页脚、广告位,以及一兆字节的框架标记。然后,按令牌付费的大模型还得从这一大堆内容中找出一段文字。
codearia-sieve 会在模型看到任何内容之前完成这项筛选——并将页面作为状态而非散文返回:
|
日期变成标准日期
|
数字变成事实
|
文本拆分为合适的块 每个块都记录其令牌数和字符数、生成它所依据的内容块,以及用于核查决策的页面 |
其余内容——菜单、页脚、横幅、标签行、“阅读更多”——都会被移除;启用 trace: true 后,还会返回已移除内容的列表及移除原因。
构建 Agent、也见过账单的人。 每抓取一个页面,Agent 还没读到一个字,就要耗费数万个 token。样本中的页面 token 中位数:输入 53 718 个,输出 1 106 个。
运行低成本决策模型的人。 分类器、排序器,以及像 Jev 这样的 System One 模型:它们负责判断,而非写作。它们几乎免费,速度也很快,但能力有明显局限:不会计数,会把日期当作文本读取,而且上下文中无关内容越多,准确率就越低。每款“网页转 Markdown”工具都在为阅读者准备输入,而这款工具为判断者准备输入。
需要可核查答案的人。 如果抓取文本中的每一项都不能追溯到来源,那么基于这些文本给出的结论就无法证实。在这里,每条事实都注明其所在区块,每个分块都带有锚点。
工作原理
八个常规代码步骤。除非你接入模型,否则不会运行任何模型。相同的 HTML 会生成完全一致的 JSON,逐字节相同。
- 抓取 — 先检查
robots.txt;如果被拒绝,会报告拒绝结果,而不是绕过限制。使用普通 HTTP 和如实的用户代理。 - 解析 — 使用
linkedom将 HTML 解析为 DOM。不使用浏览器。 - 从未经改动的树中提取日期和 ID — 清理过程会移除
<head>、署名和属性,因此会在清理之前读取日期和 ID。 - 清理 — Defuddle 移除页面杂项;如果结果为空,则改用 Readability。内联元素之间会先插入空格,因此
<span>20 Sept</span><span>10 min</span>不会变成202610 min。 - 提取区块 — 按顺序提取标题、段落、列表、表格、代码和引文,并分配位置 ID。使用
<br><br>排版的旧页面也会转换为段落;表格行会保留其列标题。 - 提取事实和锚点 — 恢复 ID;仅在数字旁边有单位时才将其提取为事实;范围会保留两端。
- 分块 — 按顺序贪心分块,同时遵守两个预算:默认上限为 20 000 个 token 和 50 000 个字符。
- 组装 — 按需返回
state、markdown、usage、warnings和追踪信息。
结果示例
const r = await sieve({ kind: 'url', url: 'https://docs.typesafe.ai/models' });
r.state.title // "Models"
r.state.facts[0] // { value: 42, unit: "USD_per_billion", label: "price_btok_mtok",
// context: "Price (per Btok / per Mtok) | jev-1.13.0: $42 / $0.042", from: "b3" }
r.state.facts[1] // { value: 0.042, unit: "USD_per_million", … } — paired by position
r.state.chunks[0] // { id: "c1", tokens: 1210, chars: 5357, anchor: "Current models",
// headings: ["Current models", "Pricing", …], blocks: ["b1", …, "b36"], text: "…" }
r.usage // { rawTokens: 127413, stateTokens: 1211,
// visibleChars: 4939, stateChars: 5357, chunks: 1, ms: 1503 }
r.warnings // []
r.markdown // the same article, for a human or a generative model
预期情况不会导致异常,而是以警告形式返回,每种警告都有名称:
| 警告 | 含义 |
|---|---|
robots-disallowed | 网站要求爬虫不要访问;我们没有抓取 |
blocked | 遇到机器人验证或拒绝访问(403、405、429、“Just a moment…”),并附带状态码 |
http-error | 404 或 500 错误页面仍成功渲染;这不是你请求的页面 |
paywall | 页面标明文章并非免费;你拿到的是预览内容 |
empty-without-js | 文章容器为空,需要脚本填充内容 |
thin-content | 页面很大,但提取到的文本很少——例如首页或列表页 |
block-split | 某个区块超出预算,因此按句子边界切分 |
facts-capped | 页面中的事实超过了所列的 500 条——例如一份很长的费用表 |
用通俗的语言说出你的需求。Agent 会找到相关页面,对每个页面调用 sieve_page,将状态交给一个带类型问题的决策模型,然后整理结果。Sieve 负责准备。裁判负责评判。Agent 负责撰写。
{ "mcpServers": { "sieve": { "command": "npx", "args": ["-y", "codearia-sieve"] } } }
已列入官方 MCP Registry,条目为 io.github.AntonG87/codearia-sieve;能够读取该注册表的客户端可以按名称安装。
|
返回带有输出架构的类型化 |
返回该 URL 上次结果中的一个分块文本,不会重新抓取。先看概览,再获取所需内容——这个工具把自己的理念也应用到了自身。 |
它与 jev-mcp 配合使用:分块大小经过调整,适合放入其字段,因此状态可以直接传入类型化问题。
经裁判验证
我们的主张是:与原始文本相比,决策模型从 Sieve 获得的输入质量更好。因此,我们将输出交给了一个决策模型。 examples/jev.ts 使用官方客户端驱动这两个 MCP 服务——codearia-sieve 准备了 6 个页面(API 文档、发布说明、两种语言的两篇 Wikipedia 文章、两个定价页面),Jev 则通过 jev-mcp 对其进行评判。运行时间相同:2026 年 9 月 21 日:
| 向 Jev 提出的问题 | Sieve 提供的输入 | 结果 |
|---|---|---|
jev_classify — 这是哪种类型的页面? | 标题 + 第一个分块的开头,未超过工具的 2 000 字符限制 | 6 个全部正确;5 个自动判定,1 个标记待审核——该页面既是文档,也是费率表 |
jev_verify — 提取的每条事实是否确实出现在页面上? | 每条事实作为一项主张,其分块作为证据 | 11 条全部核实,且全部自动完成,置信度为 0.86–1.0 |
jev_extract — 页面何时发布? | 第一个分块、日期正则表达式、描述 | 页面注明日期时,结果与 Sieve 一致;Sieve 还会读取 JSON-LD 和 <meta>,而 Jev 看不到这些内容 |
这项测试的第一轮结果恰好相反:Jev 提交了 3 条事实供审核,并对其中 1 条提出异议。这 4 个问题都追溯到了 Sieve——一行表格被列标题而非行标题标注,一个表头中的两个费率没有正确配对,还有俄语参考文献中的“256 с.”被误读为秒。修复、测试、重跑:11 条全部通过。裁判能指出解析器何时出错,这正是两者配合的意义所在。
TYPESAFE_API_KEY=… node --experimental-strip-types examples/jev.ts
作为库使用
import { sieve } from 'codearia-sieve';
await sieve({ kind: 'url', url }); // fetch it
await sieve({ kind: 'html', html, url }); // already have it; url only for anchors
await sieve(input, {
budget: { maxTokens: 8000, maxChars: 30000 }, // chunk limits
trace: true, // everything discarded, and why
tokenizer: myTokenizer, // o200k by default; swap for your model's
fetcher: myFetcher, // your transport, or a file reader in tests
now: () => fixedDate, // injected clock: identical output on identical input
selector: mySelector, task: 'is this about pricing?', // relevance judge; nothing runs without one
});
parseDate、findDates 和供应商限制项(JEV、JEV_MCP、DEFAULT_BUDGET)也已导出。
能力边界
- 首页、列表页和产品页面没有可供查找的文章。你会得到标题和
thin-content警告,而不是虚假的成功结果。 - 由 JavaScript 渲染的文章在容器为空时会返回
empty-without-js。无法区分只提供摘要、其余内容再流式传输的网站和其他情况;若不使用浏览器,你只能得到摘要。 - 文本密集型页面节省较少。 一整本小说只能节省 22%,而一份 RFC 可节省 84%:没有可移除的包装,文本也会完整保留。这正是该工具应有的表现。
- 定价网格不是表格。 一条事实会记录它来自哪个区块,却不会记录它位于哪个套餐列之下;Sieve 不会猜测两者如何配对。发送整个分块——清理后的定价页面约有一千个 token——让裁判来阅读:
examples/pricing-watch.ts。 - Token 数量使用 o200k 进行近似估算。 超过一兆字节的页面会进行抽样计数,并设置
usage.rawTokensEstimated: true。
Develop
npm install
npm test # 71 tests, offline, a few seconds
npm run demo -- <url> # the token bill for one page
npm run bench # the 20-page benchmark set
npm run analytics # the 56-page random sample: rows, CSV, summary
Design notes — vision and architecture — are in docs/.
MIT © 2026 Anton Evelson · Codearia Academy
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。