首页
/ AutoGPT Platform 中的 Exa Similar 块:用 Exa findSimilar API 实现语义相似网页发现

AutoGPT Platform 中的 Exa Similar 块:用 Exa findSimilar API 实现语义相似网页发现

2026-09-07 14:11:09作者:胡唯隽

Exa Similar 是 AutoGPT Platform(autogpt_platform 前端画布 + backend 执行引擎)内 BlockCategory.SEARCH 分类下的一个搜索类块,核心能力是调用 Exa 的 findSimilar API,根据一个已知 URL 的网页内容与上下文,从全网检索出语义相近的其他网页。本文以 Exa Similar 的官方块说明文档 docs/integrations/block-integrations/exa/similar.md 为主线,结合其 源码实现 与配套测试,完整讲解它的输入输出、内容获取选项、成本追踪与典型 Agent 工作流,帮助你在搭建 Agent 时直接落地"内容发现 / 竞品分析 / 研究扩展"等场景。

Exa Find Similar 是什么、底层如何工作

在 AutoGPT Platform 中,Exa Find Similar 是一个标准块(Block),其能力定位与同目录下的 Exa Search 块(见 search.md)互补:Search 从关键词/语义出发搜索全网,而 Find Similar 以一个已知 URL 为锚点出发。从源码注释看,该块的核心声明为:

description="Finds similar links using Exa's findSimilar API"
categories={BlockCategory.SEARCH}

它的工作原理可概括为三步:

  1. 语义分析锚点页面:块把输入的 url 发送给 Exa 的 findSimilar API,Exa 会分析该页面的内容与上下文语义(而非仅做关键词匹配)。
  2. 全网语义匹配:基于语义向量寻找与之相关的网页并返回结果列表。
  3. 可选的结果精化与内容获取:可以通过域名白名单/黑名单、抓取时间(crawl date)与发布时间(published date)范围、正文包含/排除文本等过滤条件缩小结果集;也可以开启 contents 内容获取与 moderation 内容安全过滤。

在实现层面,AutoGPT Platform 的 backend 使用官方 Python SDK exa_py 的异步客户端,并根据是否请求正文内容自动选择不同的 API 端点。查看 similar.py 中的核心逻辑:

aexa = AsyncExa(api_key=credentials.api_key.get_secret_value())

if content_settings:
    # Use find_similar_and_contents when contents are requested
    sdk_kwargs["text"] = content_settings.get("text", False)
    if "highlights" in content_settings:
        sdk_kwargs["highlights"] = content_settings["highlights"]
    if "summary" in content_settings:
        sdk_kwargs["summary"] = content_settings["summary"]
    response = await aexa.find_similar_and_contents(**sdk_kwargs)
else:
    response = await aexa.find_similar(**sdk_kwargs)

也就是说:当 contents 配置了任何内容获取选项时,块调用 find_similar_and_contents 一步拿到正文/高亮/摘要;否则调用轻量的 find_similar 只取链接与元数据。该块在 backend 中对应的完整类名为 ExaFindSimilarBlock,注册 ID 为 5e7315d1-af61-4a0c-9350-7c868fa7438a,代码位于 similar.py

在画布中接入 Exa Find Similar 与凭据配置

Exa 系列块共享同一套 Provider 凭据配置,定义在 _config.py 中:

exa = (
    ProviderBuilder("exa")
    .with_description("Neural web search")
    .with_api_key("EXA_API_KEY", "Exa API Key")
    .with_webhook_manager(ExaWebhookManager)
    .with_base_cost(100, BlockCostType.COST_USD)
    .build()
)

因此接入该块的先决条件是:

  • 在 Exa 平台申请一个 API Key,把它配置为名为 EXA_API_KEY 的环境变量,或在 AutoGPT Platform 的凭据管理中创建 provider 为 exa 的 API Key 凭据;
  • 在画布中添加 Exa Find Similar 块后,为它的 credentials 字段选择该 Exa 凭据(块的输入 schema 中该字段描述为 "The Exa integration requires an API Key.")。

配套的测试基准则定义在 _test.py 中,用 provider="exa"、类型为 API Key 的测试凭据覆盖块的运行路径,可作为你在本地调用该块时的最小凭据样例参考。

输入参数详解

必填输入:锚点 URL

url(str,必填)是本次"相似发现"的唯一锚点,Exa 会围绕这个页面的语义内容展开全网匹配。该字段在块的 schema 中被标记为常规(非高级)字段,是画布上的第一配置项。

返回数量与域名过滤

number_of_results(int,可选)控制返回结果条数。需要特别留意的是,尽管文档表格未标注默认值,源码中为它显式设置了 default=10 并标记为高级字段(similar.py),同时该值在调用 SDK 时被映射为 num_results 关键字。如果你不填写,默认只返回 10 条。

域名过滤由 include_domainsexclude_domains(均为 List[str],可选)控制,语义在源码注释中写得很清楚:

  • include_domains:若指定,结果会来自这些域名,是一个白名单;
  • exclude_domains:从结果中剔除这些域名,是一个黑名单。

两个字段都带 default_factory=list 并被标为高级字段,即不填时默认空列表、不做限制。代码中只在列表非空时才把对应 key 传给 SDK(similar.py),避免向 Exa API 发送无意义的空过滤参数。

日期范围过滤:抓取时间与发布时间

块提供两对日期过滤参数,类型均为 str (date-time)

输入 语义
start_crawl_date / end_crawl_date 针对 Exa 抓取(crawl)内容的时间范围
start_published_date / end_published_date 针对网页原始发布时间的时间范围

两者差异对应底层数据结构:crawl 时间反映的是内容被 Exa 收录/抓取的时点,published 时间反映的是作者发布内容的时点。在源码中这四个字段都是 Optional[datetime] 的高级字段,默认 None(不限制);只有当值非空时,才以 datetime.isoformat() 的格式序列化后传入 SDK(similar.py)。例如在画布中给 end_published_date 设成最近 30 天的日期,就可以实现"只找与锚点相似且近期发布的内容"。

文本模式过滤

include_textexclude_textList[str],可选)用于按正文出现的文本模式做二次过滤。需要注意 Exa 对这两个参数有约束:最多 1 个字符串,且长度不超过 5 个单词。这不同于搜索引擎的自由关键字习惯,在设计 Agent 输入时应把短语压缩到 5 词以内,例如把 "latest artificial intelligence news" 这类查询收敛为 "AI news" 之类的短模式。

内容获取设置与安全过滤

contentsContentSettings,可选)与 moderation(bool,可选)是该块两个"进阶能力开关",默认值在源码中分别为 ContentSettings()(空内容设置)与 Falsecontents 的完整子配置见下一节;moderation 置为 True 时,块会把 moderation 参数传给 Exa,由其过滤搜索结果中的不安全内容(源码中仅在为真时才写入 sdk_kwargs,见 similar.py)。

下面把 12 个输入参数汇总成可速查表格(含源码级默认值标注):

输入 说明 类型 必填 默认值(来自源码)
url 需要查找相似链接的锚点 URL str
number_of_results 返回结果条数(映射为 SDK 的 num_results int 10(高级)
include_domains 域名白名单,指定后结果仅来自这些域名 List[str] [](高级)
exclude_domains 域名黑名单 List[str] [](高级)
start_crawl_date 抓取内容起始时间 str (date-time) None(高级)
end_crawl_date 抓取内容结束时间 str (date-time) None(高级)
start_published_date 发布内容起始时间 str (date-time) None(高级)
end_published_date 发布内容结束时间 str (date-time) None(高级)
include_text 需要匹配的正文文本模式(最多 1 个、≤5 词) List[str] [](高级)
exclude_text 需要排除的正文文本模式(最多 1 个、≤5 词) List[str] [](高级)
contents 内容获取设置(正文/高亮/摘要等) ContentSettings ContentSettings()(高级)
moderation 是否启用内容安全过滤 bool False(高级)

输出与数据结构

该块声明了 6 个输出(见 similar.py 中的 Output schema):

输出 说明 类型
error 请求失败时的错误信息 str
results 相似文档列表(含元数据与可选内容) List[ExaSearchResults]
result 单条相似文档结果(逐条发射) ExaSearchResults
context 已格式化、可直接交给 LLM 的结果字符串 str
request_id 请求唯一标识 str
cost_dollars 本次请求的成本明细 CostDollars

其中 errorrequest_id 是 schema 中为失败语义与请求追踪预留的输出字段。在成功路径下,similar.py 的实际发射行为是:先一次性输出整个 results 列表,随后逐条输出 result(方便下游循环处理);当响应携带 Exa 生成的 context 时输出它;当响应携带 cost_dollars 时也一并输出。

results / result 使用共享模型 ExaSearchResults(定义在 helpers.py),该模型把 SDK 返回结果统一转换成平台侧字段,结构如下:

字段 说明
id Exa 文档 ID
url 网页地址
title 页面标题
author 作者
publishedDate 发布时间
text 提取的网页正文(请求 contents 时才有)
highlights / highlightScores 相关性最高片段及其分数
summary LLM 生成的摘要
subpages 子页面列表(配置 subpages 抓取时才有)
image / favicon 图片/站点图标资源
extras 附加链接与图片链接(linksimageLinks

深入 contents:内容获取设置

contents 是决定"拿元数据还是拿正文"的关键高级输入,它背后是定义在 helpers.pyContentSettings 模型,包含以下子配置:

  • text:正文获取。支持布尔值与对象两种形态:
    • 布尔值:true/false 简单开关;
    • 高级对象(TextAdvanced):max_characters 限制返回字符数(占位提示 1000)、include_html_tags 决定是否保留 HTML 标签(源码注释说明保留标签有助于 LLM 理解文本结构);
    • 历史版本还兼容 "enabled/disabled" 枚举写法,处理逻辑见 process_text_field
  • highlights:从每个页面提取最相关片段,用于生成 RAG 检索增强的引用。子参数包括 num_sentences(每个高亮包含的句子数,默认 1、ge=1)、highlights_per_url(每个 URL 返回的高亮条数,默认 1)、query(自定义引导 LLM 挑选高亮的问题,占位如 Key advancements)。
  • summary:针对网页的 LLM 摘要。query 可自定义摘要关注点(占位如 Main developments);output_schema 可传 JSON Schema,让摘要以结构化 JSON 输出,便于下游 Agent 做字段级消费。
  • livecrawl:实时抓取策略枚举 never / fallback / always / preferred,并配套毫秒级 livecrawl_timeout(占位 10000)与 subpagessubpage_target(子页面抓取数量与定位关键词)。
  • extras:附加内容,links(每个结果页内返回的链接数)与 image_links(每个结果返回的图片数),默认 0 表示不请求。
  • context:是否把结果格式化为可直接喂给 LLM 的 context 字符串,高级模式可用 max_characters 限制长度(占位 10000)。

当这些配置被提交时,process_contents_settingshelpers.py)会把下划线风格的模型字段转换为 Exa API 的驼峰格式负载(例如 highlights_per_urlhighlightsPerUrlmax_charactersmaxCharactersinclude_html_tagsincludeHtmlTags)。有一个值得注意的实现细节:虽然 ContentSettings 模型本身支持 livecrawl、subpages、extras、context 等更广的配置项,但就 Exa Find Similar 这个块当前版本的 run() 而言,开启内容获取后只会把 texthighlightssummary 三个键转发给 find_similar_and_contents,其余高级子项主要由同目录下 Exa Contents / Exa Search 等兄弟块消费。因此,当你在画布中只想让相似结果附带正文与摘要用于喂给 LLM 时,配置 contents.text=true(或带 max_characters 的高级对象)并配合 highlights/summary 即可,无需依赖被该块忽略的配置项。

成本跟踪与配额换算

Exa 的每个响应都会携带 cost_dollars,其中 total 表示本次请求的美元成本,模型结构见 helpers.py(包含 total 总成本、breakDown 按操作类型的明细、以及 perRequestPrices / perPagePrices 两组标准价目参考)。块拿到响应后调用 merge_exa_costsimilar.py),把 cost_dollars.total 合并进 NodeExecutionStats.provider_cost,实现 Agent 执行粒度的成本统计。

在平台计费层面,_config.py 的注释解释了换算口径:with_base_cost(100, BlockCostType.COST_USD) 表示每 1 美元按 100 平台积分(约 $0.01/credit)计费,便宜的搜索通常消耗 1–2 积分,昂贵的深度检索(约 $0.20)则消耗约 20 积分,与真实 Provider 花费一致。需要注意的是这属于平台配置注释中给出的换算示意,实际计费以平台当前策略为准。

配套测试 cost_tracking_test.py 中专门覆盖了 TestExaSimilarCostTracking

  • 当 mock 的 find_similar 响应携带 cost_dollars = CostDollars(total=0.015) 时,merge_stats 会被调用且 provider_cost 精确等于 0.015
  • 当响应没有 cost_dollars 时,merge_stats 不会被调用(成本统计跳过,不产生副作用)。

这两条用例直接印证了 Exa Find Similar 块在成功请求下的成本合并行为,可作为你在集成或做成本可视化时对照的验收标准。

典型应用场景与工作流编排建议

文档明确给出三个典型场景,它们在 AutoGPT Platform 画布上都可以直接组合成可复用的 Agent:

  1. 内容发现(Content Discovery):给定一篇你喜欢的文章 URL,让该块找出语义相似的文章、博客与资源,形成持续的内容素材池。
  2. 竞品分析(Competitor Analysis):把已知竞品公司的官网/产品页 URL 作为锚点,借助 include_domains 限定行业媒体域名、配合 end_published_date 过滤最新动态,发现同类公司或可对比的产品信息。
  3. 研究扩展(Research Expansion):把关键参考文献 URL 传入,借助 include_text/exclude_text 收紧语义方向,扩展出更多可引用的原始资料。

在这类工作流里,Exa Find Similar 通常不是终点而是上游检索节点,推荐的下游编排思路是:

  • 让块输出 results/result 给数据清洗节点,用 urltitlepublishedDate 建结构化清单;
  • 需要给 LLM 阅读时,让块直接输出 context(Exa 已格式化的上下文串)作为后续 LLM 节点的输入;
  • 开启 contents 让每条结果自带正文 texthighlightssummary,即可配合 LLM 节点实现"发现 → 摘要 → 决策"的自动化研究管线;
  • cost_dollars 接到平台统计或日志节点,监控每次相似检索的成本。

实现上,该块与同目录 Exa 家族其他块(search.pycontents.pyanswers.py 等)共享 helpers 中的模型与成本合并逻辑,你可以直接在 backend/blocks/exa 目录下横向阅读这些兄弟块,理解"相似发现"与"关键词/语义搜索""正文获取"的协同边界,从而把 Exa 的能力作为一个完整的搜索工具族嵌入 Agent。

登录后查看全文
热门项目推荐
相关项目推荐