把 AI Agent 从一个“单兵作战”的工具,变成一个“集团协作”的系统,是我最近一直在琢磨的方向。正好手头在做一套学术评审的模拟流程,借这个机会把 AI Agent 之间的互动方式彻底梳理了一遍。这篇笔记会用“AI Agent 参与学术评审”这个具体场景,把多 Agent 系统的设计思路、互动模式、落地实现和踩坑经验完整讲清楚。不管你是刚接触 Agent 开发,还是已经用 LangChain、LangGraph 这类框架写过几个 Demo,这篇文章里的内容都能直接拿去做参考。
1. 为什么选“学术评审”当作多 Agent 互动的沙盒
1.1 学术评审天然是一个多角色协作流程
学术评审这件事,本身就是个典型的多角色、多阶段、有明确输入输出的协作流程。一篇论文投出去,编辑先看格式和主题是否匹配,然后送给两个到三个审稿人,审稿人各自从创新性、实验设计、写作质量等维度提意见,最后编辑综合所有意见给出结论:接收、大修、小修还是拒稿。整个链条环环相扣,角色之间有明确分工,信息流转有清晰方向。
这就非常适合用来模拟 AI Agent 互动。因为每个角色都可以被建模成一个独立的 Agent:作者 Agent 负责生成论文摘要和回复意见,审稿人 Agent 负责阅读、质疑和打分,编辑 Agent 负责汇总、裁决和生成最终决定。这些 Agent 之间的交流方式,本质上是“传递信息 + 做出决策 + 反馈结果”,和真实世界的学术评审流程高度一致。
如果我只用一个独立的 Agent 去“生成一条学术评审意见”,那本质上只是一个高级一点的提示词模板,谈不上 Agent 互动。但当我拆成三个、四个甚至更多角色,让它们各自维护自己的上下文、各自调用工具、按顺序或按条件触发下一步,系统的复杂度就会立刻上来,前一个 Agent 的输出会直接影响后一个 Agent 的决策路径,这才是真正的多智能体协作。
1.2 从单 Agent 到多 Agent,互动的本质变了
单个 Agent 的逻辑非常简单:接收用户输入 → 调用模型推理 → 可能调用工具 → 输出结果。你不需要考虑“谁来触发”“信息怎么共享”“如果某个环节失败了怎么办”。
多 Agent 系统完全不是一回事。第一个变化是状态管理。多个 Agent 之间需要共享一份公共状态,比如论文全文、审稿意见列表、编辑裁决标记。第二个变化是流程控制。不再是一条直线走到底,而是有分支、有回环,比如编辑看了两个审稿人的意见后,如果意见冲突,可能要触发第三位审稿人。第三个变化是角色权限。作者 Agent 能不能直接修改论文?审稿人 Agent 能不能看到其他审稿人的意见?这些都要在设计时明确。
所以,做学术评审这个场景,表面上是写几个不同的提示词,实际上是在设计一个小型分布式协作系统。我甚至觉得,啃下这个场景之后,再去应对什么智能客服流转、工单自动分派、多部门审批自动化,几乎就是同一套方法论换个壳。
2. AI Agent 之间的四种主要互动模式
2.1 串行传递式:前一个 Agent 的输出是后一个 Agent 的输入
这是最简单也最直觉的互动方式。Agent A 完成自己的任务,把结果丢给 Agent B,Agent B 处理完再丢给 Agent C。整个系统像一条流水线,没有回头路。
放在学术评审里,串行模式长这样:作者 Agent 生成论文 → 审稿人 Agent 评审 → 编辑 Agent 汇总决策。每个环节只需要关心上游给自己的输入,不需要关心下游如何消费自己的输出。
优点非常明显:流程清晰、调试容易、每一步都能单独检查。缺点也很明显:没有反馈回路。如果审稿人 Agent 发现论文格式有问题,串行模式下它只能把这个意见传给编辑 Agent,不能直接让作者 Agent 重新修改。在某些简单场景下这样够了,但要实现更接近现实的学术评审,就得引入更灵活的互动方式。
2.2 中心编排式:一个主控 Agent 调度所有子 Agent
中心编排模式是实际项目里最常用的一种。一个 Orchestrator(编排者)Agent 负责拆解任务、派发给多个 Worker(执行者)Agent、收集结果、再进行下一步决策。
放在学术评审场景里,编辑 Agent 就是一个天然的主控角色。它负责拆解评审维度:这一个 Worker 专门看实验设计,那一个 Worker 专门看创新性;等所有 Worker 返回意见后,主控角色再做汇总。
中心编排式的核心优势是控制力强。主控 Agent 可以决定什么时候并行调用多个 Worker,可以根据部分返回结果随时调整后续流程。但它也有代价:主控 Agent 的提示词和逻辑最容易变成系统瓶颈,一旦编排指令不明确,下面的 Worker 就会各说各话。这也是为什么调研了 Agent 中台之后,我发现大部分商业化产品的底层编排逻辑都收敛到这种模式的原因——好理解,好兜底。
2.3 双向对话式:两个 Agent 角色反复博弈
双向对话式互动,指的是两个 Agent 之间不是一次性的输入输出,而是多轮往返的讨论。学术评审里最典型的就是作者 Agent 和审稿人 Agent 之间的 rebuttal(回复意见)环节。
作者 Agent 先提交一版回复,指出审稿人误解了某部分内容;审稿人 Agent 检查回复,要么接受解释,要么继续质疑;作者 Agent 再针对新的质疑补充说明。经过三五轮之后,双方才达成一个“审稿人与作者达成一致”的状态。
这种互动方式对上下文管理的要求最高。因为每一轮都要把历史对话记录全部带上,Token 消耗会随着轮数线性增长。在 LangChain 里可以用messages列表来维护讨论记录,在 LangGraph 里则可以把整个讨论历史存入共享的 state 字段,让它自动传递。
坦白说,这种模式做 Demo 很酷,真正放到生产环境却要注意控制轮数。我一般会设置一个最大轮数(比如 4 轮),超过之后强制让编辑 Agent 介入裁决,防止两个模型无限拉扯。
2.4 分层监督式:每个子流程都有自己的小主管
分层监督式可以理解为中心编排模式的升级版。不是一个大主管直接管所有执行者,而是先有几个中层主管,每个中层主管再带一组子 Agent。
在学术评审里,这个结构非常自然:主编 Agent 不直接面对每位审稿人,而是先分给领域编辑 Agent,领域编辑再把任务派给具体的审稿人 Agent。审稿人之间互不知晓,只向自己的领域编辑汇报。
优点在于职责隔离和信息封装。主编不需要关注论文的技术细节,只需要看到各领域编辑提交的汇总意见。缺点是流程变长、延迟变高,如果每一层都是大语言模型的推理调用,整个评审链路跑下来可能要消耗好几倍的 Token 和延迟。
下表把这四种模式的关键差异做了一个直观对比:
| 互动模式 | 信息流转方向 | 适合场景 | 主要弱点 | 在学术评审中的典型对应 |
|---|---|---|---|---|
| 串行传递式 | 单向流水线 | 流程固定、无需回溯 | 无法反馈修正 | 作者 → 审稿人 → 编辑 |
| 中心编排式 | 主控调度、星型分发 | 并行任务、动态决策 | 主控容易成为瓶颈 | 编辑分配多位审稿人 |
| 双向对话式 | 两两多轮往返 | 讨论、博弈、协商 | Token 消耗大、可能死循环 | 作者回复审稿人质疑 |
| 分层监督式 | 多层树状汇报 | 规模大、职责分明 | 链路长、延迟高 | 主编 → 领域编辑 → 审稿人 |
我做实际项目时的经验是:不要只选一种模式死磕到底。学术评审系统最理想的状态是混合模式,比如主流程用中心编排,遇到意见冲突时临时切换到双向对话,最后逐层汇总时用树状结构。
3. 核心细节解析:学术评审 Agent 系统怎么设计
3.1 角色定义与提示词设计
每个 Agent 本质上就是一个“角色 + 目标 + 边界”的提示词组合。学术评审系统里我通常会这样定义角色:
作者 Agent,目标是“向审稿人清晰解释论文的创新性和必要性”,边界是“不能修改论文正文,只能生成回复意见”。审稿人 Agent,目标是“从创新、实验、写作三个维度严格审查论文”,边界是“只负责提出质疑和得分,不决定论文是否接收”。编辑 Agent,目标是“综合所有意见给出最终决策”,边界是“必须在三个选项中选择一个:接收、修改、拒稿”。
提示词设计时最关键的是明确输出格式。我踩过不少坑,最后基本都会用结构化的输出约束。比如审稿人 Agent 的提示词里直接写死要求:
system_prompt = """ 你是《AI Agents 前沿》期刊的审稿人。 你的任务是对给定的论文进行严格评审。 输出内容必须严格使用如下 JSON 结构: { "summary": "论文内容概括,100字以内", "scores": {"innovation": 1-5, "experiment": 1-5, "writing": 1-5}, "questions": ["质疑点1", "质疑点2", "质疑点3"], "verdict": "major_revision / minor_revision / reject" } """结构化的好处有两个:一是后续 Agent 解析输出非常方便,不用从散文里抽取关键信息;二是模型为了输出合规 JSON,会不自觉地规整自己的推理内容,准确性反而更高。
3.2 公共状态与上下文流转
多 Agent 系统设计里最容易翻车的地方就是状态管理。学术评审这个场景涉及的信息维度很多:论文本身、各审稿人的打分、编辑的决策、讨论记录、最终意见。如果这些信息散落在各个 Agent 的内部上下文里,后续根本没法统一控制。
我参考了 LangGraph 里 StateGraph 的做法,定义了一个统一的评审状态对象:
from typing import Annotated, TypedDict import operator class ReviewState(TypedDict): paper: str # 论文全文 author_response: str # 作者对审稿意见的回复 reviews: Annotated[list, operator.add] # 各审稿人返回意见的聚合列表 discussion: Annotated[list, operator.add] # 作者与审稿人的多轮对话记录 final_decision: str # 最终录用决策这里有两个很妙的设计点。第一,reviews和discussion用operator.add作为归并函数,LangGraph 会把不同节点返回的新条目自动追加到列表里,不需要我手动维护整个历史。第二,paper和final_decision是普通字段,后写覆盖先写,适合存放全局唯一的快照信息。
上下文流转的原则是:每个 Agent 只取自己需要的字段,不要一股脑把所有历史对话都塞进去。编辑 Agent 不需要看作者和审稿人全部五轮讨论的原始内容,只需要看最终结论。所以我在给编辑 Agent 组装输入时,会做一个字段裁剪,大幅降低 Token 消耗。
3.3 工具调用:让 Agent 不只会“说”,还会“做”
学术评审如果只是让模型读文本、生成意见,那和前几年的大语言模型强提示词工程没什么区别。真正的 Agent 化,在于它能不能主动调用工具去影响环境。
我在原型的第二版里给审稿人 Agent 接了两类工具。第一类是检索工具,比如通过论文标题去搜索相关的已有工作,辅助判断该论文的创新性是否足够。用 LangChain 的Tool接口封装:
from langchain.tools import Tool def search_related_works(title: str) -> str: # 这里可以是真实调用学术搜索 API # 也可以是模拟返回几条相关论文标题 return f"与 '{title}' 相关的工作:<检索结果>" search_tool = Tool( name="search_related_works", description="当需要判断论文创新度时调用,输入为论文标题", func=search_related_works, )第二类工具是约束检查器,检查论文的格式要求、字数限制、图表是否齐全。这些看起来很基础,但正是让 Agent “不是光聊”的关键。
给 Agent 绑定工具时的注意事项是:工具描述要写得非常直白,最好说明“什么时候该调用、什么时候不该调用”。模型是根据描述来决定是否触发工具的,描述含糊会导致工具被滥用或完全不被调用。
3.4 与 FastAPI 集成:怎么扛并发
顺着搜索热词里大家关心的问题——“AI Agent 怎么扛并发”,我多聊几句。多 Agent 流程一旦跑起来,每一步都是真实的后端请求,如果直接同步执行,一个用户发起的一篇论文评审可能占住一个工作线程几十秒,基本没法用。
我的方案是两层解耦。第一层是FastAPI 层只做入口和状态登记,接到评审请求后立即生成一个review_id,把任务丢进 Celery / Redis Queue,立刻返回“评审进行中”。第二层是Worker 进程里跑完整的 LangGraph 流程,评审结束后把结果写回数据库。前端通过轮询review_id获取结果。
FastAPI 端口只需要一个轻量化接口:
from fastapi import FastAPI, BackgroundTasks from pydantic import BaseModel app = FastAPI() class ReviewRequest(BaseModel): paper_title: str paper_content: str @app.post("/review") async def start_review(req: ReviewRequest, background_tasks: BackgroundTasks): review_id = generate_id() background_tasks.add_task(run_review_pipeline, review_id, req.paper_content) return {"review_id": review_id, "status": "processing"}BackgroundTasks在轻量场景够用了,如果要更稳健的队列重试和任务优先级,就上 Celery。并发瓶颈通常不在 FastAPI 本身,而在大语言模型 API 的限流限制。应对的办法就是给每个 Agent 的调用加信号量或令牌桶限速,再配合指数退避重试。
4. 实操过程:从 0 到 1 搭建“三 Agent 学术评审”原型
4.1 环境准备与依赖安装
整个原型用 Python 3.11 开发,核心依赖是langchain、langgraph、fastapi、uvicorn,大模型接口先接一个通用的 OpenAI 兼容接口。第一步直接安装:
pip install langchain langgraph fastapi uvicorn[standard] openai建立一个项目目录和文件结构:
agent-review/ ├── main.py # FastAPI 入口 ├── state.py # 评审状态定义 ├── agents.py # 作者、审稿人、编辑 Agent 的定义 ├── graph.py # LangGraph 图结构编排 └── run.py # 本地直接调用的脚本入口4.2 顶层图结构设计
在 LangGraph 中,一个多 Agent 评审系统的核心图结构如下。整个流程分成四个关键节点:author_agent生成论文摘要、reviewer_agent评审并生成意见、author_rebuttal生成回复、editor_agent汇总决策。
from langgraph.graph import StateGraph, END def build_graph(): workflow = StateGraph(ReviewState) workflow.add_node("author_agent", author_agent) workflow.add_node("reviewer_agent", reviewer_agent) workflow.add_node("author_rebuttal", author_rebuttal) workflow.add_node("editor_agent", editor_agent) workflow.set_entry_point("author_agent") workflow.add_edge("author_agent", "reviewer_agent") workflow.add_edge("reviewer_agent", "author_rebuttal") workflow.add_edge("author_rebuttal", "editor_agent") workflow.add_edge("editor_agent", END) return workflow.compile()在 LangGraph 中,节点就是普通的函数,接收整个 state 作为输入,返回一个 dict 作为写入 state 的增量,所有字段变更都会自动合并。如果一个节点要提前终止,可以添加条件边,比如审稿人 Agent 给出reject时,跳过 author_rebuttal 直接到 editor_agent。
4.3 各个 Agent 节点的核心逻辑
首先看 author_agent。它负责把论文内容和标题整理成一个标准摘要,并生成一个“作者自证”的亮点说明:
def author_agent(state: ReviewState) -> dict: paper = state["paper"] prompt = f""" 你是论文作者。请基于论文内容: 1. 用150字以内概括论文核心贡献 2. 说明该工作的独特之处 返回格式:<summary>概括</summary><highlights>独特之处</highlights> 论文内容: {paper} """ response = call_llm(prompt) return {"author_response": response}reviewer_agent 是核心节点,它会读取论文内容和作者摘要,按审稿人提示词输出结构化意见,然后用自己的意见去触发一个工具调用,检查相关参考文献是否存在。
author_rebuttal 的逻辑很有意思。如果reviews中存在 “reject” 之外的质疑,它会逐条回应。这里的实现略去了复杂的提问描述,但实践中建议保留完整的质疑列表。
最后是 editor_agent。它会收到所有审稿意见和作者回复,输出最终决策,并把决策字符串写入state["final_decision"]。
4.4 一个可运行的完整调用链
正常情况下,四个节点串行执行就能输出一份模拟学术报告。下面是运行图的参考代码:
def run_pipeline(paper_content: str): graph = build_graph() config = {"recursion_limit": 20} init_state = {"paper": paper_content, "reviews": [], "discussion": []} result = graph.invoke(init_state, config) print("最终决策:", result["final_decision"]) return result if __name__ == "__main__": sample_paper = "本文提出一种基于多Agent协作的自动化论文评审框架..." run_pipeline(sample_paper)体验过整体链路之后,我的建议是:先跑通串行全流程,再迭代增加回环和并行节点。直接一步到位上复杂图结构,调试时很容易分不清是哪一步出了问题。就像我最初二版加入了对话回环,结果每次都因为上下文太长超时,把回环拆出来单独调试后才恢复正常。
4.5 Aware 处理并发的几个实践参数
如果你想在自己的服务里扛住真正的并发请求,几个关键参数值得记录。对于大模型 API 的调用,每秒钟最多发多少个请求,可以算出一个阀值;如果并发超过这个阀值,就需要排队而不是简单地放行。另一个重要参数是超时时间。一个评审流程里单次大模型调用我一般设 60 秒超时,整个图设 300 秒总超时,超过就降级为“评审超时,请稍后重试”。
并发上来以后还要注意,日志里必须带上review_id,否则多个任务同时跑,排查问题完全无从下手。每个节点开始和结束都打一行日志,记录当前 state 中的关键字段长度。
5. 常见问题与排查技巧实录
5.1 提示词脆弱性与角色漂移
多 Agent 系统最常见的问题就是“角色漂移”。审稿人 Agent 写着写着突然开始替编辑做决定,或者作者 Agent 回复意见时反过来批评审稿人水平太差。这是因为模型的角色约束不够强。
我的解决办法有两个。一是在系统提示词里反复强调边界,用类似“你是审稿人,只有编辑能做出最终接收决定”“你无权修改论文正文”这样的命令式语句;二是在每个节点的返回结构上做校验,比如审稿人 Agent 的返回里如果没有包含scores字段,就强制要求模型重新生成一次。实测下来,这边界的校验比提示词有效得多。
5.2 上下文爆炸与 Token 管理
学术评审场景特别容易积累长对话,尤其是作者回复审稿人意见这种多轮场景。每一轮都要带上之前的全部讨论,五轮下来一个节点就可能消耗上万 Token。
我试过几种办法,最终沉淀下来两招。第一是裁剪,给编辑 Agent 的输入只保留审稿意见的最终汇总,不保留原始讨论记录。第二是压缩,每轮讨论结束之后,增加一个专门的 summarize Agent,把该轮的关键结论压缩成三条以内。这两种方式配合使用之后,整个流程的 Token 消耗至少降了百分之四十。
5.3 模型幻觉与“像模像样的假评审”
大语言模型非常擅长生成看着头头是道、实际没有依据的批评。学术评审场景里这个问题尤其致命。审稿人可能提出“本文没有与 XX 方法对比”,但实际上论文里专门有一节做过这种对比。
针对这台幻觉问题,实操中我会给 reviewer_agent 接一个verify_statement工具,它会把每一条质疑意见先对照原文检索一遍,看论文中是否真的存在相关内容。如果存在,则自动修改质疑意见为“建议加强对比分析”之类更准确的表述。效果非常直观,评审意见的质量明显变好。
5.4 死循环与超时兜底
对话式 Agent 互动最容易踩的坑就是死循环。作者 Agent 和审稿人 Agent 理论上可以不间断地争论下去。哪怕我设置了最大轮数为 4,仍然可能因为某个节点的重试逻辑写得不严谨,出现无限循环。
经验是三重兜底。第一,在循环条件的出口加硬编码计数;第二,在图配置里设置recursion_limit;第三,在异步任务层加总超时,超过总超时直接杀掉任务。运行手册里永远要写一句话:多 Agent 流程必须有超时兜底,不然线上事故就是一瞬间的事。
5.5 排查问题的一线心得
排查多 Agent 系统的问题,最有效的工具不是单步 DeBugger,而是完整的中间过程日志。我会给每个 Agent 加一个debug=True开关,开启后把每个节点接收到的输入和输出的完整文本都落到日志文件里。排查时只看状态转换,就能发现是哪一步数据格式出错、哪一步上下文被污染。
还有一个实操心得:不要相信缓存也命中了就跳过调试。LangChain 自带InMemoryCache和 SQLite 缓存,调试阶段长期开着缓存会导致你改了提示词但跑出来的还是旧结果,排查思路直接跑偏。开发环境建议彻底关掉响应缓存。
6. 从“评审”到“中台”:多 Agent 系统的通用化
6.1 学术评审框架复用到其他业务场景
做完这个学术评审系统之后我发现,很多流程本质上都可以抽象成“具备不同专业背景的角色在一个公共状态下协作决策”的框架。比如工单流转:一线客服 Agent、技术专家 Agent、审批主管 Agent;比如内容审核:内容生成 Agent、初审 Agent、终审 Agent。学术评审只是这个通用框架的一个具体实例。
如果想把这个框架产品化,最简单的做法是定义一套“角色配置 + 图模板 + 状态 Schema”的组合,做成一个 Agent 中台。每一个新场景进来,只需要配置新的角色提示词、新的状态字段、新的流程模板,不用从头写一遍编排代码。
6.2 一个未来的扩展方向:评审结果的可解释性
学术评审相比普通自动化任务,有一个特别值得关注的需求是可解释性。编辑 Agent 给出拒稿决的时候,读者不仅要知道结果,还要知道依据是什么。我在系统里增加了一个结构,把编辑决策关联到具体审稿意见的 ID 上,这样输出结果时能做到“决策可溯源”。
这个思路同样适用于其他 Agent 协作场景,尤其是金融风控、医疗辅助这类高合规要求的领域。当多个 Agent 协作完成一个高风险决策时,系统必须能回答“为什么在这个环节做了这个决定”的问题。
做多 Agent 系统这么久,我最大的体会是:技术本身不难,难的是对“协作边界”的把握。每个 Agent 都太容易越界,太容易自信,所以主控者的任务不只是调度,还得不断校准它们的边界。学术评审这个场景给了我很完整的锻炼。如果你也想上手体验多 Agent 系统,我强烈建议从模仿一套真实的角色协作流程开始,别一上来就追求复杂算法,先把角色、状态和流程这三件事吃透,后面无论是做产品还是深入架构都会顺畅很多。