
在 Google DeepMind 于 2025 年公开多智能体系统 AI Co-Scientist 之前学术界对“AI 辅助科研”的想象大多停留在两个层面让大模型帮忙总结文献或者让它生成一段实验方案草稿。这两种用法本质上都是检索增强的文本生成模型并没有真正参与“提出科学问题”这个环节。Co-Scientist 的定位从一开始就不同它用一组分工明确的 AI Agent把“提出研究假设、评估假设、改进假设”做成一条可运行的流水线。而“实验室集成研究伙伴”这个新方向又把问题从模型设计推向了工程落地——一个科研助手要真正进入实验室不能只靠更会生成的模型还要靠检索、编排、权限、监控、人工审批和验证闭环共同支撑。先看它多智能体流水线如何工作再看实验室集成会产生哪些工程问题最后给出一个可以动手实现的研究助手最小原型并整理验证方法、常见故障排查和上线前检查清单。1. 先理解 Co-Scientist 解决的是哪个环节的问题1.1 科研流程中真正缺的不是“总结文献”而是“提出假设”科研流程可以粗分为六个环节提出科学问题、检索文献、生成假设、设计实验、执行实验、分析数据。传统大模型工具最容易上手的是第二和第六环节也就是“帮我把这篇论文总结一下”和“帮我把这批实验数据整理成图表”。这两个环节虽然能节省时间但并没有改变科研的核心工作方式。真正的瓶颈在第一和第三环节。提出科学问题需要研究者判断什么值得做生成假设则需要研究者基于已有证据、机制推理和实验条件构造出一个可以被实验检验的判断。假设生成是一个开放性问题同一份文献不同人会提出不同的可检验假设质量差异来自对机制的把握、对证据的权衡和对实验可行性的判断。这部分工作很难用“让模型多生成几段话”来解决因为单次生成缺少反馈、缺少对比、缺少甄别。1.2 为什么单次 prompt 很难产出高质量科学假设如果直接在对话框里写“请为我提出一个关于癌症耐药性的研究假设”模型大概率会输出一个结构完整但泛泛而谈的段落。问题不是模型不够聪明而是单次 prompt 没有给模型提供足够的思考结构没有评审者没有对比项没有改进循环。Co-Scientist 的做法是引入多智能体结构让生成、反思、排序、进化这些动作分离。生成 Agent 负责提出候选假设反思 Agent 负责找漏洞排序 Agent 负责比较优劣进化 Agent 负责把高分假设改得更好。每一步的输出都会成为下一步的输入形成类似人工科研讨论中的“提出—质疑—修改”循环。这也是推理时计算test-time compute的意义在推理阶段投入更多计算换取更高比例的优质输出而不是简单依赖模型参数变大。1.3 “实验室集成研究伙伴”意味着从模型问题变成系统问题当一个工具定位为“独立问答助手”时用户手动输入目标系统返回假设文本剩下的查文献、做实验、记录结果都由人完成。但当定位变成“实验室集成研究伙伴”时系统就不能再是一块孤立的对话界面。它需要连接到实验记录、数据库、文献库和审批流程能够在真实的研发节奏里提供建议而不是只在被询问时输出一段文字。这里的技术难度已经从提示词工程变成了系统集成工程。数据接入、权限隔离、审计日志、异步任务、人工审批节点、成本上限、模型回滚这些原本在业务系统中常见的问题全部会出现在科研 AI 系统里。理解这一点再看 Co-Scientist 的架构和工作原理会更清楚它到底解决了什么以及哪些能力是模型本身带来的哪些能力要靠工程系统补齐。2. 拆解 Co-Scientist 的多智能体流水线谁生成、谁评审、谁进化2.1 六个 Agent 的分工可以映射到研发流程的六个角色在 DeepMind 公开的多智能体设计中Co-Scientist 并不是一个“超级模型”直接回答科研问题而是由多个职责不同的 Agent 协作完成。理解这套设计最直接的方式是把每个 Agent 对应到真实研发流程中的一个角色。Agent核心职责对应研发流程中的角色生成 Agent基于研究目标和已有证据生成候选假设提出点子的研究者反思 Agent审视假设找出逻辑漏洞和证据缺口审稿人排序 Agent对候选假设进行两两对比形成排名项目评审组进化 Agent对高分假设进行变异、组合、改进反复修改方案的工程师邻近性 Agent检查新假设与已有假设的相似度避免重复查重员元评审 Agent汇总全部中间结果做出最终判断课题组长这个设计的核心思想是“单一职责”。生成 Agent 不需要同时负责判断自己的输出是否合理反思 Agent 不需要考虑如何改进——每种行为都由专门的模型调用和提示词模板承担。这样做的好处是每个环节的可控性更强哪个环节质量差就单独调整哪个 Agent而不是重写整段 prompt。容易误解的地方在于多智能体不等于“开多个对话框”。如果只是把同一个模型用不同 prompt 各调用一次再把结果拼在一起那不是多智能体而是多次采样。多智能体的关键在 Agent 之间有明确的输入输出关系前一个 Agent 的结果会真实影响后一个 Agent 的行为。2.2 锦标赛排序为什么不用单一评分排序 Agent 面临一个很实际的问题让大模型直接给假设打 0 到 10 分分数很容易受 prompt 措辞影响而且不同轮次之间分数不具可比性。今天的“8 分假设”和明天的“8 分假设”可能质量完全不同。Co-Scientist 选择的是两两对比加淘汰赛的思路。把候选假设两两配对让排序 Agent 判断哪个更好胜者进入下一轮最后形成完整的排名。这种锦标赛式排序比绝对打分更稳定因为模型只需要做“二选一”的相对判断难度更小结果也更可复现。公开案例中这套排序方法被用在药物重定位、肝纤维化靶点识别等生物医学问题上目的是让高质量假设稳定地排到前面而不是只依赖一次随机输出。2.3 一个具体例子从“找靶点”到“可执行方案”假设研究目标是“为急性髓系白血病寻找新的治疗靶点”。一次完整的 Co-Scientist 流程大致是这样的生成 Agent 基于研究背景一次输出 5 个候选假设每个假设包含机制说明和初步证据。反思 Agent 逐一审视指出其中一个候选假设虽然机制合理但缺少可用的公共数据集来验证表达差异。进化 Agent 把两个分数较高的候选假设组合成一个新版本补充了“先做转录组筛选再做小分子抑制实验”的验证路径。邻近性 Agent 提示新组合后的假设与已有专利重叠度偏高需要修改分子选择范围。多轮循环后元评审 Agent 汇总所有中间结果给出 3 个最终候选假设每个都附带机制说明、现有证据、建议实验和风险提示。这个流程真正的价值在于每一步的输出都可以被人类科学家检查。系统不是直接给一个“最终答案”而是把从初步想法到成熟方案的过程拆成了一串可审计的节点。这也是它能从独立工具走向实验室集成的结构基础——如果中间过程不可检查研究者很难放心让系统参与真实科研决策。3. 动手实现一个最小研究助手多智能体编排思路3.1 先定义最小闭环理解 Co-Scientist 之后可以在自己的环境里搭一个简化版研究助手目的是体验多智能体编排的核心模式而不是复刻 DeepMind 的完整系统。最小闭环可以这样定义输入一个研究目标和若干约束条件系统先检索相关文献再由多个 Agent 协作生成候选假设最后输出排序后的假设列表每个假设都附带依据和实验建议。这个闭环已经涵盖生成、反思、进化、排序四个核心动作足够说明多智能体编排的原理。学习阶段不需要追求大模型。使用任意一个支持 OpenAI 兼容接口的模型即可甚至可以先用本地部署的小模型跑通流程再替换成更强的推理模型。这里要特别注意下面代码是演示编排思路的骨架实际项目需要根据自己的包名、模型接口和数据结构调整。3.2 用 Python 实现一个可运行的 Agent 编排骨架先定义数据结构和两个基础 Agent。这里刻意不绑定具体框架方便看清每个步骤做了什么。# orchestrator.py import asyncio from dataclasses import dataclass, field dataclass class Hypothesis: title: str rationale: str experiments: list[str] references: list[str] score: float 0.0 dataclass class ResearchTask: goal: str constraints: list[str] field(default_factorylist) seed_context: list[str] field(default_factorylist) class GenerationAgent: def __init__(self, llm_client): self.llm_client llm_client async def run(self, task: ResearchTask, prior: list[Hypothesis]) - list[Hypothesis]: prompt build_generation_prompt(task, prior) texts await self.llm_client.complete(prompt, temperature0.8, n5) return [parse_hypothesis(t) for t in texts] class ReflectionAgent: def __init__(self, llm_client): self.llm_client llm_client async def run(self, hypothesis: Hypothesis) - list[str]: prompt build_reflection_prompt(hypothesis) return await self.llm_client.complete(prompt, temperature0.2, n3) class EvolutionAgent: def __init__(self, llm_client): self.llm_client llm_client async def run(self, hypothesis: Hypothesis, critiques: list[str]) - Hypothesis: prompt build_evolution_prompt(hypothesis, critiques) text await self.llm_client.complete(prompt, temperature0.6, n1) return parse_hypothesis(text[0])三个 Agent 的职责很清晰生成 Agent 做开放扩展所以温度高一些反思 Agent 做挑剔审查温度低一些进化 Agent 介于两者之间既要修改又不能太发散。build_generation_prompt、parse_hypothesis这类函数需要自己实现它们负责把研究目标拼成提示词以及把模型输出解析成结构化对象。接着是主流程负责控制循环、去重和排序async def run_research_pipeline(task: ResearchTask, llm_client, cycles3): generation GenerationAgent(llm_client) reflection ReflectionAgent(llm_client) evolution EvolutionAgent(llm_client) hypotheses await generation.run(task, prior[]) for _ in range(cycles): new_hypotheses [] for h in hypotheses: critiques await reflection.run(h) improved await evolution.run(h, critiques) new_hypotheses.append(improved) hypotheses deduplicate_by_similarity( task.goal, hypotheses new_hypotheses ) ranked await tournament_rank(hypotheses, llm_client, top_k3) return ranked主流程有四个关键点。第一循环次数cycles直接决定成本和质量不建议初始设置超过 3。第二每轮进化都基于上一轮结果因此需要给模型传入必要的上下文但不需要把全部历史都塞进去。第三deduplicate_by_similarity在排序前执行避免多个高度相似的假设占据排名靠前的位置。第四tournament_rank实现两两对比排序而不是让模型一次性打分。注意这套代码只演示编排思路生产环境要把每个 Agent 的超时、重试、异常处理和 token 上限单独设计不能假设模型调用永远成功。在正式项目中可以把这套编排逻辑映射到 LangGraph 的 StateGraph 节点或者落到工作流引擎里。LangGraph 这类框架提供了状态管理、断点恢复和可视化对调试多智能体流程很有帮助。但先理解上面的骨架再迁移到框架会比直接套框架更清楚每一步在做什么。3.3 接入检索让假设有文献依据没有文献检索的研究助手生成出来的假设大概率是空中楼阁。最小闭环至少要接入一个外部检索源。以 PubMed 为例可以用 NCBI E-utilities 做一个简化版搜索工具# retrieval.py import httpx async def search_pubmed(query: str, top_k: int 5) - list[dict]: async with httpx.AsyncClient(timeout15) as client: search await client.get( https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi, params{db: pubmed, term: query, retmax: top_k, retmode: json}, ) search.raise_for_status() ids search.json().get(esearchresult, {}).get(idlist, []) if not ids: return [] detail await client.get( https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi, params{db: pubmed, id: ,.join(ids), retmode: json}, ) detail.raise_for_status() result detail.json().get(result, {}) return [ {