2026年8月28日 2 分钟阅读

Agent 总在过时网页上做判断?用 Keenable 把搜索、抓取与时间回溯接进工作流

tinyash 0 条评论

很多 Agent 的“联网能力”看起来已经够用:搜索几个关键词,打开结果页,再把内容交给模型总结。但一旦任务变成竞品研究、技术选型或事实核查,问题很快出现:搜索结果混杂,页面正文需要二次清洗,昨天看到的答案今天可能已经变化,模型也很难知道一次调用到底花了多少预算。

Keenable 是一个面向 AI Agent 的 Web Search Infrastructure。它把网页搜索和页面抓取封装成 API、CLI 以及远程 MCP Server,并提供一个值得注意的能力:Time Machine。通过 query_time,应用可以查询某个历史时刻的索引状态,而不是简单地给当前结果加一个日期过滤器。对需要可复现研究的 Agent 来说,这比“搜索结果大概差不多”更接近真正的证据链。

它解决的不是“有没有搜索框”

Keenable 的公开文档把入口分成三层:MCP 适合直接交给 Agent 使用,CLI 适合人在终端调试和脚本编排,REST API 则适合后端服务。搜索和抓取是两个核心操作:search_web_pages 返回标题、URL、描述和摘要;fetch 将页面内容以 Markdown 形式返回,必要时还能用 live=true 从源站实时抓取。

这使一个典型的研究流程可以拆成明确的步骤:先用搜索拿到候选,再只抓取排名靠前的页面,最后让模型基于 Markdown 正文回答。搜索与阅读分离后,缓存、重试和成本统计都有了落点,不必让每个 Agent 自己拼接浏览器操作。

更重要的是,Keenable 的文档没有把“历史搜索”描述成普通的时间筛选。query_time 会让索引回到指定时刻,之后获得的页面不会参与候选;相对时间过滤器也会以这个查询时刻为基准重新计算。换句话说,下面两种问题并不等价:

  • “现在搜索,并过滤最近 30 天发布的页面”;
  • “站在 2026 年 1 月 1 日,查询当时可获得的结果”。

前者仍然使用今天的索引,后者才适合复盘过去一次 Agent 运行时究竟能看到什么。

最快的安装与 MCP 接入

官方 CLI 是单二进制工具,文档给出了 Homebrew、安装脚本和 Cargo 三种方式。Linux 或 macOS 上可以先安装,再完成设备登录:

brew install keenableai/tap/keenable-cli
keenable login
keenable configure-mcp --all
keenable search "rust async patterns" -p

configure-mcp --all 会为检测到的客户端写入配置。官方 CLI 文档明确列出的支持对象包括 Claude Code、Cursor、Windsurf、Codex 和 OpenCode。这里有一个很实用的边界:它不是一个新的 Agent,也不是调度器,而是给现有 Agent 增加统一的搜索与页面读取工具。

如果只想手动配置远程 MCP,可以在支持 HTTP MCP 的客户端中使用下面的结构。示例刻意用环境变量,避免把密钥写进配置文件:

{
  "mcpServers": {
    "keenable": {
      "url": "https://api.keenable.ai/mcp",
      "headers": {
        "X-API-Key": "${KEENABLE_API_KEY}"
      }
    }
  }
}

Keenable 文档同时说明,省略密钥可以使用共享的 public tier,适合第一次试用;生产服务应使用自己的 API key。Claude Desktop 是一个特殊例外:它的配置文件只接受本地 command Server,远程 url 不会报明显错误,却不会出现工具。要给它应用自己的密钥,官方推荐使用本地桥接包:

{
  "mcpServers": {
    "keenable": {
      "command": "npx",
      "args": ["-y", "@keenable/mcp-server"],
      "env": {
        "KEENABLE_API_KEY": "${KEENABLE_API_KEY}"
      }
    }
  }
}

这类客户端差异值得写进部署检查表:URL 型 MCP、stdio 型 MCP 和产品内置 Connector 不是同一件事,不能只把一段配置复制到所有客户端。

REST API:把研究流程变成可测试代码

需要在后端控制重试、缓存或审计时,可以直接使用 REST API。认证请求把 API key 放在 X-API-Key Header 中;官方还提供不带 key 的 /public 端点,但要求用 X-Keenable-Title 标识应用。

一个最小的搜索调用如下:

import os
import requests

response = requests.post(
    "https://api.keenable.ai/v1/search",
    headers={"X-API-Key": os.environ["KEENABLE_API_KEY"]},
    json={
        "query": "TypeScript MCP server security",
        "max_results": 10,
        "snippet_max_length": 1200,
    },
    timeout=20,
)
response.raise_for_status()

for item in response.json()["results"]:
    print(item["title"], item["url"])

搜索结果中的 published_atacquired_at 都是 ISO 8601 时间。建议把原始 JSON 保存到研究记录中,而不是只保存模型最后生成的结论。这样后续能区分“源页面后来更新了”和“当时的检索本来就错了”。

抓取页面时,默认行为是读取 Keenable 已索引的副本;对于没有被索引的 URL,文档要求显式传入 live=true。这一区分很适合做稳定性策略:常规重复研究优先使用索引副本,遇到需要确认最新状态的页面再使用实时抓取。

Time Machine 适合哪些任务

假设你在构建一个每日技术情报 Agent。普通实现可能只记录查询词和最终答案,但网页会不断变化,几天后无法重现当时的输入。更稳妥的记录至少包括:查询词、query_time、搜索结果 JSON、实际抓取的 URL、模型提示词以及最终答案。

检索历史状态的命令可以这样写:

keenable search "AI coding agent release" \
  --query-time 2026-01-01T00:00:00Z \
  --published-after 30d \
  --max-results 20

官方 CLI 文档特别说明:设置 --query-time 后,30d 会相对于这个历史时刻计算,而不是相对于当前时间。这个细节可以避免评测集“时间穿越”:模型回答 1 月 1 日的问题时,不会意外看到 1 月 2 日才被索引的页面。

不过 Time Machine 不是网页存档的万能替代品。它重放的是 Keenable 的索引状态;如果你需要证明某个页面当日的完整原文,还要保存抓取结果,或者使用 fetch 的实时能力并记录响应。文章版本、索引时间和页面内容是三个不同维度,不能混成一个“历史搜索”开关。

免费额度与工程边界

官方 Credits 文档写明,每个组织每月有 100,000 次免费额度;搜索和抓取通常各消耗一次额度,但具体费用应以响应中的 SKU 和 amount 为准。MCP 的认证调用会在 _meta["keenable/usage"] 中返回使用信息,例如 search.realtime、消耗 credits 以及是否来自付费额度。

工程上可以据此做三层控制:

  1. 先搜索后抓取:不要为每个结果都调用完整页面抓取,只读取进入候选集的 URL。
  2. 把 usage 写入日志:按任务、Agent 或团队归因,而不是月底再猜费用。
  3. 为 public tier 设置降级:无密钥只作为体验和开发环境路径,正式任务使用组织级 key,避免共享 IP 池影响可用性。

Keenable 的公开首页还展示了 Search API 与 Time Machine 两类产品,并把搜索、抓取、MCP 和多个 Agent 框架集成放在同一套文档中。它的优势不是替某个模型“更聪明地搜索”,而是把搜索输入、页面内容、历史状态和使用量变成可以被程序控制的基础设施。

先做一层适配器,而不是把服务写死在 Prompt 里

在真实项目中,建议把 Keenable 封装成一个小型检索适配器。适配器只向上层暴露 search(query)fetch(url),同时负责注入超时、重试、来源白名单和原始响应落盘。这样未来切换到其他搜索提供商时,Agent 的提示词和评测数据不必跟着重写。

还要把“搜索到”与“验证过”分开标记。搜索结果的标题和描述只能用于发现线索;涉及版本、许可证、命令或安全结论时,应继续抓取官方文档、源码或发布说明。一个实用的记录结构可以包含 source_urlacquired_atquery_timeretrieved_atverification_status。其中 acquired_at 是服务索引页面的时间,retrieved_at 是你的程序拿到响应的时间,两者不要混用。

Keenable 的 public tier 也有明确边界:文档说明未认证请求共享每 IP 的请求池,并且没有认证调用的 usage 元数据。开发阶段可以用它验证 API 形状,压力测试和团队服务则应该尽早切换到认证路径。这种记录还方便做回归测试:固定一组查询和 query_time,检查结果结构、来源域名与关键页面是否仍满足预期,再单独评估模型答案。

最后还要留意一个现实取舍:MCP 会让工具直接出现在模型的决策空间中,但也意味着每次调用都应该有超时、额度和来源校验。建议先在 CLI 中验证查询与抓取,再接入 MCP;先记录原始结果,再开放自动总结。这样即使搜索服务、源站或模型发生变化,也能知道变化发生在哪一层。

相关链接

发表评论

你的邮箱地址不会被公开,带 * 的为必填项。