关于 Agent Evidence API
Agent Evidence API 面向 AI Agent 提供带来源的网页证据、声明核验及美国国家气象局天气数据,可通过 HTTP 和 MCP 使用。证据摘录附有来源 URL、检索时间和内容哈希;仅在成功检索到内容时收取 x402 费用。
主要功能
- 01从指定网页提取相关证据
- 02提供支持、反驳等核验结论
- 03附来源、检索时间与内容哈希
- 04查询美国天气预警和预报
- 05支持免费预览真实结果
适用场景
- 01核验声明并追溯网页出处
- 02为研究问题收集指定网页证据
- 03查询美国某州天气预警
- 04获取指定坐标的天气预报
MCP 相关
通过 MCP 暴露证据检索、天气预警和天气预报工具,并提供免费的工具发现与示例。调用采用 x402 按次支付;没有检索到来源时不收费。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://agent-evidence.thx93.dev/mcpclaude mcp add --transport http thx93-agent-evidence-api https://agent-evidence.thx93.dev/mcp{"mcpServers":{"thx93-agent-evidence-api":{"type":"http","url":"https://agent-evidence.thx93.dev/mcp"}}}在 Cursor 中打开{"servers":{"thx93-agent-evidence-api":{"type":"http","url":"https://agent-evidence.thx93.dev/mcp"}}}在 VS Code 中打开{"mcpServers":{"thx93-agent-evidence-api":{"type":"http","url":"https://agent-evidence.thx93.dev/mcp"}}}{"mcpServers":{"thx93-agent-evidence-api":{"serverUrl":"https://agent-evidence.thx93.dev/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
详细介绍
Agent Evidence API
为 AI Agent 提供带引用、以来源为依据的网页证据与主张核验,以及来自美国国家气象局的天气信息——支持 HTTP 和 MCP。通过 x402 使用 Base 上的 USDC 按调用付费——每次调用 $0.01,未检索到任何内容时则完全免费。使用这两项服务均无需 API 密钥或账户。
| 内容 | 地址 |
|---|---|
| HTTP 证据端点 | POST https://agent-evidence.thx93.dev/v1/evidence |
| HTTP 天气预警 | POST https://agent-evidence.thx93.dev/v1/weather/alerts — {"state":"TX"} |
| HTTP 天气预报 | POST https://agent-evidence.thx93.dev/v1/weather/forecast — {"latitude":37.7749,"longitude":-122.4194} |
MCP 服务(research_evidence) | POST https://agent-evidence.thx93.dev/mcp |
| stdio 上的 MCP 服务(桌面客户端) | npx -y @thx93/agent-evidence-mcp — 使用你自己的钱包支付 x402 费用 |
MCP 服务(get-alerts、get-forecast) | POST https://agent-evidence.thx93.dev/weather/mcp |
| 真实输出免费示例 | GET https://agent-evidence.thx93.dev/demo — 来自实际付费调用的未经编辑的响应,无需钱包 |
| 零安装买家 CLI | curl -fsSL https://agent-evidence.thx93.dev/buy.mjs -o buy.mjs |
| x402 能力清单(全部五项付费资源) | https://agent-evidence.thx93.dev/.well-known/x402 |
所有 MCP 路由上的发现操作均免费(tools/list、initialize、ping 和一个
health 工具),因此 Agent 可以先查看架构并探测服务是否在线,再决定是否付费。
可选:语义排序
默认情况下,排序采用确定性的词法匹配,但效果存在经测量的上限。询问 “东京的人口是多少?” 时,它会返回提到“人口”和“东京”的段落——1603 年历史、战时人口下降、市政税——却漏掉回答问题的句子,因为该句写的是 “市区”,而没有重复“东京”。我们试过两种词法启发式方法,后来都撤回了;没有任何关键词技巧能解决这个问题。
可选的 Laya 伴随服务可以弥补这一缺陷。Laya 是一个开放权重(Apache-2.0)的类型化决策模型:它使用 noul 对段落评分,即 P(此段落直接回答了问题)。无供应商、无 API 密钥、无单次调用费用,你的内容也不会离开主机。
python services/laya/server.py # ~2 GB resident, ~35 s cold load
REASONING_PROVIDER=laya REASONING_URL=http://127.0.0.1:8077 ...
针对上述案例,在单个来源上的测量结果:
| 来源数 | none | laya | 前 3 条是否包含答案? |
|---|---|---|---|
| 1 | ~1.4 s | ~11.4 s | ❌ → ✅ |
| 5 | ~1.6 s | ~1.8 s(回退) | ❌ → ❌ |
只有在预算足以处理完整候选池时,才会启用模型。 每个候选项的耗时约为 800 ms(单次调用测得约 420 ms,但伴随服务会串行处理,因此在实际并发情况下约为 700 ms)。预算会在各来源间分配,因此 1–2 个来源可以处理宽度为 12 的候选池,而更大的请求则不行。测量发现,较窄的候选池毫无用处——它只能重新排列已经排除答案的段落——因此,与其为此耗费约 20 s,不如回退到词法排序,保持快速。降低 REASONING_POOL_SIZE,即可在更大的请求中启用,但会牺牲召回率。
预算是硬上限,而非目标:每次调用前都会预留预算,因此并发来源的总耗用不会超出上限。(早期版本会先检查预算,再等待;这样五个来源都会在任何一个来源扣减预算前通过检查——8 s 的预算最终导致请求耗时 50 s。)
取舍在于延迟,而非准确率:每个候选项约为 420 ms,因此包含 12 个候选项的候选池,每个来源需要约 5 s 的推理时间。这就是它默认关闭的原因。启用后只会改变证据的排序——每条摘录、来源、URL 和哈希都完全相同——如果找不到伴随服务、服务响应缓慢或返回意外内容,该服务会静默保留词法排序结果。原始模型概率绝不会公开(SPEC §21)。
请注意,候选池大小很重要:第一个版本只对词法排序已选出的 5 个候选项进行排序,而答案原本排在第 8–20 位,因此根本没有机会将它提升上来。更宽的候选池才是奏效的关键。
在 Docker 中运行后端?伴随服务必须能从容器访问:添加 --add-host=host.docker.internal:host-gateway 并将 REASONING_URL 指向 http://host.docker.internal:8077,或者将两者放在同一个 Docker 网络中。
只有在服务成功交付时才会向你收费
x402 中间件只有在处理程序返回低于 400 的状态码时才会结算付款,因此服务经过设计,所有失败情况都会返回 4xx 或 5xx:
- 如果无法检索任何来源——全部为 404、全部被 SSRF 拦截,或全部属于不受支持的内容类型——请求会以
NO_SOURCES_RETRIEVED(502)失败,不会扣款。早期版本在这种情况下会返回200 inconclusive,这会让买家为一个空结果支付 $0.03。 - 部分成功仍会结算。如果 5 个来源中有 1 个成功检索,就已交付真实证据;每个来源的警告会说明其余情况。
- 在 MCP 传输中,失败的工具调用会在 HTTP 200 响应中报告为
isError: true——这是正确的 MCP 行为,但支付中间件无法识别。Worker 会将其改写为 502,以免扣款;JSON-RPC 正文则保持原样传递。
已通过线上部署验证:所有来源均失败的请求会返回 502 NO_SOURCES_RETRIEVED;一个有效来源加一个失效来源的请求则会返回 200。
无需付费即可试用
每种付费接口都有免费的预览,会返回真实、未经编辑的结果,而非模拟内容:
curl -s -X POST https://agent-evidence.thx93.dev/v1/evidence/preview \
-H 'content-type: application/json' \
-d '{"question":"What is a centrifugal pump used for?",
"url":"https://en.wikipedia.org/wiki/Centrifugal_pump"}'
curl -s 'https://agent-evidence.thx93.dev/v1/weather/alerts/preview?state=TX'
curl -s 'https://agent-evidence.thx93.dev/v1/weather/forecast/preview?latitude=37.7749&longitude=-122.4194'
证据预览会返回一个来源和最多三个摘录,附带来源 URL、获取时间和内容哈希,但不提供评估结果。付费调用最多接受五个来源,并会给出「支持/反驳/混合/无法确定」的判定。
每个调用方地址每天可预览 25 次,无需账户或钱包。付费接口刻意分开设置:它们必须继续返回 402,因为每个 x402 目录和验证器都会检查这一点;如果在原接口中提供预览,就会导致服务无法上架。
常见问题
什么是 Agent Evidence API?
这是面向 AI Agent 的 HTTP 和 MCP 服务,可从公开网页返回带引用、以来源为依据的证据,并提供来自美国国家气象局的美国天气信息。你提交问题和最多五个 URL;它会返回与问题相关的段落,以及来源 URL、获取时间和内容哈希,并给出 supported、contradicted、mixed 或 inconclusive 评估。
我需要 API 密钥或账户吗? 不需要,无需注册。每次调用都通过 x402 在 Base 上以 USDC 付款,因此拥有钱包的 Agent 可以按实际使用量付费。
费用是多少? 每次调用 0.01 USDC。未获取到内容时不会收费——如果无法获取来源,或没有提供证据,就会取消结算。
我可以先查看输出再付款吗?
可以。GET /demo(HTML)和 GET /demo.json 会提供一个来自真实付费调用的完整、未经编辑的证据包。MCP sample 工具也会免费返回相同内容。
这与搜索引擎或网页抓取工具有什么不同? 两者都不是。URL 由你提供;服务不会替你发现来源。它提供的是出处信息:每段摘录都关联到一次真实获取操作,并附有时间戳和内容哈希,因此可以追溯某项声明对应网页实际写了什么。
它有哪些限制?
匹配采用确定性的词法匹配,而非语义匹配。如果问题涉及多个事项,但只有一个来源提供了匹配段落,服务会回答 inconclusive,而不会猜测。天气信息仅限美国,因为数据来自美国国家气象局。
如何通过 Agent 调用它?
可通过 HTTP(POST /v1/evidence)或 MCP(POST /mcp)调用。买家 CLI 无需安装:
curl -fsSL https://agent-evidence.thx93.dev/buy.mjs -o buy.mjs,或
npx @thx93/x402-evidence。
市场分析
docs/market-analysis.md — x402 经济实际为何付费:根据唯一发布真实使用数据的目录(每项服务过去 30 天的调用次数和独立付款人数)进行衡量。内容并不令人愉快:本服务所属类别的调用量仅为搜索类别的 1%,且其价格区间在五个类别中表现最弱。
工程报告
docs/ENGINEERING-REPORT.md — SPEC.md §44 要求提供的报告:已构建的内容、架构、部署和测试命令、x402 和 MCP 状态、注册目录的就绪情况、剩余的手动配置以及已知限制。报告明确说明哪些内容已演示,哪些尚未演示,包括尚未进行任何结算,以及一项 §42 验收标准未达成。报告不会声称项目已达到生产就绪状态。
只有你才能采取的操作
docs/CHECKLIST.md — 所有剩余且需要人工完成的步骤:首次付款、确认目录上架、发布内容,以及我特意留给你决定的事项。其他工作均已完成。
完成第一笔销售
请参阅 docs/FIRST-SALE.md — 从空钱包到付款结算和目录收录的完整流程,一页即可了解。
如何查看收入
后端在付费路由上处理的每个请求,都已通过后端自身的 x402 付款验证。Worker 只负责代理。日志以追加方式写入数据卷,因此即使容器重建或重新部署,日志也会保留,不像 Docker 日志那样会消失。
每一行表示此进程已验证一份付款凭证,不代表付款已结算。 x402 的顺序是验证 → 处理程序 → 结算,因此后端会在协调器完成结算前写入日志;之后即使结算失败,这里仍会显示该记录。因此字段命名为 payment_provided;它之前叫 settled,这是不正确的。
docker exec aee-live cat /app/data/usage.jsonl # the raw record
# Buyer traffic: requests that carried an x402 payment proof, so operator and
# test calls are excluded. This is NOT a revenue figure - see below.
docker exec aee-live sh -c "grep -c '"payment_provided":true' /app/data/usage.jsonl"
要查看实际到账金额,请查阅链上记录。买方客户端会打印结算交易,权威账本是收款地址:
https://basescan.org/address/0x9c0e2B44180439294Fa30Ae2B2a94f8655455FD0
每一行都包含时间戳、请求 ID、问题的加盐哈希(绝不记录问题文本)、检索到的来源数量、返回的证据条目数量、评估结果,以及服务端耗时。
{"ts":"2026-09-21T07:53:04.341Z","request_id":"req_2fcc…","question_hash":"725f50fca9fbe049",
"question_chars":32,"sources_requested":1,"sources_retrieved":1,"evidence_items":5,
"assessment":"supported","processing_ms":6,"outcome":"ok"}
关于链上记录,付款响应中包含结算交易哈希,收款地址为 0x9c0e2B44180439294Fa30Ae2B2a94f8655455FD0——请在 basescan 上核对。
在线部署
| 端点 | https://agent-evidence.thx93.dev |
| MCP | https://agent-evidence.thx93.dev/mcp |
| 健康状态 | /health · 深度检查:/health?deep=1 |
| 注册表 | io.github.Thx93/agent-evidence-api — 已发布,状态为 active |
| 付款 | x402,exact,Base 主网(eip155:8453)上的 0.03 USDC |
| 购买 | 无需安装:curl -fsSL .../buy.mjs -o buy.mjs && node buy.mjs "question" https://source.example |
无需 npm 账户,也无需安装任何东西即可购买;买方 CLI 是由服务本身提供的单文件独立程序:
curl -fsSL https://agent-evidence.thx93.dev/buy.mjs -o buy.mjs
X402_PRIVATE_KEY=0x... node buy.mjs "Is Rotamech a manufacturer of centrifugal pumps?" https://example.com
也可以先查看付费墙——这会返回 402,不会收取任何费用:
curl -X POST https://agent-evidence.thx93.dev/v1/evidence \
-H 'content-type: application/json' \
-d '{"question":"Is Rotamech a manufacturer of centrifugal pumps?","urls":["https://example.com"]}'
面向 AI Agent 的证据基础设施。 提交问题或主张,以及你希望核查的公开网页,它会返回结构化且带引用的证据:来源 URL、检索时间戳、简短证据摘录、元数据,以及明确的 supported / contradicted / mixed / inconclusive 评估结果。
AI Agent 可通过 HTTP 和 MCP 两种方式访问本服务,且每个请求都通过 x402 + Base 上的 USDC 付费。无需账户、密码或 API 密钥——付款即为身份验证。
- 产品规范:
SPEC.md— 需求的权威依据。 - 工程规则:
AGENTS.md— 项目唯一的规则手册。 - 架构:
docs/architecture.md
本服务提供证据,而非真相。 评估由确定性词汇匹配生成,服务会在无法判断时返回
inconclusive,而不是猜测。不要将supported状态视为证明。
实现状态 — 请先阅读此处。 所有软件包和两个应用均已实现,
pnpm typecheck已通过整个工作区的检查。pnpm test在六个测试套件中覆盖了约 147 个测试用例,其中包括一个跨软件包的端到端流程测试。尚未完成的事项:尚未演示过链上 x402 付款,没有自动化 x402 付款测试,
ROBOTS_POLICY虽已配置但尚未生效,并且apps/worker/wrangler.jsonc中有两个已提交的字面量测试钱包地址,在部署前需要替换。请参阅实现状态。
1. 服务的功能
Agent 提交:
- 一个问题或主张,以及
- 一个或多个用作来源的公开 URL。
随后,服务会:
- 验证 URL,并拒绝任何不安全的 URL(SSRF 防护),
- 在有界的超时时间、重定向次数和响应大小限制下获取页面,
- 检测内容类型并解析 HTML,
- 提取元数据(标题、描述、规范 URL、Open Graph、JSON-LD、语言、发布日期和修改日期、标题、字数),
- 规范化主要内容并生成 SHA-256 内容哈希,
- 提取与问题匹配的简短证据摘录,并标出其在文档中的位置,
- 比较各个来源并得出评估结果,
- 返回带有完整溯源信息的结构化响应。
它不是网页抓取工具、SEO 工具、通用爬虫、代理、浏览器自动化服务或搜索引擎。它是证据基础设施:Agent 需要展示依据时会调用的工具。
返回内容
{
"request_id": "req_3f9c1a7b2e4d4a6f8b0c1d2e",
"version": "1",
"question": "Is Rotamech Industries a manufacturer of centrifugal pumps?",
"assessment": {
"status": "supported",
"basis": "1 source(s) contained passages matching the question (example.invalid) with no contradicting passages found."
},
"sources": [
{
"requested_url": "https://example.invalid/products",
"final_url": "https://example.invalid/products",
"status": 200,
"content_type": "text/html; charset=utf-8",
"title": "Rotamech Industries — Products",
"canonical_url": "https://example.invalid/products",
"description": "Rotamech Industries manufactures centrifugal pumps for industrial use.",
"publisher": "Rotamech Industries",
"language": "en",
"published_at": "2024-03-01T09:00:00.000Z",
"modified_at": null,
"retrieved_at": "2026-09-20T21:16:07.412Z",
"word_count": 63,
"content_hash_sha256": "3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b",
"evidence": [
{
"excerpt": "Rotamech Industries is a manufacturer of centrifugal pumps.",
"context": "h2:Products > p[1]",
"relevance": "direct"
}
],
"structured_data": { "json_ld": [], "open_graph": {} },
"warnings": [],
"from_cache": false,
"redirect_chain": []
}
],
"limitations": [
"Assessment is derived from deterministic lexical matching, not semantic reasoning. A configured reasoning provider may refine it, but never replaces source evidence."
],
"processing_ms": 412
}
docs/api.md 中记录了每个字段。
2. Agent 为什么会使用它
因为引用来源的 Agent 比只会断言的 Agent 更有用。
- 依据支撑。 Agent 无需生成看似合理的句子,而可以附上真实的 URL、检索时间戳、内容哈希,以及支撑该主张的段落。
- 核实。 Agent 可以检查特定页面的实际内容,而不是依赖摘要。
- 比较。 服务会比较多个来源,并将分歧报告为
mixed,而不是把不同说法平均处理。 - 从设计上确保诚实。 没有足够匹配的内容时,答案为
inconclusive。服务绝不编造事实、绝不假装来源支持其实际不支持的说法,也绝不输出置信度分数。 - 无需入门流程。 无需注册、无需密钥、无需套餐。发现工具、调用工具、按请求付费并获取证据。
3. 使用案例
Agent 收到的问题是:“Rotamech Industries 实际上是离心泵制造商,还是只是经销商?”
它自身掌握的模型知识已经过时且无法核实,因此先收集候选 URL,再调用此服务:
{
"question": "Is Rotamech Industries a manufacturer of centrifugal pumps?",
"urls": [
"https://example.invalid/products",
"https://example.invalid/about",
"https://example.invalid/registry-record"
],
"max_sources": 5,
"language": "auto",
"mode": "evidence"
}
公司网站支持这一主张;注册信息页面则否定了这一点。服务返回:
{
"assessment": {
"status": "mixed",
"basis": "Sources disagreed: 2 leaning to support (example.invalid) and 1 leaning against (example.invalid)."
}
}
其中包含双方简短的引用摘录、检索时间戳和内容哈希。
现在,Agent 得到了此前没有的信息:一个有据可辩的答案,列出了双方说法并展示各自的出处,同时也诚实地说明了局限。它可以告诉用户“公司对此有此说法;注册信息记录对此提出异议;以下是双方来源”,而不是武断地选一方并表现得信心十足。
4. MCP 用法
传输方式:可流式传输的 HTTP。端点:与 API 同一主机上的 /mcp。
${MCP_PUBLIC_URL} e.g. https://${PUBLIC_API_DOMAIN}/mcp
工具
| 工具 | 付费情况 | 用途 |
|---|---|---|
research_evidence | 付费(x402) | 获取公开来源并返回结构化、带引用的证据。 |
health | 免费 | 状态检查。 |
客户端配置示例
{
"mcpServers": {
"agent-evidence-api": {
"type": "http",
"url": "${MCP_PUBLIC_URL}",
"headers": {
"Accept": "application/json, text/event-stream"
}
}
}
}
headers 中无需填写任何身份验证信息。这里没有密钥。
initialize 和 tools/list 免费
这对自主 Agent 很重要,也是有意如此设计的:
| JSON-RPC 方法 | 是否付费? |
|---|---|
initialize | 免费 |
tools/list | 免费 |
tools/call → health | 免费 |
tools/call → research_evidence | 付费 |
| 其他所有方法 | 免费 |
Agent 必须能够先发现工具,才能决定是否为其中某个工具付费。只有实际调用付费工具时才需要付费。如果 JSON-RPC 批次中任意一项是付费调用,整个批次都会计费。
示例工具调用
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "research_evidence",
"arguments": {
"question": "Is Rotamech Industries a manufacturer of centrifugal pumps?",
"urls": ["https://example.invalid/products"],
"max_sources": 5,
"language": "auto",
"mode": "evidence"
}
}
}
工具输入架构(与 HTTP 请求正文相同):
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
question | string | 是 | 1–2000 个字符。 |
urls | string[] | 否 | 架构中最多 25 个,运行时默认 5 个。 |
max_sources | integer | 否 | 正数,≤ 25。 |
language | string | 否 | "auto" 或 BCP-47 标签。 |
mode | "evidence" | 否 | v0.1.0 中唯一的值。 |
完整详情(包括 MCP 客户端收到的付款要求响应示例):docs/mcp.md。
5. HTTP 用法
GET /health free liveness
GET / free capabilities
POST /v1/evidence paid the evidence resource
GET /health
curl -s https://${PUBLIC_API_DOMAIN}/health
{ "status": "ok", "service": "agent-evidence-api", "version": "0.1.6" }
GET /
免费的能力描述,可用于在付款前发现服务。
curl -s https://${PUBLIC_API_DOMAIN}/
{
"service": "agent-evidence-api",
"version": "0.1.6",
"description": "Evidence infrastructure for AI agents. Returns structured, cited, freshly-retrieved evidence from public web pages so an agent can verify claims and ground answers in sources.",
"endpoints": {
"health": "GET /health (free)",
"evidence": "POST /v1/evidence (paid, x402)",
"mcp": "POST /mcp (MCP streamable HTTP; initialize and tools/list are free)"
},
"mcp": { "transport": "streamable-http", "tools": { "research_evidence": "paid", "health": "free" } },
"payment": {
"protocol": "x402",
"scheme": "exact",
"network": "eip155:84532",
"asset": "USDC",
"price_usd": "0.03",
"recipient": "0x…",
"facilitator": "https://x402.org/facilitator"
}
}
POST /v1/evidence
POST /v1/evidence HTTP/1.1
Host: ${PUBLIC_API_DOMAIN}
Content-Type: application/json
payment-signature: <x402 payment proof>
{
"question": "Is Rotamech Industries a manufacturer of centrifugal pumps?",
"urls": ["https://example.invalid/products", "https://example.invalid/about"],
"max_sources": 5,
"language": "auto",
"mode": "evidence"
}
返回 §1 中所示的 EvidenceResponse 文档。
没有有效付款时,会收到 HTTP 402,其中包含 PAYMENT_REQUIRED 错误信封和 x402 付款要求:
{
"error": {
"code": "PAYMENT_REQUIRED",
"message": "Payment is required to access this resource.",
"request_id": "req_5c4b3a291807f6e5d4c3b2a1"
}
}
错误
所有失败都使用同一种信封。错误代码保持稳定——请根据 error.code 进行判断。
{
"error": {
"code": "INVALID_URL",
"message": "The supplied URL is invalid or unsupported.",
"request_id": "req_3f9c1a7b2e4d4a6f8b0c1d2e"
}
}
| 代码 | HTTP |
|---|---|
INVALID_REQUEST | 400 |
INVALID_URL | 400 |
BLOCKED_URL | 400 |
SSRF_ATTEMPT | 400 |
PAYMENT_REQUIRED / PAYMENT_INVALID / PAYMENT_EXPIRED | 402 |
UNAUTHORIZED | 401 |
UNSUPPORTED_CONTENT | 415 |
RATE_LIMIT | 429 |
EXTRACTION_FAILURE / INTERNAL_ERROR | 500 |
TIMEOUT | 504 |
REDIRECT_LIMIT / RESPONSE_TOO_LARGE / UPSTREAM_HTTP_FAILURE / BACKEND_UNREACHABLE | 502 |
NOT_CONFIGURED | 503 |
含义完整表格:docs/api.md §5。
一个来源失败不会导致请求失败
如果 5 个 URL 中有一个无法访问,你仍会收到其他 4 个来源的结果。失败的来源会显示为 status: null、空的 evidence,并附带说明原因的警告:
{
"requested_url": "https://example.invalid/gone",
"status": null,
"evidence": [],
"warnings": [
{ "code": "UPSTREAM_HTTP_FAILURE", "message": "The source returned an error status." }
]
}
同时,limitations 会增加:"有 2 个来源中的 1 个无法检索;请查看各来源的警告。"
6. x402 付款流程
Agent
│ 1. POST /v1/evidence (or tools/call research_evidence)
▼
Worker ──▶ 402 Payment Required + payment requirements
│
Agent
│ 2. pays USDC on Base / Base Sepolia to the recipient address
│ 3. retries the same request with payment-signature: <proof>
▼
Worker ──▶ 4. verifies via the x402 facilitator
│ invalid → 402 PAYMENT_INVALID
│ expired → 402 PAYMENT_EXPIRED
▼
Backend ──▶ 5. runs the evidence pipeline
▼
Worker ──▶ 6. 200 + EvidenceResponse
- 无需 API 密钥,无需用户账户。 这是有意为之(SPEC §11、§38)。Agent 不应需要注册、申请密钥或订阅。
- 收款方只需要一个公开地址。 接收 USDC 无需私钥,因为服务不会签署任何内容——付款由客户端签署。
- 切勿提交私钥。 不要放进
wrangler.jsonc、.env,也不要放在其他任何地方。X402_TEST_PRIVATE_KEY是仅供本地测试使用的一次性 Base Sepolia 密钥,绝不可存入主网资金,也绝不可提交。 - 开发绕过机制有双重保护。 本地设置
DEV_BYPASS_PAYMENT=true可跳过付款检查——但仅限网络不是 Base 主网的情况。在eip155:8453上,即使该标志泄漏到生产配置中,也绝不能绕过付款。
完整详情:docs/x402.md。
7. Base 和 Base Sepolia
| 环境 | 网络 | CAIP-2 标识符 |
|---|---|---|
| 测试 | Base Sepolia | eip155:84532 |
| 生产 | Base | eip155:8453 |
两种情况下的结算代币均为 USDC。
测试网和生产环境的配置分别保存在不同的 Worker 环境中,绝不可混用。packages/core/src/config.ts 中的安全默认值是 Base Sepolia,因此未配置的部署会运行在测试网上,而不是意外运行在主网上。
apps/worker/wrangler.jsonc 提供了三个环境:
| 环境 | 激活方式 | 网络 | 付款 |
|---|---|---|---|
| production | wrangler deploy | eip155:8453(Base) | 必需 |
| dev | wrangler dev --env dev | eip155:84532(Sepolia) | 已绕过 |
| test | wrangler dev --env test | eip155:84532(Sepolia) | 必需 |
8. 定价配置
定价由环境变量驱动,不会硬编码。
| 变量 | 默认值 | 含义 |
|---|---|---|
X402_PRICE_USD | 0.01 | 每次请求的价格,单位为 USD。 |
X402_NETWORK | eip155:84532 | 结算网络。 |
X402_RECIPIENT | (empty) | 公开收款地址。 |
X402_FACILITATOR_URL | https://x402.org/facilitator | 用于验证的 Facilitator。 |
MVP 默认价格约为每次证据请求 $0.03。这是起始价格,并非固定的商业定价。
使用前会对价格字符串进行标准化:开头的 $ 可省略,数值会格式化为两位小数。请注意,无法解析的值不会导致 Worker 停止运行——系统会静默回退到 $0.03。每次更改后都请验证该值。
9. 本地开发
需要 Node.js ≥ 22.6(缓存使用内置的 node:sqlite 模块,因此无需编译原生依赖)和 pnpm。
pnpm install
cp .env.example .env # placeholders only; fill in locally, never commit
openssl rand -hex 32 # → BACKEND_AUTH_SECRET
pnpm typecheck
pnpm test
| 脚本 | 用途 |
|---|---|
pnpm typecheck | 对所有工作区的源码进行类型检查。 |
pnpm test | 运行所有 *.test.ts 文件。 |
pnpm test:security | SSRF / URL 验证测试套件。 |
pnpm test:e2e | 端到端验收流程。 |
pnpm fixtures | 确定性的本地 fixture 服务。 |
pnpm dev:backend | 在 :8080 启动后端。 |
pnpm dev:worker | 在 :8787 启动 Worker。 |
pnpm validate | typecheck && test。 |
fixture 服务(tests/fixtures/server.ts)离线运行且结果确定——不依赖在线网站。它会提供内容页面、重定向链、重定向到私有地址和元数据的陷阱、永不响应的路由、8 MiB 流式路由,以及 404/500 响应,因此可以通过真实套接字测试 SSRF 和限制控制。
pnpm fixtures
# [fixtures] listening on http://127.0.0.1:<port>
两条开发命令都能正常运行,但有一个注意事项。
pnpm dev:backend会在:8080启动 Fastify 后端;pnpm dev:worker会启动 Worker。要将 Worker 指向后端并调用/v1/evidence,还需要完成 x402 结算,或者在使用非主网时设置DEV_BYPASS_PAYMENT=true。请参阅实现状态。
10. 部署
Cloudflare Worker (public edge) → protected origin → Docker container → Fastify backend → SQLite
-
VPS 上的后端。 由
docker/构建的 Node.js + Fastify 服务,通过docker compose运行,并设置restart: unless-stopped,将持久化卷挂载到/app/data,用于存储 SQLite 缓存。 -
Cloudflare Worker。
bash scripts/deploy-live.sh会部署生产环境,并且只有在构建成功退出、版本 ID 确实发生变化且外部验证确认线上服务正常时,才会报告成功。(wrangler deploy的管道处理不可靠:即使构建失败,wrangler deploy | tail也会以 0 退出,这曾两次掩盖部署故障。) (Base 主网)。 -
共享密钥。 为确保它绝不会被提交,
wrangler.jsonc中故意不包含BACKEND_AUTH_SECRET:wrangler secret put BACKEND_AUTH_SECRET它必须与后端自己的
BACKEND_AUTH_SECRET一致。使用openssl rand -hex 32生成。 -
源站保护——首选方案是使用 Cloudflare Tunnel,这样后端就没有公共监听器,也不会有公共 DNS 记录。另一种方案是使用经过身份验证的源站,并通过防火墙限制为仅允许 Cloudflare 的出口 IP 段访问。无论采用哪种方案,每个内部请求都必须验证共享密钥,因为网络限制和请求身份验证是相互独立的防护层。
使用占位符——PUBLIC_API_DOMAIN、BACKEND_ORIGIN_URL、MCP_PUBLIC_URL——切勿编造真实域名。
完整说明、环境变量表、运行状况检查和手动凭据清单:docs/deployment.md。
原则上可部署,但尚未部署或端到端验证。 Docker 构建文件、后端和 Worker 均已就绪。尚未从此代码库进行任何部署,而且必须先修复两处配置缺陷(参见实施状态)。另请参阅
docs/deployment.md。
11. 安全性
抓取器将每个 URL 都视为不可信输入。必需的防护措施(SPEC §18)均由 @aee/fetcher 包强制实施:
- 协议白名单——仅允许
http和https;拒绝file://和其他所有协议。 - 拒绝特定地址——拒绝 localhost 及其别名、环回地址、RFC1918/私有 IPv4 地址、链路本地地址、多播地址、未指定地址、IPv6 环回地址、IPv6 链路本地地址、IPv6 私有地址段,以及云元数据端点(
169.254.169.254等)。 - 编码规避——十进制、八进制、十六进制、简写形式和 IPv4 映射的 IPv6 表示形式,均在解析后进行范围检查,而非通过字符串匹配。
- DNS——显式解析,对所有解析出的地址进行验证,并在连接时重新验证,以封堵 DNS 重绑定漏洞窗口。
- 重定向——验证每一跳,而不只是第一个 URL,并强制执行
MAX_REDIRECTS。 - 端口——仅允许白名单中的端口。
- 限制——强制执行连接超时、请求总超时、流式传输过程中的最大响应字节数、防范解压炸弹,以及并发限制。
- 绝不通过 shell 执行 URL。抓取路径中不使用
child_process。 - 日志——使用结构化 JSON,并对密钥进行脱敏。绝不记录支付密钥或来源密钥、私钥或钱包密钥。
此外,来源保护可确保调用方无法绕过 Worker 直接调用后端以逃避付费:使用 Cloudflare Tunnel(首选)或配置防火墙的来源服务器,并对每个内部请求进行服务器间身份验证。BACKEND_AUTH_SECRET 没有默认值,正是为了让配置错误的后端默认拒绝未认证请求,而非在未认证的情况下运行。
此外,还须遵守 SPEC §19 中的访问规则:不得绕过访问控制、规避机器人防护、自动登录、绕过付费墙或破解 CAPTCHA。系统会使用清晰可识别的 User-Agent,robots.txt 的处理方式可通过 ROBOTS_POLICY 配置,且仅限访问公开资源。请仅提交你获准访问的 URL。
这些控制措施已在
packages/fetcher中实现,并在tests/security/中通过单元测试,本地测试通过(92 个安全用例)。尚未进行独立审计。ROBOTS_POLICY已强制执行。请参阅docs/security.md,了解各项控制的状态表、各项措施的实施位置,以及如实列出的差距。
12. 局限性
坦率地说,你应该在依赖输出之前了解以下内容。
| 局限性 | 详情 |
|---|---|
| 仅进行确定性的词汇匹配 | 评估基于术语匹配和固定的否定提示词列表,不具备语义理解能力。改述后的矛盾如果没有共享词汇,就不会被检测到;包含大量相同术语的否定段落则会被检测到。 |
| 除非配置提供方,否则不进行语义推理 | 设计中包含 ReasoningProvider 扩展点(见 SPEC §37),但目前尚未实现。即使实现了,它也可以拆分、排序、比较和综合内容,但绝不能用缺乏依据的文字替代源证据。 |
| v0.1.0 仅支持由 Agent 提供的 URL | 你必须提供 URL。目前没有搜索提供方,因此该服务无法为你发现来源。实际上,urls 是必填项。 |
| 摘录有意保持简短 | 默认 MAX_EXCERPT_CHARS 为 600(架构上限为 4000)。这是提供引用证据的服务,不是内容倾倒服务,不会复现整份文档。 |
inconclusive 很常见,也符合预期 | 如果问题与检索到的文本没有显著的共同术语,诚实的答案就是 inconclusive。这表示服务正常工作,而非失败。 |
| 忽略长度少于 3 个字符的词元 | 这些词元会从问题术语中剔除,因此非常简短的问题或仅包含缩略词的问题可能匹配效果不佳。 |
| 词干提取较粗糙 | 只会去掉一个词尾 ing/ed/es/s。没有词干提取库,也不处理不规则形式。 |
| 停用词使用固定的英文列表 | 非英语问题受影响较小(该列表针对英语,在其他语言中大多不起作用),但非英语问题的排序质量并未经过调优。 |
| 不支持 PDF、图像或 JavaScript 渲染的证据 | DocumentProvider 和 BrowserProvider 是未来的扩展点,尚未实现。仅支持静态 HTML。 |
| 不检测来源变更,也不评估可信度 | SourceTrustProvider 尚未实现;该服务会报告页面所述内容,但不会评估发布方的可信度。 |
| 缓存命中会明确标记,不会隐藏 | 会返回 from_cache: true 和 SERVED_FROM_CACHE 警告,且 retrieved_at 始终为实际检索时间。可能会提供不超过 CACHE_TTL_SECONDS(默认 24 h)的旧证据。 |
| 单个来源出错不会导致请求失败 | 各来源的错误会分别报告在 warnings 中,错误计数则会添加到 limitations 中。请查看这些数组。 |
| 速率限制按后端进程分别计算 | 基于 CF-Connecting-IP 键控的令牌桶会执行 RATE_LIMIT(429)限制,并使用有界的令牌桶映射。限制在进程内生效,因此多个后端副本各自拥有独立的配额;要在边缘层限流则需要 Durable Objects。 |
| 不处理非 HTML 内容 | 对于不支持的内容类型,服务会返回正文为 null 的来源,并附带 UNSUPPORTED_CONTENT_TYPE 警告,而不是报错。支持处理的类型为 HTML、纯文本、XML 和 JSON。 |
| Robots 规则匹配使用前缀/通配符,并非完整实现 RFC 9309 | 会执行 ROBOTS_POLICY=ignore|warn|enforce,并使用有界的每来源缓存。有歧义的规则会按允许处理,并发出警告,而不是默默拒绝请求。每个请求都会发送一个清晰可识别的 User-Agent。 |
| 尚未演示链上支付 | x402 门控已实现;但尚未针对任何部署执行使用已注资的 Base Sepolia 或主网进行结算。 |
| 未经独立安全审查 | SSRF 控制已在源代码中实现并通过单元测试,但尚未经过对抗性审计。 |
而现在
**已实现并通过类型检查:**全部六个包(schemas、core、fetcher、extraction、cache、mcp)、两个应用(backend、worker)、Docker 构件和 server.json。pnpm typecheck 已在整个工作区通过,六个测试套件覆盖约 147 个用例,其中包括一个端到端流程测试:该测试通过 HTTP 调用真实后端,并连接到夹具服务。
仍待解决:
| 缺口 | 详情 |
|---|---|
| 测试钱包地址为字面值 | apps/worker/wrangler.jsonc 中的 env.dev 和 env.test 使用了相同的字面接收地址。部署前请替换为占位符。 |
| Robots 匹配规则经过简化 | 已实施 ROBOTS_POLICY;匹配规则采用前缀/通配符方式,而非完整的 RFC 9309 规则,遇到歧义时默认允许。 |
| 未验证链上支付 | x402 门控已实现并经过审查;尚未执行使用已充值的 Base Sepolia 或主网进行的结算。 |
| 没有自动化 x402 支付测试 | SPEC §26 要求进行 402 测试和有效测试网支付测试。目前两者都不存在。 |
| 限流在进程内执行 | 按后端副本执行,而非在边缘进行全局限流。 |
server.json 中的远程 URL 是占位符 | 命名空间已确认(io.github.Thx93/),但必须替换 remotes[].url,且 repository.url 指向的仓库目前尚不存在。 |
| 没有独立的安全审查 | SSRF 控制已在源码中实现并通过单元测试;尚无人以对抗性方式对其进行审计。 |
本地验证结果:pnpm typecheck 退出码为 0,pnpm test 报告 199 项测试通过,并且 scripts/smoke.sh 和 scripts/worker-smoke.sh 均通过了针对运行中套接字的测试。请重新运行这些脚本并报告实际输出,不要假定它们会通过——这些结果来自单台机器。
13. 发布到注册表
SPEC §28 要求项目做好注册表发布准备,但不自动发布。这意味着:
- 使用当前官方架构的
server.json元数据文件; - 验证该文件;
- 记录准确的发布步骤;
- 提供命名空间所有权和身份验证检查清单;
- 仅在凭据和授权明确可用时,使用官方
mcp-publisher工作流手动发布。
server.json 现已创建,并声明这是一个远程流式 HTTP 服务(没有 packages 条目,因为没有可安装的 npm 包)。发布前还有两件事需要完成:
remotes[].url仍是https://mcp.example.invalid/mcp;请将其替换为真实的MCP_PUBLIC_URL。name和repository.url声明了一个 GitHub 命名空间——请确认它们确实属于你,因为系统会验证命名空间所有权,虚构的账号名会验证失败。
目前尚未发布。准确的发布流程、验证步骤和命名空间检查清单见
docs/registry-publication.md。
发现策略——包括 MCP Registry、GitHub 仓库、适用情况下的 npm 元数据、机器可读元数据、文档和面向 Agent 的工具描述——见 docs/discovery.md。其中还列出了值得使用的真实描述性短语(网络证据、来源验证、主张验证、证据提取、以来源为依据的研究、比较来源、带引文的证据、最新网络证据),并明确指出描述必须真实,不得堆砌关键词。
在服务实际可用前,请勿发布。 注册表条目列出了无法调用的工具,情况会比没有条目更糟。目前仍有两个明确的阻碍:必须将占位符 remotes[].url 替换为可用的端点,并确认 name/repository.url 中的命名空间确实属于你。
项目结构
agent-evidence-api/
├── AGENTS.md # sole project rules file
├── SPEC.md # product specification (authority on requirements)
├── README.md
├── server.json # MCP Registry metadata (remote streamable-HTTP server)
├── .env.example # environment template, placeholders only
├── pnpm-workspace.yaml
├── package.json
├── docs/
│ ├── architecture.md # architecture, pipeline, layering rule
│ ├── api.md # HTTP endpoints, exact schemas, error codes, limits
│ ├── mcp.md # MCP transport, tools, free vs paid, client config
│ ├── x402.md # payment flow and configuration
│ ├── security.md # SSRF controls, origin protection, secrets
│ ├── deployment.md # local, Docker, Worker, origin protection
│ ├── discovery.md # agent discoverability strategy
│ └── registry-publication.md # exact MCP Registry publish steps
├── apps/
│ ├── backend/ # Fastify service — the VPS workload
│ │ └── src/ # app.ts, auth.ts, server.ts
│ └── worker/ # Cloudflare Worker — the public edge
│ ├── src/index.ts
│ ├── wrangler.jsonc
│ └── .dev.vars.example
├── packages/
│ ├── schemas/ # zod schemas + types (the shared wire contract)
│ ├── core/ # EvidenceService, config, logger, assessment
│ ├── fetcher/ # SSRF-hardened HTTP fetching (ip.ts, fetch.ts)
│ ├── extraction/ # HTML parsing, metadata, main content, lexical ranking
│ ├── cache/ # SQLite-backed bounded cache (node:sqlite)
│ └── mcp/ # MCP server + tool definitions (streamable HTTP)
├── tests/
│ ├── fixtures/ # deterministic local fixture server
│ ├── security/ # ssrf.test.ts, limits.test.ts
│ └── e2e/ # evidence-flow.test.ts (cross-package)
├── scripts/
│ ├── run-tests.mjs # test runner (node --test + tsx)
│ └── smoke.sh # live socket smoke test against the built backend
├── .dockerignore
└── docker/
├── Dockerfile
├── docker-compose.yml
├── env.production.example # Base mainnet
└── env.development.example # Base Sepolia
HTTP 适配器和 MCP 适配器都会调用同一个 EvidenceService——二者之间没有重复的业务逻辑(SPEC §39):
HTTP adapter ─────┐
├──> EvidenceService ──> Fetch / Extract / Cache
MCP adapter ──────┘
x402 位于 Worker 的支付边界,不会进入核心引擎。
实现状态
编写文档时的状态快照。
已实现
packages/schemas— 完整的线协议契约(请求、响应、来源、证据条目、警告、错误、限制),并已构建输出。packages/fetcher— 经 SSRF 加固的检索:协议白名单、IPv4/IPv6 地址范围分类(包括十进制/八进制/十六进制/127.1格式以及 IPv4 映射的 IPv6 地址)、主机名规则、端口白名单、对所有 DNS 记录进行解析后 IP 验证、逐跳重定向验证、连接时针对 DNS 重绑定的重新验证、连接和总超时、流式字节数上限,以及手动解压。packages/extraction— HTML 解析、元数据、主要内容提取、规范化、内容哈希、确定性词法排序、否定提示。packages/cache— 键规范化、CacheProvider、有界 SQLite 适配器。packages/core— 配置、带密钥脱敏功能的结构化日志、跨来源评估、EvidenceService、类型化的ServiceError。packages/mcp— 远程 MCP 适配器:无状态模式下的可流式 HTTP(sessionIdGenerator: undefined、enableJsonResponse: true),每个 HTTP 请求都会创建一对新的Server和传输对象、tools/list,以及将请求委托给 HTTP 层所用同一EvidenceService的tools/call。工具输入架构由 zod 通过z.toJSONSchema生成。apps/backend— Fastify 服务:缺少密钥时启动失败关闭,除/health外的所有端点均进行恒定时间共享密钥验证,提供GET /health、POST /internal/v1/evidence,以及/mcp上的 POST/GET/DELETE。apps/worker— 完整边缘层:x402 门控、免费的/health和/、转发POST /v1/evidence、MCP 请求体检查与转发、受保护的开发绕过机制、规范错误封装。docker/— 多阶段Dockerfile、docker-compose.yml、分别用于主网/测试网的环境模板,以及根目录.dockerignore。server.json、apps/worker/.dev.vars.example、scripts/smoke.sh。
已在此环境中验证
pnpm typecheck— 整个工作区均通过(tsc --noEmit,退出码 0)。- 共包含 6 个测试套件,约 147 个用例:
tests/security/ssrf.test.ts(30 个)、tests/security/limits.test.ts(16 个)、tests/e2e/evidence-flow.test.ts(18 个)、packages/mcp/src/mcp.test.ts(15 个)、packages/extraction/src/extraction.test.ts(46 个)、packages/cache/src/cache.test.ts(22 个)。
已在本地验证,尚未由第三方独立复现
pnpm typecheck→ 退出码 0;pnpm test→ 199 项通过;scripts/smoke.sh和scripts/worker-smoke.sh→ 所有检查均通过。尚无第三方复现这些结果。- 尚未演示链上 x402 付款(已验证 402 门控;结算路径需要有资金的测试网钱包)。
待解决缺陷
| 缺陷 | 详情 |
|---|---|
| 测试钱包地址为字面值 | apps/worker/wrangler.jsonc 在 env.dev 和 env.test 中都包含相同的字面值收款地址。SPEC §33 和 AGENTS.md §6 禁止提交钱包配置。 |
| Robots 匹配逻辑经过简化 | EvidenceService 会执行 ROBOTS_POLICY;匹配方式为前缀/通配符,而非完整的 RFC 9309 实现。 |
| —(已修复) | 现在会按来源发出 UNSUPPORTED_CONTENT(415)。 |
| 未进行链上结算测试 | 402 门控以及免费/付费 MCP 的区分均由 scripts/worker-smoke.sh 覆盖;速率限制已通过单元测试和集成测试。实际 USDC 结算需要有资金的 Base Sepolia 钱包,而这属于外部凭证。 |
server.json 尚不可发布 | 命名空间已确认,但 remotes[].url 仍是占位符,且引用的仓库不存在。 |
| 端口白名单包含 8080/8443 | 这对工具很方便,但这些端口也常用于内部接口。若不需要,应缩小白名单范围。 |
文档
| 文档 | 内容 |
|---|---|
docs/architecture.md | 组件图、请求处理流程、边缘端与后端的划分、身份验证边界、分层规则、软件包归属和扩展点。 |
docs/api.md | GET /health、GET /、POST /v1/evidence;准确的请求和响应架构;评估状态;完整示例;所有错误代码;资源限制及其环境变量。 |
docs/mcp.md | 可流式传输的 HTTP 传输、/mcp、两个工具、准确的输入架构、免费与付费发现、客户端配置、调用示例、需要付款时的响应。 |
docs/x402.md | 402 → 付款 → 重试 → 验证 → 执行流程、配置变量、CAIP-2 网络 ID、USDC 结算、测试与生产环境隔离、开发绕过机制和私钥规则。 |
docs/security.md | SPEC §18 要求的 SSRF 控制集、来源保护、共享密钥方案、密钥处理、robots/访问行为,以及各项措施的执行位置。 |
docs/deployment.md | 本地开发、VPS 上的 Docker、Cloudflare Worker、wrangler secret put BACKEND_AUTH_SECRET、健康检查、重启策略、SQLite 卷和来源保护选项。 |
docs/discovery.md | 注册表、代码仓库、npm、机器可读元数据、文档,以及面向 Agent 的工具描述。 |
docs/registry-publication.md | MCP Registry 的准确发布步骤、验证和命名空间所有权检查清单。 |
贡献规则
AGENTS.md 是唯一的项目规则手册。它规定了硬性约束、安全规则、编码标准、测试要求和完成标准。不要创建 CLAUDE.md、.cursorrules、GEMINI.md 或任何与之冲突的指令文件。
产品需求见 SPEC.md。如果本 README 与规范不一致,以规范为准;如果源代码与规范存在矛盾,应报告,而不是默默自行解决。
许可证
MIT。参见 package.json。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。