《从零实现 Agent 系统》连载 29|多 Agent 研究 Harness:Lead、Worker 与 Spawn

对照项目 Agentium 的背景:Agentium 论文与开源项目介绍。本文图表及核心设计均来自开源项目 Agentium,源码详见 GitHub

如果你正在做 Deep Research 产品化,这篇回答一个问题:Agentium 里这条研究链路怎样落成可运营的 job------请求怎么进来、分支怎么受预算约束、steer 怎样被消费、milestone 怎样验收。

Agentium 参考 DeerFlow、GPT Researcher、Anthropic 等 orchestrator--worker 体系的总体形态,工程上补齐 SpawnBudget 硬闸、全阶段 steer 审计、租户隔离 job store、milestone CI。先把 v1 / v2 / workflow / agentic 四条线分清,再进 v2 全链路。


先把链路跑活

接进业务时,先把主干请求跑通:打开 AGENTIUM_RESEARCH_V2_ENABLED=1,用 chat 分流(POST /v1/chat/messages + orchestration_mode=research)或控制面直调(POST /v1/research/v2/jobs)创建任务。拿到 job_id 后看 GET /v1/research/v2/jobs/{id}/events,在 GET /v1/research/v2/jobs/{id}payload.reportpayload.graph,复盘再拉 .../trajectory。链路跑顺,后面的 DyTopo、HITL、milestone 才有意义。

一个最小的 v2 创建 payload 通常长这样:

json 复制代码
{
  "query": "请检索并对比近几年 ACL 系列会议与 arXiv 的 multi-agent research 代表论文:列出方法、评测基准、代码可用性与局限,并总结可用于企业 Deep Research Harness 的设计要点。",
  "request_id": "req-001",
  "trace_id": "trace-001",
  "max_workers": 3,
  "max_depth": 3,
  "spawn_mode": "parallel"
}

payload 示意如上,用来建立可观测主干:任务是否创建、spawn 是否发生、合成是否完成、失败卡在哪个 phase。


先把几条线分清

Agentium 里「研究」不是单一实现,下面四个概念各管一层,别混成一种产品:

旋钮 管什么 research 相关时
orchestration_mode(会话级,连载 19 这条消息走对话、固定 workflow,还是研究 job research → 创建 v2 研究任务(v2 开关打开时),202,不进 Chat SSE
interaction_mode(轮次级,连载 28 本轮工具权限、风险档、是否开 tool loop 已走 research 分流时基本无意义
v1 DeepResearchPipeline 固定五段流水线 plan → search → synthesize → critique → report
v2 Research Harness Lead--Worker 树 + job + 图事件 ResearchLeadLoop + ResearchJobV2Service,本篇主体

入口:POST /v1/chat/messages + orchestration_mode=research 返回 202(dispatch: research_job);POST /v1/research/v2/jobs 控制面直调,返回 200;POST /v1/research/run 仍是 v1 DAG。三条入口职责不同,不存在旧版已经没了。

v2 总开关 AGENTIUM_RESEARCH_V2_ENABLED 默认关(0)。未开时 v2 路由不可用或无法 enqueue;回滚置 0,v1 仍在。勿写死全站只有 v2。

agentic + autonomous 是单会话里模型自主调工具;research harness 是后台 job、图 SSE、steer 队列。workflow 是连载 08 的固定 DAG。三者入口与可观测面不同,混用排障痛苦。

举个最容易混的例子:同样是这条"ACL + arXiv 对比"请求,走 chat research 会先拿到 job_id 再看事件流;走 research/run 会直接拿到 workflow 快照;走普通 agentic 则是会话内流式回复。入口不一样,后面的调试面板也完全不一样。


v1 管线与 v2 Harness:双轨、取舍

仓库里 v1 与 v2 双轨并存。v1 阶段固定、artifact 血缘清晰;v2 是 Lead 带 Worker 的多路检索树,壳层加预算、审计、milestone。

维度 v1 DeepResearchPipeline v2 ResearchLeadLoop + Harness
编排 固定 5 节点 DAG Lead spawn Worker,可 DyTopo、critique 补 spawn
入口 POST /v1/research/run、CLI chat research(202)或 POST /v1/research/v2/jobs
可观测 Artifact 合同、workflow 快照 GraphEventBus、trajectory、milestone
分解 plan handler research_think + 观测型 decompose gate
critique 有阶段;测试 stub 常 issues=[] 确定性单轮 critique + 有限 follow-up spawn
steer 无系统化全阶段 steer POST .../steer + 多阶段消费
并行 search 阶段 SpawnBudget + spawn_mode

v1 适合要与 workflow 统一 artifact、要 DAG 确定性、未开 v2 或刻意保持五段流水线。代价是图事件、运营 steer、跨 job recall、milestone 与 v2 不对齐;默认 stub 下 critique 几乎不拦错。

v2 适合多分支研究图、Deep Research 工作台、steer/HITL、milestone 回归、跨任务 recall。代价是开关与配置更多;DyTopo、critique 仍是轻量启发式加预算闸,live milestone 不能与 CI stub 等同。

v1 的 DAG 借鉴了 Anthropic《Building effective agents》里的 workflow-first 思路;v2 则借鉴了《Multi-agent research system》里的 orchestrator--worker 思路。

下面用同一 query 走两条路,对照阶段名与图上节点。示例里的 ID、时间戳是示意,真实值以 job 回包为准。

"

请检索并对比近几年 ACL 系列会议与 arXiv 的 multi-agent research 代表论文:列出方法、评测基准、代码可用性与局限,并总结可用于企业 Deep Research Harness 的设计要点。

示例 A:v1 五段 DAG

入口有两种:POST /v1/research/run 直调,或 chat 里 orchestration_mode=workflow(同一管线,返回 202 和 workflow_snapshot)。不必开 AGENTIUM_RESEARCH_V2_ENABLED

请求体示意:

json 复制代码
{
  "query": "请检索并对比近几年 ACL 系列会议与 arXiv 的 multi-agent research 代表论文:列出方法、评测基准、代码可用性与局限,并总结可用于企业 Deep Research Harness 的设计要点。",
  "request_id": "req-v1-001",
  "trace_id": "trace-v1-001"
}

编排是固定五段,没有 Lead 随时 spawn 的树;并行主要在 search 阶段(由注入的 research.search handler 决定 fan-out),其余按 DAG 顺序走。

v1 没有显式子 Agent:plan 产出子任务清单,search 并行执行。这条 query 可以拆成四步:

  • 先拉 ACL/EMNLP/NAACL 的代表论文,拿到方法、任务、年份这些基础字段;
  • 再补 arXiv 的新近工作,防止只看会议信号导致"时间滞后";
  • 单独整理评测基准和代码可用性,避免把"有结果"和"可复现"混在一起;
  • 最后在 synthesize + critique 合并,形成对比结论和企业可落地建议。

这条链路里没有 b1/b2 这种显式分支 ID。想验证"子任务是否跑到",通常看两处:plan 产物里有没有把任务拆出来,以及 search 阶段 artifact 是否覆盖这些拆分项。

单次 pipe.run() 内,逻辑顺序大致如下:

顺序 阶段 产物里常见内容
1 plan 子主题列表、检索意图(stub handler 时可能是固定模板)
2 search 各子主题检索片段;测试环境常为确定性 stub
3 synthesize 合并笔记 + 初步 citation
4 critique issues 数组;默认 stub 常为 [],很少拦停
5 report report_markdown / summary;artifact ID 可沿血缘追溯

和 v2 的差别主要在可观测面:v1 没有 job_id 和图 SSE,靠 workflow 快照与 ArtifactStore;运行中也没有 steer 插队,纠偏只能改 query 重跑或换 v2;分解在 plan 一次定稿,不会像 v2 那样 DyTopo、critique 再补 spawn。

workflow_runresearch/run 成功时,响应里先看:

json 复制代码
{
  "success": true,
  "dispatch": "workflow_run",
  "run_id": "workflow_run:session-abc:req-v1-001",
  "workflow_snapshot": {
    "nodes": [
      { "id": "plan", "status": "completed" },
      { "id": "search", "status": "completed" },
      { "id": "synthesize", "status": "completed" },
      { "id": "critique", "status": "completed" },
      { "id": "report", "status": "completed" }
    ]
  }
}

排障顺着五个节点状态和各阶段 artifact 看,不要去找 node_added

示例 B:v2 Lead--Worker Harness

入口:POST /v1/chat/messages + orchestration_mode=research(202,dispatch: research_job),或 POST /v1/research/v2/jobs(200)。须 AGENTIUM_RESEARCH_V2_ENABLED=1

创建 job 示意:

json 复制代码
{
  "query": "请检索并对比近几年 ACL 系列会议与 arXiv 的 multi-agent research 代表论文:列出方法、评测基准、代码可用性与局限,并总结可用于企业 Deep Research Harness 的设计要点。",
  "request_id": "req-v2-001",
  "trace_id": "trace-v2-001",
  "max_workers": 3,
  "max_depth": 3,
  "spawn_mode": "parallel"
}

Lead 分解 → spawn Worker → 可选 DyTopo 加深 → critique 补 spawn → 合成;事件写入 ResearchGraphEventBus,图上节点逐步长出。

Lead 按主题 spawn 分支,Worker 各自检索。分支分工如下:

  • b1:汇总 ACL/EMNLP/NAACL 代表论文,建立会议线索;
  • b2:补充 arXiv 增量工作,覆盖最新变化;
  • b3:整理 benchmark 与代码可用性,单独评估可复现性;
  • b4:DyTopo follow-up 分支,补齐分支检索后的证据缺口;
  • c1:critique follow-up 分支,在合成前按 issues 定向补证据。

对应检索意图是:b1 偏"会议脉络与代表方法",b2 偏"最新演化与新问题",b3 偏"指标与代码落地",b4/c1 偏"发现缺口后回补证据"。

如果你发现"该补的分支没补出来",通常先看三件事:SpawnBudget 是否已满(max_spawn_total / max_depth)、max_dynamic_followupscritique_max_followups 是否过低,以及事件流里是否出现 steer_consumedDyTopo.routecritique 这三类信号。

异步 job 可边拉事件边看,时间线示意:

时刻 phase / 事件 含义(示意)
T0 POST 返回 job_id=job-7f3a job 入队,phase=lead_loop
T1 node_added root Lead 挂上研究图根节点
T2 console_line Lead.decompose 分解出 b1/b2/b3(ACL 系列 / arXiv / 评测与代码)
T3 node_status b1→running parallel 模式下多 Worker 同时跑 arxiv/web
T4 Worker(b2).arxiv_q=... 控制台 hook:实际检索词,排障用
T5 node_status b1→completed WorkerResult 带 citations、gaps、confidence
T6 DyTopo.route 从 gaps 抽 need/offer,计划 follow-up b4
T7 critique + issues 确定性 critique 发现引用偏少 → 计划 c1
T8 spawn c1 仍受 SpawnBudget;已满则 break,不会无限补
T9 synthesize integrate_evidence → report_markdown
T10 job status=completed GET .../jobs/{id}payload.report + payload.graph

订阅 GET /v1/research/v2/jobs/{id}/events,事件流片段示意:

json 复制代码
{"type": "node_added", "node_id": "b2", "parent": "root", "label": "arXiv 候选"}
{"type": "console_line", "text": "Worker(b2).arxiv_q=multi-agent research arxiv latest"}
{"type": "node_status", "node_id": "b2", "status": "completed"}
{"type": "node_added", "node_id": "c1", "parent": "critique", "label": "citation follow-up"}
{"type": "metrics_snapshot", "spawn_used": 5, "spawn_budget_max": 8}

v2 独有的一步是 steer 插队。假设 T3 时发现 ACL 2024 关键论文漏检,调用 POST /v1/research/v2/jobs/{id}/steer

json 复制代码
{ "message": "补查 ACL 2024 多智能体研究及其开源代码可复现性" }

Lead 在 poll_steer 窗口消费后可能 spawn steer1 分支;审计里要有 steer_consumedspawn_node_id,不能只有 steer 入队记录。新证据先进整合再合成,不是改最终报告的 prompt。

并排总览

你想验证的事 v1 先看 v2 先看
任务有没有跑完 workflow_snapshot 五节点是否全 completed job status + 图里 synthesize 是否完成
检索是否发生 search 阶段 artifact / handler 日志 Worker console_line、citations、gaps
分解是否合理 plan 输出结构 quality_gates.decomposedecompose_gate 事件
运营纠偏是否生效 无标准 steer 路径(重跑或换 v2) steer_events + 新 spawn 节点
质量能否对外宣称 真网 handler + 人工读报告 另跑 live milestone,勿用 stub 成绩代替

既要 artifact 血缘简单又要图上 steer,常见做法是简单场景 v1 直调、工作台用 v2;v2 开关打开也不会自动替换所有 research/run 调用方。


一条请求在服务端到底发生了什么

v2(时间线)

把 v2 请求按时间线展开,动作并不复杂。入口先按 orchestration_mode 分流,research 请求交给 ResearchJobV2Service;服务写入 job 记录并挂上预算参数、可选 recall 参数。resolve_spawn_budget 算出本次任务的硬闸后,ResearchLeadLoop.run() 开始分解、spawn、动态加深、critique、合成,图事件持续写到 ResearchGraphEventBus。结束后再把 reportgraph、可选 mind_mapevidence_tree 回写 job payload,并通过 export_trajectory 与审计事件完成对账。

v1(对照时间线)

v1 路径更短:一次 DeepResearchPipeline.run() 在进程内跑完五段,没有独立 job 事件总线。

v1 没有 GET .../events;在响应里拿 workflow_snapshot,或事后按 run_id 查 artifact 链。chat workflowresearch/run 同一条管线,差别在鉴权与会话绑定。

两段流程的价值在边界清楚:入口、编排、检索、存储、事件各管一块,排障可以顺着链路走,不必在一个巨型函数里猜状态。


研究图是怎么长出来的

这一节聚焦入口与 recall。

用户带 orchestration_mode=research(或直调 v2 jobs API)提交后,控制面不进 Chat SSE------长时 spawn、重试、动态 follow-up 不适合用一轮对话的 token 流承载。服务端创建 v2 job(job_idrun_id、phase 如 lead_loop),挂按 job 隔离的 EventBus。工作台订阅 node_addednode_statusconsole_linemetrics_snapshot,看到的是 root → branch → follow-up / critique → synthesize,而不是最后一次性吐长文本。

可选 previous_job_idrecall_artifact_ids 在 Lead 入口拼 recall 前缀(AgentRxiv 风格):上一轮报告摘要、制品片段、S6 黑板笔记压进 query。租户不一致时 build_recall_prefix 整段清空,recall_artifact_ids 也会跳过非本租户制品,不能跨租户接着上次挖。


分解:STORM 多视角 + 可选 LLM + 质量门禁

Lead 第一拍 research_thinkdecompose_query:默认 STORM 多视角分支(methods / evaluation / applications ...),避免永远三条固定话术;llm_decompose_enabled 时可走进程级 hook,失败则回落确定性分支。

gate_decompose_branches 检查分支数量、多样性、是否 legacy 固定三联;结果写入 last_decompose_gate,图上打 Lead.decompose_gate_failed。门禁失败不会 cancel job,仍是观测型:日志里能看见分解质量可疑,Lead 仍用已得 branches 往下 spawn。运维看 console 或报告里的 quality_gates.decompose,gate 红了不等于停跑。

用这篇的论文检索例子来看就很清楚:同一个 query 不会只拆成"找论文"这一条,而会至少拆出"ACL 系列代表作""arXiv 增量工作""评测与代码可用性"三路。如果拆出来三路几乎是同义改写(比如都在重复"找最新论文"),decompose gate 会提示多样性不足,提醒你先改分解策略,再看后面的检索质量。


Worker:分支检索、缺口与来源校验

Worker 不再拆子问题;拆题、spawn、合成都在 Lead。ResearchWorkerRunner 只执行一条 SpawnRequest:按标签推断 arxiv / web,构造查询,调搜索与 fetch,产出 WorkerResult(topic、contribution、citations、gaps、confidence)。要多层展开,靠 Lead 的 DyTopo follow-up 或 critique 补 spawn。

gaps(如 no_retrievable_sources)驱动加深与 critique follow-up。source_validate_enabled 开启时,低质量 citation 可过滤并带 quality_score。控制台 Worker(bN).arxiv_q=... hook 保留,排障看实际检索词。


Spawn 执行:并行 / 顺序 / 混合 + 预算

首批分支由 execute_spawn_requestsspawn_mode 执行:

模式 行为
parallel 线程池并行,宽度 ≤ SpawnBudget.max_workers;各分支 query 基本独立
sequential 逐条跑,下一跳可带前序完成分支的 snippet(便于压测与复现)
hybrid 每批最多 max_workers 个并行;批与批之间给后续请求带已完成结果的 context

SpawnBudget 对一切 spawn 硬顶 max_spawn_totalmax_depth。初始分支、steer 插队、DyTopo、critique 补 spawn 共用同一账本;dynamic follow-up 在 can_spawn 处 break,不会无限长。

每次 spawn 前过 EmergenceGuardrails(research.spawn)。poll_steer 有队列消息时可即时 spawn steer 分支,记入 steer_events(phase、consumed_atspawn_node_id)。

可以拿一组固定参数感受差异:max_workers=3, max_spawn_total=8, max_depth=3。parallel 会先并行跑 3 条;sequential 是一条跑完再下一条;hybrid 会一批并行、一批带上下文继续。无论哪种模式,只要累计 spawn 到 8,就会停止继续补分支。


配置建议:先稳,再快

灰度起步可以保守:AGENTIUM_RESEARCH_V2_ENABLED 先在开发或灰度打开,AGENTIUM_RESEARCH_V2_SPAWN_MODE 用 parallel,max_workers 从 2~4 起,max_depth 先 2~3;AGENTIUM_RESEARCH_DYNAMIC_ROUTING 默认开,critique_max_followups 先 1 或 2,human_feedback_mode 从 minimal 起。

并行、动态加深、critique 一起拉满时,预算撞墙、检索不足、审批拖住任务会叠在一起,很难分清。先把失败路径跑顺,再逐项加量。


DyTopo 与 critique:不是第二个 Lead,也不是辩论 Agent

分支完成后,若 dynamic_routing_enabled,仍是同一个 LeadLoop 做轻量路由:从各 WorkerResult 抽 need/offer,用 token 重叠画语义边(DyTopo.route),再 plan_dynamic_spawn_chainmax_dynamic_hops × max_dynamic_followups 内 spawn follow-up。不会另起一个编排 Agent;实现上是词重叠路由,正文不展开算法。

合成前是单轮确定性 critique(run_deterministic_critique):查 integrated 有无 facts、gaps/conflicts、分支是否跑完,没有第二个 LLM 互辩。issues 经 plan_critique_followups 转成补 spawn(受 critique_max_followups 与 SpawnBudget 限制),图上出现 critique 节点。

可选 _maybe_run_code_experiment 在 SafetySandbox 下跑受控实验节点,失败记为分支 failed。

DyTopo 补「缺的那块证据」;critique 是合成前清单复核,缺口大时再补一两个定向分支,避免扩成无限递归辩论。


Steer 与人机检查点

ResearchJobV2Service.steer 把纠偏文案入队(job 须 running / cancelling)。steer 会改检索路径,不只改报告措辞:poll_steer 在 spawn 中可插队新分支;post_spawn、pre_synthesize、pre_critique 等阶段也会 _consume_phase_steer。新证据先进 integrate_evidence,再影响合成。

human_feedback_mode(minimal / each_phase / each_critique)可在 decompose、synthesize、critique 前走 ApprovalGate,与连载 12 治理对齐。未注入 ApprovalService 时检查点标 hitl_service_unavailable

同一句 steer 在不同阶段效果不同:spawn 阶段更像新增并行检索;pre_synthesize 像合成前补证据;pre_critique 像先补齐再复核。


收束:整合证据、导图与制品

synthesize_reportintegrate_branch_evidence,再合成 summary、report_markdown、citations(带 citation_indices)。gate_synthesis_report 可检查摘要长度与引用是否达标。

报告 payload 还可含 mind_map、evidence_tree(长报告按 evidence_tree_min_tokens 折叠)、critique 元数据。大段分支正文经 maybe_offload_branch_text 进 ArtifactStore(连载 08)。任务完成返回 report + graph 快照;支持 export_trajectory 导出脱敏轨迹。摘要给快速读,citations 给对账,mind_map / evidence_tree 给结构化复盘。


共享黑板、Skills 与系统评测

S6 黑板(SharedWorkspaceMemory)是多分支 Worker 共用的带租约共享白板,在同一研究任务里共享进度、handoff 摘要和待补证据。claim / post / read 与 recall 前缀配合,适用于进程内 Harness;跨 Pod 不是自动分布式,跨实例恢复叠连载 15 checkpoint / handoff。无租约 post 会被拒。

skills/deep-research 提供 Prompt 与模板边界;运行时以 Lead/Worker 代码路径为准。

milestone 脚本 run_research_milestone_eval.py 三档语义不同:stub 用假 Worker、不打网;golden 读 fixture;live 真检索。CI 默认 stub gate(如 milestone_pass_rate ≥ 0.8),stub 绿了不能等同 live 达标。对外宣称生产检索质量,须显式跑 live 并看 spawn 效率、引用覆盖、耗时等 KPI。


线上排障,别先怪模型

线上别先盯最终报告骂模型。顺着 Harness 倒推:入口是不是 research job、events 是否在增长、预算是否撞墙、decompose gate 与 critique issues、steer 是否 steer_consumed、live 评测是否支撑质量判断。

按这个顺序,5 分钟内通常能定位大头:events 是否还在增长、预算是否打满、分解/critique 信号是否正常,最后才看 prompt。先确认壳层可控,再动策略;否则改 prompt 重跑,可能只是预算早已打满。


与外部深研产品的差异(一句)

业界常见的规划 → 多路检索 → 报告,Agentium 同样参考;差异在 SpawnBudget、全阶段 steer 审计、租户 job store、milestone CI 是否写进运行时,而不是多堆 Agent 角色名。


几个高频误区

最常见的坑是接入层:把 research 当 Chat SSE 接,而不是消费 job 事件 API;把分解 gate 当阻断器,看到红灯就以为任务会停。还有预算判断:以为 dynamic follow-up 会一直加深,但 max_spawn_totalmax_depth 会先把路堵住。

另两类误判也很常见:steer 只看到入队、没核对 steer_consumed;stub milestone 一绿就当 live 达标。再加上忘了开 v2 开关就认定功能坏了,最后看起来像模型问题,其实是链路理解没对齐。


收束一下,下一篇讲什么

v2 Harness 把 STORM/LLM 分解、观测型门禁、spawn 模式、Worker 检索、DyTopo、critique 补 spawn、steer/HITL、证据整合与 mind_map 收进 ResearchJobV2Service,与 orchestration_mode=research 对齐;与 v1 五段 DAG 双轨并存,按场景选型。入口与 workflow、agentic 三分法一并记住,少混线。

下一篇进入资源 Admin:MCP、Skill、Persona 的登记、probe 与 WorkspaceAgentConfig 绑定。(连载 30)

相关推荐
枫子有风1 小时前
AI编程-Vibe coding(大厂常问问题)
人工智能·ai编程
枫叶林FYL1 小时前
BRIDGE:多模态查询的强化学习对齐与文本检索重构
人工智能·语言模型
Sam09272 小时前
Loop Engineering 是什么:让 AI Agent 从一次性回答变成可迭代执行
人工智能·ai
TCW11212 小时前
AI底层系列:用C++实现线性代数的公式推导与算法设计-6.线性方程组的解集
c++·人工智能·算法
毛骗导演2 小时前
Tool Boundary:如何让大模型永远不知道也不会泄露用户敏感数据
前端·架构
古城小栈2 小时前
Python 的主流Ai框架为什么优先适配 Linux 系统?
linux·人工智能·python
财经资讯数据_灵砚智能2 小时前
基于全球经济类多源新闻的NLP情感分析与数据可视化(夜间-次晨)2026年6月15日
大数据·人工智能·python·ai·信息可视化·自然语言处理·灵砚智能
暮云星影2 小时前
瑞芯微rk3588利用Rockchip NPU运行大语言模型(LLM)
arm开发·人工智能·语言模型·自然语言处理
ujainu小2 小时前
CANN ops-transformer:编译和运行 FlashAttention 示例
人工智能·深度学习·transformer