AutoGPT 平台 Exa Research 块:在可视化 Agent 工作流中编排自主联网研究任务
导读
Exa Research 块组是 AutoGPT Platform(autogpt_platform)可视化 Agent 编排体系中用于“深度联网研究”的一组能力块:它们封装了 Exa Research API 的异步研究任务创建、状态查询、结果轮询与任务分页列表四个操作,让不写代码的 Agent 构建者也能在画布上搭建"提出问题 → 自主检索网络 → 综合多来源证据 → 输出带引用报告(甚至结构化 JSON)"的自动化研究链路。读完本文,你将掌握四个块的输入/输出契约、默认值与约束、任务状态机与费用上报机制,并能在自己的 Agent 中组合出"先异步发起、再等待完成、最后取结果"的实战方案。
本文主体依据仓库文档 research.md 整理,全部实现细节以源码 research.py 及其配套测试为佐证。
一、块组概览:一次覆盖"发起—查询—等待—盘点"的完整闭环
Exa Research 块组共包含四个块,源码位于 autogpt_platform/backend/backend/blocks/exa/research.py,全部归入 BlockCategory.SEARCH,其中创建块同时属于 BlockCategory.AI。四个块的定位如下:
| 块 | 作用 | 文档章节 |
|---|---|---|
| Exa Create Research | 创建研究任务,可选择性等待完成(默认开启) | 原文档 "Exa Create Research" |
| Exa Get Research | 按 research_id 查询单个任务的实时状态、结果与费用明细 |
原文档 "Exa Get Research" |
| Exa List Research | 按创建时间倒序列出全部任务,支持游标分页 | 原文档 "Exa List Research" |
| Exa Wait For Research | 独立轮询等待一个任务到达终态,返回 timed_out 供流程做超时分支 |
原文档 "Exa Wait For Research" |
从命名与分工可以看出设计者的组合意图:Create 负责"下发",Get 负责"查询",Wait 负责"阻塞直到终态",List 负责"全局视图与恢复现场"。它们共享同一套底层 HTTP 接口(https://api.exa.ai/research/v1)与数据模型,因此四个块之间产出的 research_id 可以互相衔接、自由串接。
说明:该块族属于 AutoGPT 平台 Exa 集成(同目录下还有 Search、Answers、Contents、Similar、Websets 等共 14 份块文档,见 docs/integrations/block-integrations/exa),彼此独立、可按需搭配。
二、使用前的准备:Exa 凭据与费用计量约定
所有四个研究块的第一输入项都是 credentials(类型 CredentialsMetaInput,必填),描述为 "The Exa integration requires an API Key."。凭据底层由共享 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)。在运行时,请求头会以x-api-key携带密钥(见 research.py 中create与get的headers组装)。实际使用前请确保在 AutoGPT 平台的集成凭据管理中完成 Exa API Key 的绑定。 - 基础计费约定:Provider 采用"每 1 USD 折算 100 信用点"的基准成本模型(
with_base_cost(100, BlockCostType.COST_USD)),代码注释给出示例:一次约 0.20 美元的深度研究(Deep Research)约合 20 个信用点,从而与 Exa 账单支出基本对齐。这是平台的平台信用预估值,与块输出的"实际美元费用(cost_dollars.total)"是两套并行的费用口径。 - webhook 扩展:Provider 注册了
ExaWebhookManager,说明该集成族在更深层支持 webhook 订阅能力(创建/查询研究之外的 Webhook 块详见 webhook_blocks.md),但四个 Research 块本身的终态检测走的是轮询而非回调。
三、Exa Create Research:一条指令,异步全网研究
3.1 设计意图
创建异步研究任务并可选等待:Exa 平台会自主探索网页、搜索相关信息,将多来源发现综合成一份带引用的报告。相比普通搜索块,它输出的是"研究结论"而非"候选链接列表"。
3.2 输入参数
| 输入 | 说明 | 类型 | 必填 | 源码默认值/约束 |
|---|---|---|---|---|
instructions |
研究指令——明确写清要找什么信息、如何开展研究、期望的输出格式 | str |
是 | 无默认;源码 placeholder 示例:"Research the top 5 AI coding assistants, their features, pricing, and user reviews" |
model |
研究模型档位:fast 快速出结果,standard 质量均衡,pro 深度分析 |
"exa-research-fast" | "exa-research" | "exa-research-pro" |
否 | 默认 "exa-research"(standard) |
output_schema |
JSON Schema,用于强制结构化输出。提供后结果会被校验并以解析后的 JSON 返回 | Dict[str, Any] |
否 | 默认 None;标记为 advanced 参数 |
wait_for_completion |
是否在返回前等待研究完成,保证立刻拿到结果 | bool |
否 | 默认 True |
polling_timeout |
等待完成的最大秒数(仅当 wait_for_completion=True 时生效) |
int |
否 | 默认 600,取值范围 1–3600;advanced 参数 |
参数解读(对应源码 research.py ExaCreateResearchBlock.Input):
model由枚举ResearchModel定义,其成员值exa-research-fast/exa-research/exa-research-pro会原样透传给 Exa API 的model字段;不填则走默认的 balanced 档位。instructions是决定研究质量的核心。由于 Exa 侧"自主规划检索策略",指令应同时覆盖检索目标(哪些事实、指标、观点)、检索策略(如只看官方来源、时间范围)与产出格式(如分节列出结论+引用),配合下方output_schema可获得完全结构化的结果。- 选择
wait_for_completion=False时块会在任务创建后立即返回(此时仅有research_id/status/model/instructions/created_at),适合"先创建、后由工作流中的其它块异步接管";选择True(默认)则会阻塞到终态并返回报告全文与费用。
3.3 输出字段
| 输出 | 说明 | 类型 |
|---|---|---|
error |
操作失败时的错误信息 | str |
research_id |
用于追踪本次研究请求的唯一 ID | str |
status |
研究的最终状态 | str |
model |
实际使用的研究模型 | str |
instructions |
传入的研究指令 | str |
created_at |
研究创建时间(Unix 毫秒时间戳) | int |
output_content |
研究输出的纯文本(仅当 wait_for_completion=True 且已完成时返回) |
str |
output_parsed |
结构化 JSON 输出(仅当同时满足 wait_for_completion=True 且提供了 output_schema 时返回) |
Dict[str, Any] |
cost_total |
总费用(美元,仅当等待完成时返回) | float |
elapsed_time |
完成所耗秒数(仅当等待完成时返回) | float |
注意:源码输出定义中输出为
Optional的可选字段在任务未完成/未等待时不会产出(包括error,其默认不产出,仅在特定失败路径被显式 yield)。设计上将“等待成功”与“立即返回”明确区分。
3.4 底层调用链与行为细节
从 ExaCreateResearchBlock.run 的实现可以看到完整机制:
- 创建阶段:向
POST https://api.exa.ai/research/v1发送 JSON,主体包含model与instructions;若提供了output_schema则追加outputSchema字段。 - 立即返回分支(
wait_for_completion=False):只 yield 基础字段,status通常为pending。 - 等待分支(默认
True):以固定 10 秒间隔轮询GET https://api.exa.ai/research/v1/{research_id},直到状态进入终态集合{"completed", "failed", "canceled"};随后调用ResearchTaskModel.from_api(...)将 camelCase 的 API 响应规范化为稳定模型,输出全文、解析结果与elapsed_time。 - 超时行为:若轮询超过
polling_timeout秒仍未到达终态,块会抛出ValueError(f"Research did not complete within {polling_timeout} seconds"),即表现为块级运行失败,可在画布上连接错误分支处理。
3.5 典型应用场景
原文档给出三类代表性用法(见 research.md):
- 市场研究(Market Research):自动调研市场趋势、竞品与行业发展,产出全部附引用来源。
- 尽职调查(Due Diligence):对公司、人物或技术做全方位背景调研。
- 内容研究(Content Research):为文章、报告、演示文稿采集带引用的主题素材。
配合 output_schema,市场研究的结果可直接落成"竞品名称/价格/优劣势"之类的结构化表,省去下游再解析的环节。
四、Exa Get Research:随时查询任意任务的实时状态与完整结果
4.1 设计意图
对先前创建(或跨运行遗留下来)的研究任务,按 research_id 查询当前状态与结果。可用于判断任务仍在运行、已完成还是失败,也可把“过早结束的工作流”重新接回结果。
4.2 输入参数
| 输入 | 说明 | 类型 | 必填 | 源码默认值/约束 |
|---|---|---|---|---|
research_id |
要查询的研究任务 ID | str |
是 | placeholder:"01jszdfs0052sg4jc552sg4jc5" |
include_events |
是否返回研究的详细事件日志 | bool |
否 | 默认 False;advanced 参数 |
include_events=True 时,块会在 GET 请求上追加 events=true 查询参数(源码第 326–328 行)。
4.3 输出字段
| 输出 | 说明 | 类型 |
|---|---|---|
error |
操作失败时的错误信息 | str |
research_id |
研究任务标识符 | str |
status |
当前状态:pending / running / completed / canceled / failed |
str |
instructions |
原始研究指令 | str |
model |
使用的研究模型 | str |
created_at |
创建时间(Unix 毫秒时间戳) | int |
finished_at |
结束时间(当状态为 completed/canceled/failed 时) | int |
output_content |
研究输出文本(completed 时) | str |
output_parsed |
匹配 outputSchema 的结构化 JSON(若提供了 schema 且已完成) |
Dict[str, Any] |
cost_total |
总费用(美元,completed 时) | float |
cost_searches |
执行的搜索次数 | int |
cost_pages |
抓取的页面数 | int |
cost_reasoning_tokens |
用于推理的 AI token 数 | int |
error_message |
研究失败时的错误信息 | str |
events |
详细事件日志(include_events=True 时) |
List[Dict[str, Any]] |
费用明细的实现来源:cost_searches、cost_pages、cost_reasoning_tokens 分别对应 ResearchCostModel 的 num_searches、num_pages、reasoning_tokens。在 ResearchCostModel.from_api 中,Exa 返回的小数计数会被四舍五入取整(int(round(...))),因此你可以用这三个字段做粒度化的成本归因。
4.4 典型应用场景
- 状态监控(Status Monitoring):跟进以异步方式启动的长时间研究任务进度。
- 结果取回(Result Retrieval):取回工作流早期阶段已创建任务的最终报告。
- 成本追踪(Cost Tracking):查看已完成任务的搜索/抓页/token 开销构成,用于预算与优化。
五、Exa List Research:全量盘点与游标分页
5.1 设计意图
按创建时间**倒序(最新在前)**列出账号下的全部研究任务,支持分页以应对大量历史任务,适合做任务总览、历史恢复与审计。
5.2 输入参数
| 输入 | 说明 | 类型 | 必填 | 源码默认值/约束 |
|---|---|---|---|---|
cursor |
分页游标 | str |
否 | 默认 None;advanced 参数 |
limit |
单页返回的任务数量 | int |
否 | 默认 10,范围 1–50;advanced 参数 |
5.3 输出字段
| 输出 | 说明 | 类型 |
|---|---|---|
error |
操作失败时的错误信息 | str |
research_tasks |
按创建时间倒序排列的任务列表 | List[ResearchTaskModel] |
research_task |
单个研究任务(每个任务单独产出一次) | ResearchTaskModel |
has_more |
是否还有更多任务可分页 | bool |
next_cursor |
下一页的游标 | str |
该块输出设计为"一鱼两吃":既把整个列表作为 research_tasks 整体输出(便于一次性处理或交给聚合块),又对列表内每个任务以 research_task 逐条 yield(便于把列表扁平化到逐条循环,例如在后续块中逐项判断状态或取结果)。has_more/next_cursor 由 API 响应的 hasMore/nextCursor 映射而来,构成"翻页握手"。
5.4 典型应用场景
- 研究管理(Research Management):面向项目管理查看所有进行中与已完成的任务。
- 任务发现(Task Discovery):找回历史创建的任务,取回结果或复查状态。
- 行为审计(Activity Auditing):为合规或报告目的复盘研究活动历史。
分页"下一页"的推进方式:将上一页的 next_cursor 传入下一轮执行的 cursor,配合 has_more 判断是否终止。
六、Exa Wait For Research:把"异步"变"同步"的等待闸门
6.1 设计意图
以可配置超时轮询一个研究任务,直到完成或超时。它是 Create 内置等待能力的独立化/可复用化——特别适合"先 Create(不等待)→ 中间穿插其它并行任务 → 再 Wait 收口"的并发编排,或把异步研究转成同步流程以简化逻辑。
6.2 输入参数
| 输入 | 说明 | 类型 | 必填 | 源码默认值/约束 |
|---|---|---|---|---|
research_id |
要等待完成的研究任务 ID | str |
是 | placeholder:"01jszdfs0052sg4jc552sg4jc5" |
timeout |
最长等待秒数 | int |
否 | 默认 600,范围 1–3600 |
check_interval |
每次状态检查的间隔秒数 | int |
否 | 默认 10,范围 1–60;advanced 参数 |
6.3 输出字段
| 输出 | 说明 | 类型 |
|---|---|---|
error |
操作失败时的错误信息 | str |
research_id |
研究任务标识符 | str |
final_status |
轮询停止时的最终状态 | str |
output_content |
研究输出文本(completed 时) | str |
output_parsed |
结构化 JSON(若提供了 outputSchema 且完成) |
Dict[str, Any] |
cost_total |
总费用(美元) | float |
elapsed_time |
实际等待的秒数 | float |
timed_out |
是否在完成前超时 | bool |
6.4 与 Create 内置等待的差异与超时处理
从源码行为看,两者的轮询逻辑同构,但 Wait 块有三个独特之处:
- 自定义检查间隔:
check_interval可调(Create 内部固定 10 秒),短间隔适合对耗时敏感的任务,长间隔可减少 API 调用次数。 - 不抛错、给分支:Create 等待超时会抛
ValueError;Wait 块超时则正常返回并将timed_out=True,同时附带最后一次查询到的final_status与elapsed_time。这使得工作流可以优雅处理"研究未按时完成"——例如把尚未完成的任务交给后续的 Get/再等待节点,或触发人工介入。 - 何时被等待的任务可以由任意节点创建:只要持有有效的
research_id(来自 Create 立即返回、List 发现、或历史执行记录),即可接入等待。
6.5 典型应用场景
- 串行工作流(Sequential Workflows):确保研究完成后再执行依赖它的下游步骤。
- 同步化集成(Synchronous Integration):把异步研究包装成同步操作,简化业务流程编排。
- 超时处理(Timeout Handling):为时间敏感型应用实现带优雅超时的研究流程。
七、背后的数据模型与状态机(源码视角)
所有四个块共享同一套底层模型,定义于 research.py:
ResearchStatus状态机:pending→running→completed/canceled/failed。终态集合在 Create 与 Wait 的轮询中被复用,判定一致。ResearchTaskModel:统一的任务视图,字段包括research_id、created_at、model、instructions、status、output_schema、output(内含content与可选parsed)、cost_dollars、finished_at、error。它的from_api类方法负责把 Exa 的 camelCase 响应(如researchId、createdAt、finishedAt、costDollars、output)映射为 snake_case 稳定模型,屏蔽 API 字段命名差异,保证块输出契约长期稳定。ResearchCostModel:费用构成(total、num_searches、num_pages、reasoning_tokens),并自动对小数计数取整。
这也解释了"为什么四个块输出的 status、created_at、cost_* 语义完全一致":它们都经由同一 from_api 归一化,下游无论接哪个块都能得到相同结构的 JSON 供大模型或模板消费。
7.1 费用上报机制:实际美元成本如何进入平台统计
cost_total 只是"看得见"的部分;在后台,研究块还会把真实的美元花费写入执行统计。逻辑位于 helpers.py:
extract_exa_cost_usd(response)兼容多种响应形态(Pydantic 对象、camelCase 字典costDollars.total、snake_case 字典、乃至裸字符串数值),最终提取出以美元计的total;提取不到时返回None。merge_exa_cost(block, response)在拿到美元金额后调用block.merge_stats(NodeExecutionStats(provider_cost=cost_usd, provider_cost_type="cost_usd")),把每次研究实际花费并入节点执行统计(NodeExecutionStats.provider_cost),供成本看板归集。
测试 cost_tracking_test.py 用一组典型的完整响应(COMPLETED_RESEARCH_RESPONSE,含 total: 0.05、3 次搜索、10 页、500 推理 token)验证了该链路:当轮询返回 completed 时,Create/Get/Wait 块均会以 provider_cost=0.05 调用一次 merge_stats;当响应不含 costDollars 时则不会合并任何费用。这与 _config.py 中"Exa 每次响应都携带 cost_dollars.total"的注释相互印证。
八、端到端编排建议:三种常见模式
基于四个块的输入/输出契约,可总结出三种高价值组合模式(均在 AutoGPT 平台画布上以拖拽连线实现):
- 同步一站式(默认最简):
Exa Create Research(wait_for_completion=True,默认)→ 直接消费output_content/output_parsed/cost_total。适合单任务、结果即取即用的场景。 - 异步分步(高并发/长任务):
Exa Create Research(wait_for_completion=False,拿到research_id)→ 并行执行其它不相关子流程 → 任一时刻Exa Get Research拉取status判断是否完成 → 完成后取回output_content与费用明细。若中间逻辑较多,可用Exa Wait For Research一次性收敛到终态,再走结果分支;超时分支返回的timed_out=True可再接入重试或人工通知。 - 多任务聚合/恢复现场:
Exa List Research(配合next_cursor分页)→ 遍历research_task→ 对仍处running/pending的任务Exa Wait For Research收口,对已完成任务Exa Get Research取数。适合"定时巡检所有研究任务"与"重启后恢复上次未完成研究"。
无论哪种模式,均建议在 instructions 中固化产出规范(必要时用 output_schema 强制 JSON 结构),并在费用敏感场景依赖各块输出的 cost_total 与 cost_* 明细做预算核算——真实的 provider_cost 已由块自动并入平台执行统计。
延伸阅读
- 本块族文档:research.md(即本文所依据的官方文档)
- 同族集成文档:search.md、answers.md、contents.md、code_context.md、similar.md
- 块实现源码:autogpt_platform/backend/backend/blocks/exa/research.py
- 共享 Provider 与计费配置:autogpt_platform/backend/backend/blocks/exa/_config.py
- 费用合并工具函数:autogpt_platform/backend/backend/blocks/exa/helpers.py
- 成本追踪测试(含完整 API 响应样例):autogpt_platform/backend/backend/blocks/exa/cost_tracking_test.py
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00