AI Agent自主研究落地:从Discovery Loop到验证闭环的工程实践 做 AI Agent 的开发者最近应该都绕不开一个词“智能体自主研究”。无论是科研辅助、自动化数据分析还是企业知识库的自动归纳越来越多的团队开始尝试让 Agent 不只是“问答”而是能够自己提出问题、设计实验、验证结论并不断把新发现反馈到下一轮研究里。但我也观察到很多人在做这类系统时最容易踩的坑是Agent 跑了一堆流程生成的结论却经不起复核或者每次结果都像“开盲盒”完全无法复现。智源 AREX 提出的“Discovery Loop”和“验证闭环”本质上就是为了解决这个问题让智能体的研究过程既可探索、又可验证最终形成一条可累积、可进化的闭环路径。本文先从概念讲清楚什么是 Discovery Loop、什么是验证闭环再给出一套可运行的 Python 工程示例演示如何把“假设生成 - 探索发现 - 独立验证 - 策略更新”的循环落地最后会针对工程化落地中的常见问题给出排查思路。如果你正在做智能体平台开发、科研自动化或者准备把 Agent 接入真实业务这篇文章会非常有用。1. 背景与核心概念1.1 智能体自主研究从“工具调用”到“科研过程模拟”很多人对 Agent 的第一印象是“能调用工具的聊天机器人”也就是用户给一个问题Agent 拆解步骤然后调用搜索、代码、数据库等工具返回答案。这种方式在 QA 场景下很好用但离“自主研究”还有一段距离。真正意义上的智能体自主研究更接近一位研究助理的日常工作流程接收一个相对开放的研究目标而不是一个明确的问题把目标拆解成可验证的子问题主动检索文献、查数据、跑实验根据中间结果调整研究路径最终给出带证据链的结论。所以“自主研究”的核心不是“多调用几个工具”而是 Agent 要像一个研究者一样具备提出假设、收集证据、验证结论、复盘失败的能力。这也是 AREX 这类智能体框架和普通 Agent 框架拉开差距的地方。1.2 什么是 Discovery LoopDiscovery Loop 可以直译为“发现循环”。它不是一次性的推理过程而是一个持续迭代的探索过程。简单来说它描述的是下面这个模式定义一个研究问题基于已有知识或线索生成候选假设通过检索、实验或数据分析去收集证据把新证据和新线索记录下来带着更多线索重新生成假设再次探索。用一句话概括就是让 Agent 在“问题空间”里不断做广度探索像一个科研人员一样“先发散再收敛”。很多早期的 Agent 系统只做了一步用户提问 - Agent 回答。这本质上是一个“查询闭环”。但 Discovery Loop 强调的是“多轮假设生成 多源证据收集”它能让 Agent 在面对复杂问题时不轻易给出单点结论而是把可能的方向都探索一遍。1.3 什么是验证闭环如果说 Discovery Loop 负责“找可能性”那么验证闭环负责“确认可靠性”。验证闭环的核心动作包括对 Agent 生成的每一个结论做独立验证用不同的工具或数据源交叉检查检查证据是否可复现把验证通过的结果写入“可信知识库”把验证失败的原因记录到“失败库”用于后续策略修正。只探索不验证系统就会变成“幻觉放大器”。只验证不探索系统又会变成“重复劳动机器”。所以 AREX 把两者放在一起本质上是让智能体同时具备“学术想象力”和“学术严谨性”。1.4 为什么 AREX 把两者结合成一套范式从公开资料和工程实践经验来看AREX 强调的不只是一个产品功能而是一种智能体工程方法论。它把 Discovery Loop 和验证闭环做成了可编排的流程让开发者不再需要从零去设计“要不要验证”“怎么验证”这类问题。AREX 的关键思路是探索和验证在流程上解耦在数据上耦合。流程上解耦探索阶段可以大胆发散验证阶段必须严格收敛数据上耦合探索阶段产生的证据、假设、失败记录都会成为验证阶段和下一轮探索阶段的数据输入。这样的好处是系统的“聪明程度”不再完全依赖模型推理能力而是依赖是否有完善的循环机制。模型可能在某一轮表现一般但只要循环结构合理Agent 就能在后续迭代中不断修正自己。2. AREX 的整体设计和技术定位2.1 分层架构概览从工程实现的角度看AREX 这类智能体自主研究框架通常可以分成五层。下面用表格做一个概括层级核心职责典型组件任务层接收研究目标、定义边界、管理权限任务解析器、人机交互界面编排层管理 Discovery Loop 状态机决定何时探索、何时验证循环控制器、策略调度器执行层调用真实工具完成检索、计算、实验搜索 API、代码执行器、数据库客户端验证层对结果做规则校验、独立复现、交叉验证验证器、实验执行器、人工复核队列记忆层存储假设、证据、失败原因和长期策略记忆向量数据库、Redis、关系型数据库这种分层的好处在于每一层都可以单独替换和扩展。比如执行层的搜索工具可以换验证层的规则可以加记忆层的数据存储可以迁移。只要层与层之间的接口足够清晰整个系统就不会因为某一部分升级而推倒重来。2.2 核心抽象状态、循环与判定AREX 这类系统的代码设计里有几种抽象非常重要ResearchState表示一次研究任务的当前状态比如“探索中”“验证中”“已收敛”LoopController驱动整个循环决定下一轮是继续探索、进入验证还是结束任务Verdict验证层输出的判定结果不只是“通过/不通过”还要带上理由、证据、置信度。这些抽象保证了“自主研究”不是写死的一串 if-else而是可以被配置、被观测、被调整的工程流程。2.3 与通用 Agent 框架的差异如果你用过 LangChain、Dify、Coze 这类通用 Agent 平台会发现它们的重点在“工具编排”和“对话管理”上。AREX 这套思路则更强调“研究过程的状态化管理”。通用 Agent 框架通常是“一次任务一次规划一次执行”。而 AREX 这类自主研究框架是“一个目标多轮循环层层验证”。因此在实际落地时你往往需要在通用 Agent 框架之上自己再实现一个循环控制器和验证器这正是本文后面示例要解决的问题。3. 从 Discovery Loop 到验证闭环机制拆解3.1 Discovery Loop 的四个关键阶段我们可以把 Discovery Loop 拆成四个阶段问题定义把模糊的研究目标转成可执行的问题列表假设生成根据已有证据、模型知识或历史记忆生成候选结论探索执行调用外部工具收集证据覆盖不同角度记录沉淀把证据、中间结论、失败原因写回记忆层。每个阶段都需要有明确的输入输出。比如“假设生成”的输入是问题、已有证据、历史记忆输出是一组假设“探索执行”的输入是假设输出是证据或实验结果。在工程实现上我建议给每个阶段增加独立的日志和回调接口方便后续做评估和调试。很多 Agent 项目跑一段时间后无法复盘就是因为阶段没有边界所有内容混在同一个循环里。3.2 验证闭环的四道闸门验证闭环不只是一次性检查而是一套层层递进的闸门机制。我把最常见的四道闸门整理如下验证层级验证内容失败处理完整性验证检查结论是否回答了原始问题有没有遗漏关键子问题打回重新探索可复现性验证重跑同一流程看结论是否一致降低置信度必要时拒绝交叉验证用不同数据源或工具验证同一结论标记为“待人工复核”证据链验证检查证据来源、时间、参数、推导过程是否可追溯证据链不完整则拒绝这四道闸门不一定全部自动化。对高风险场景最后一道“证据链验证”可以有人工参与。关键是系统要能明确告诉你一个结论到底是通过了哪些验证才被接受的。3.3 自进化验证结果如何反馈给系统“自进化”听起来很高端但实际上并不需要重新训练模型。更务实的做法是把验证失败的原因结构化并写入记忆层作为下一轮决策的参考。举个例子如果多次失败是因为“检索不到足够证据”那系统可以在探索阶段主动扩充关键词如果多次失败是因为“实验数据不稳定”那系统可以在验证阶段引入多次实验取平均如果多次失败是因为“假设本身太激进”那系统可以增加一条策略先验证简单假设再推进复杂假设。这就是从“Discovery Loop”到“验证闭环”形成闭环的真正价值验证阶段产生的失败经验能反过来优化 Discovery Loop 的探索策略。4. 环境准备与仿真工程搭建4.1 环境要求为了更好地理解这套机制我们直接用 Python 写一个可运行的仿真工程。示例使用 Python 3.10不需要安装额外第三方库只依赖标准库中的dataclasses和typing。版本需要根据你的实际环境调整。如果你本机是 Python 3.8可以把Hypothesis | None改成Optional[Hypothesis]如果是 Python 3.12则完全兼容。示例工程的核心目的不是复刻 AREX 全部功能而是演示 Discovery Loop 和验证闭环的最小可运行模型。真实落地时你还需要接入大模型接口、搜索引擎、数据库和代码执行环境。4.2 项目结构我们创建一个简单的项目结构research_agent/ ├── main.py ├── models.py ├── memory.py ├── loops.py └── verifier.pymodels.py定义研究任务、证据、假设的数据结构memory.py实现记忆层保存证据、假设和失败原因loops.py实现 Discovery Loop 的探索逻辑verifier.py实现验证闭环main.py串联整个流程。5. 完整实战一个可运行的自主研究 Agent 示例5.1 定义数据模型先定义核心数据结构。这里的关键设计是每个假设必须带有支撑证据 ID每个证据必须带有可复现性评分。这样后续验证时系统才能判断“结论是不是站得住脚”。# 文件路径research_agent/models.py from dataclasses import dataclass, field from typing import List dataclass class Evidence: source_id: str content: str keywords: List[str] reproducibility_score: float 0.0 dataclass class Hypothesis: id: str claim: str supporting_evidence: List[str] field(default_factorylist) refuting_evidence: List[str] field(default_factorylist) status: str proposed # proposed / accepted / rejected verdict_reason: str dataclass class ResearchTask: question: str max_iterations: int 3这里我故意把status定义成字符串而不是枚举是为了让示例更简单。真实项目中建议使用 Python 的Enum或 Pydantic 的字面量类型避免状态值随手乱写。5.2 实现记忆层记忆层在自主研究系统中非常重要。它负责保存所有证据和假设同时记录失败原因。注意这里的“记忆”不是指大模型的上下文窗口而是工程层面的持久化数据存储。# 文件路径research_agent/memory.py from typing import Dict, List, Optional from models import Evidence, Hypothesis class MemoryStore: def __init__(self) - None: self.evidence_map: Dict[str, Evidence] {} self.hypotheses: List[Hypothesis] [] self.failure_reasons: Dict[str, int] {} def add_evidence(self, evidence: Evidence) - None: self.evidence_map[evidence.source_id] evidence def get_evidence(self, source_id: str) - Optional[Evidence]: return self.evidence_map.get(source_id) def add_hypothesis(self, hypothesis: Hypothesis) - None: self.hypotheses.append(hypothesis) def record_failure(self, reason: str) - None: self.failure_reasons[reason] self.failure_reasons.get(reason, 0) 1实际项目中MemoryStore可以替换成 Redis、向量数据库或关系型数据库。唯一的原则是所有中间产物都要能根据 ID 找回不能只存在于模型的上文窗口里。5.3 实现 Discovery Loop下面用一个模拟的MockDiscoveryLoop类来演示 Discovery Loop。真实环境中search应该调用搜索 APIgenerate_hypothesis应该调用大模型。这里为了可复现直接用预设数据演示。# 文件路径research_agent/loops.py from typing import List from models import Evidence, Hypothesis, ResearchTask from memory import MemoryStore class MockDiscoveryLoop: 模拟 Discovery Loop用于演示自主研究的探索过程。 def __init__(self, memory: MemoryStore) - None: self.memory memory def search(self, keywords: List[str]) - List[Evidence]: 模拟文献检索按关键词返回预先准备好的证据。真实场景应接入搜索 API。 pool [ Evidence( source_idlit-001, content温度升高导致催化剂表面吸附能力下降但反应速率常数上升。, keywords[温度, 催化, 速率], reproducibility_score0.9, ), Evidence( source_idlit-002, content在 300K-500K 范围内某催化反应速率随温度升高而加快。, keywords[温度, 速率], reproducibility_score0.8, ), Evidence( source_idlit-003, content部分催化剂在高温下会失活反而不利于反应持续进行。, keywords[温度, 催化剂, 失活], reproducibility_score0.85, ), ] matched [ ev for ev in pool if set(keywords).intersection(set(ev.keywords)) ] for ev in matched: self.memory.add_evidence(ev) return matched def generate_hypothesis(self, question: str, evidence: List[Evidence]) - Hypothesis: 根据证据内容粗粒度生成假设。真实环境中应由 LLM 完成。 all_text .join(e.content for e in evidence) if 随温度升高而加快 in all_text or 上升 in all_text: claim 温度升高会提升该催化反应的反应速率。 elif 失活 in all_text: claim 高温可能导致催化剂失活进而降低反应速率。 else: claim 温度对反应速率影响不显著。 hypothesis Hypothesis( idfhyp-{len(self.memory.hypotheses) 1}, claimclaim, supporting_evidence[e.source_id for e in evidence], ) return hypothesis def run(self, task: ResearchTask) - Hypothesis: print(f开始 Discovery Loop研究问题{task.question}) hypothesis: Hypothesis | None None for i in range(1, task.max_iterations 1): print(f\n[迭代 {i}]) evidence self.search([温度, 催化, 速率]) if not evidence: self.memory.record_failure(未检索到有效证据) break hypothesis self.generate_hypothesis(task.question, evidence) self.memory.add_hypothesis(hypothesis) print(f生成假设{hypothesis.claim}) print(f支撑证据{hypothesis.supporting_evidence}) if hypothesis is None: raise RuntimeError(Discovery Loop 未生成有效假设) return hypothesis这里需要注意几点search方法返回的证据会立刻写入 memory这是为了后续验证阶段可以直接读取。generate_hypothesis只是简单基于关键词判断真实场景要换成大模型调用并设计好 Prompt。run方法中的max_iterations是防止探索阶段无限循环的关键参数。5.4 实现验证闭环接下来是验证闭环。这里模拟了一个独立实验验证步骤也就是 Agent 不能只相信自己从文献中检索到的证据还要想办法通过实验或其他工具进行复现。# 文件路径research_agent/verifier.py from models import Hypothesis, ResearchTask from memory import MemoryStore class VerificationEngine: 模拟验证闭环通过独立实验和证据交叉检查判断假设是否成立。 def __init__(self, memory: MemoryStore) - None: self.memory memory def run_independent_experiment(self, claim: str) - dict: 模拟独立实验返回实验结论。真实环境应触发代码执行或实验任务。 if 提升 in claim: return { passed: True, detail: 独立实验显示高温组速率比低温组高 18%与假设一致。, } if 失活 in claim: return { passed: True, detail: 独立实验显示催化剂活性在高温下下降 25%与假设一致。, } return { passed: False, detail: 独立实验未观察到显著差异。, } def verify(self, hypothesis: Hypothesis, task: ResearchTask) - Hypothesis: print(f\n开始验证假设{hypothesis.claim}) # 第一步证据完整性检查 if not hypothesis.supporting_evidence: hypothesis.status rejected hypothesis.verdict_reason 缺少支撑证据 self.memory.record_failure(缺少支撑证据) return hypothesis # 第二步独立实验验证 result self.run_independent_experiment(hypothesis.claim) if not result[passed]: hypothesis.status rejected hypothesis.verdict_reason result[detail] self.memory.record_failure(独立实验未通过) return hypothesis # 第三步证据质量复核 evidence_scores [] for source_id in hypothesis.supporting_evidence: ev self.memory.get_evidence(source_id) if ev: evidence_scores.append(ev.reproducibility_score) if evidence_scores and min(evidence_scores) 0.7: hypothesis.status rejected hypothesis.verdict_reason 存在低可复现性证据需人工复核 self.memory.record_failure(证据可复现性不达标) return hypothesis hypothesis.status accepted hypothesis.verdict_reason 证据完整、独立实验通过、可复现性达标 print(f验证通过{hypothesis.verdict_reason}) return hypothesis这个验证器虽然简单但已经具备验证闭环的核心思想不轻信单条证据不跳过独立实验不以“模型说对就对”作为结论依据。5.5 运行入口与预期输出最后写main.py把 Discovery Loop 和验证闭环串联起来。# 文件路径research_agent/main.py from models import ResearchTask from memory import MemoryStore from loops import MockDiscoveryLoop from verifier import VerificationEngine def main() - None: memory MemoryStore() loop MockDiscoveryLoop(memory) verifier VerificationEngine(memory) task ResearchTask( question温度升高是否会影响催化反应的反应速率, max_iterations2, ) hypothesis loop.run(task) hypothesis verifier.verify(hypothesis, task) print(\n 结果汇总 ) print(f研究问题{task.question}) print(f最终结论{hypothesis.claim}) print(f状态{hypothesis.status}) print(f验证理由{hypothesis.verdict_reason}) print(f失败原因统计{memory.failure_reasons}) if __name__ __main__: main()运行命令cd research_agent python main.py预期输出大致如下开始 Discovery Loop研究问题温度升高是否会影响催化反应的反应速率 [迭代 1] 生成假设温度升高会提升该催化反应的反应速率。 支撑证据[lit-001, lit-002, lit-003] [迭代 2] 生成假设温度升高会提升该催化反应的反应速率。 支撑证据[lit-001, lit-002, lit-003] 开始验证假设温度升高会提升该催化反应的反应速率。 验证通过证据完整、独立实验通过、可复现性达标 结果汇总 研究问题温度升高是否会影响催化反应的反应速率 最终结论温度升高会提升该催化反应的反应速率。 状态accepted 验证理由证据完整、独立实验通过、可复现性达标 失败原因统计{}这个示例虽然场景很小但它完整展示了“探索 - 假设 - 验证 - 接受”的最小闭环。你可以修改task.max_iterations、证据池内容或实验判定逻辑观察系统行为变化。6. 工程化设计与扩展思路6.1 把工具调用抽象成接口真实项目里Agent 不可能只依赖一个模拟搜索方法。建议把所有外部能力抽象成统一接口例如from typing import List, Dict, Any class ResearchTool: def name(self) - str: ... def run(self, params: Dict[str, Any]) - Any: ...每个工具只负责一件事搜索工具负责查资料代码执行工具负责跑分析脚本数据库工具负责查结构化数据实验工具负责触发真实实验任务。这样编排层才能统一调度验证层也能对不同工具的输出做标准化检查。6.2 缓存、去重与成本控制Discovery Loop 最怕的问题之一是“原地打转”。如果没有缓存和去重机制Agent 可能会用同样的关键词搜索十次然后生成几乎一样的假设。工程上是这样处理的每次搜索前把关键词列表哈希后存入缓存命中缓存则直接返回历史结果不重复调用外部 API每次生成假设前计算假设文本的相似度与已有假设对比设置单次任务的迭代上限和费用上限。成本控制在自主研究系统里不是可选项而是必选项。因为一个研究任务可能涉及几十次工具调用如果没有预算控制线上成本会非常不可控。6.3 验证器的插件化设计验证闭环要做到可扩展最好把验证器拆成多个独立插件。推荐的结构是验证插件类型作用RuleVerifier检查字段完整性、格式、枚举值ReproduceVerifier重跑代码或实验检查结果是否一致CrossCheckVerifier调用第二种工具或数据源交叉验证HumanReviewHandler把高风险结果推送给人工审核每个插件输入一个Hypothesis和一个EvidenceList输出一个Verdict。编排层根据业务规则决定哪些插件必须通过、哪些插件可以降级。6.4 可观测性与审计日志自主研究系统的决策链路比普通 Agent 长很多因此必须做好可观测性。每个任务应该有唯一的trace_id循环里的每一步都要记录当前状态输入参数工具调用结果假设内容验证结果失败原因耗时和花费。这样即使最终结论出问题也能回溯到具体是哪一步引起的。对科研场景来说审计日志甚至比最终结论更重要因为没有过程可信度就没有结果可信度。7. 常见问题与排查思路问题现象常见原因解决思路Agent 反复执行相同搜索缺少缓存和去重增加搜索缓存记录访问过的关键词组合结论与证据明显不符验证环节缺少独立校验引入交叉验证或实验验证器验证结果不稳定外部工具返回波动增加重试、超时以及多次实验取平均循环无法正常结束缺少迭代上限设置max_iterations和费用预算自我进化效果不明显失败原因没有结构化对失败原因分类、统计并映射到策略调整已有证据被重复写入记忆层缺少主键约束使用source_id唯一索引重复写入时更新人工复核流程卡住审核任务没有超时机制为人工审核队列设置 SLO超时自动降级或提醒如果你在实际项目里遇到了相似问题建议先从日志入手检查某一次结论从探索到验证的全部路径。大多数“智能体不可控”的问题并不是模型问题而是流程缺少约束和记录。8. 最佳实践与落地建议8.1 先从“最小闭环”开始不要一上来就构建一个包含几十个工具、多智能体协作的巨型系统。建议先跑通“一个研究问题 - 一次 Discovery Loop - 一次验证闭环”的最小流程确认数据结构和验证逻辑可靠再逐步扩展工具和数据源。最小闭环跑通之后你才会真正理解哪些地方需要缓存、哪些地方容易出现死循环、哪些证据质量指标最有效。8.2 定义清晰的评估集自主研究系统的效果不能靠感觉需要一组“金标准”评估集。比如准备 20 个研究问题每个问题都预置标准答案和关键证据然后统计系统在每轮迭代后是否接近标准答案。推荐指标包括指标说明探索覆盖率关键证据是否在探索阶段被覆盖到验证通过率被接受的结论占比结论可复现率同一问题多次运行结论是否一致单任务成本工具调用次数和费用平均迭代次数收敛速度是否合理8.3 全自动与半自动结合在科研和业务场景中不建议在所有环节都做全自动。比较稳妥的做法是低风险结论自动验证后直接输出高影响结论自动验证后再加一道人工复核涉及外部系统操作时Agent 只生成执行方案由人工确认后再执行。“智能体自主研究”不等于“无人值守”。边界划分得越清楚系统越容易在真实环境落地。8.4 安全与权限边界如果 Agent 能够执行代码、查询数据库或触发外部任务必须遵循最小权限原则。重点注意以下几点所有外部操作必须走统一网关不能直接暴露数据库密码代码执行使用沙箱环境限制网络访问和文件系统权限高危操作删除、写入、资金相关必须二次确认保存完整审计日志方便定位问题。自主研究系统做的是“放大人类研究能力”不是“绕过人类控制边界”。在工程初期就把安全设计进去比上线后再补要省力得多。8.5 失败经验要“可复用”很多团队做完一轮 Agent 实验后只把成功结论保存下来失败经验直接丢掉。这种做法非常可惜。建议在记忆层里单独维护一个failure_reasons字典记录失败的类别、上下文和最终处理方式。下一轮任务开始前循环控制器可以读取这些失败经验主动调整搜索策略或验证强度。这就是“自进化”最务实的落地方式不需要训练模型只需要让系统“记住错误并且下次少犯同样的错误”。9. 下一步可以怎么学如果你现在正准备做智能体自主研究相关项目我的建议是先动手跑完上面的示例再按以下顺序深入把MockDiscoveryLoop替换成大模型调用让 Agent 自动生成假设把search替换成真实搜索 API接入多轮检索增加插件化验证器引入统计检验和人工复核接入真实记忆存储比如 Redis 或向量数据库最后再考虑多智能体协作、自动评估和自进化策略。AREX 带来的启示是智能体真正难的不是“让它动起来”而是“让它动得有章法”。Discovery Loop 给了系统探索能力验证闭环给了系统纠错能力。两者结合才形成了可持续进化的研究范式。如果你也在探索类似的智能体自主研究方案欢迎在自己的项目中实践这套思路并结合自己的业务场景做调整。框架可以不同但“先探索、再验证、后沉淀”的闭环思想是通用的。