基于LangGraph构建多智能体协作系统:从任务拆解到报告生成
1. 项目概述:从单兵作战到团队协作的AI研究范式
最近在折腾一个挺有意思的东西:如何让多个AI智能体像一支训练有素的研究团队一样协同工作。这个想法的起点很简单,我们平时用ChatGPT或者Claude这类大模型,本质上是在和一个“全能但孤独”的专家对话。它能写代码、能分析、能总结,但一个复杂的研究任务,比如“深度调研某个新兴技术领域并产出结构化报告”,往往需要拆解、分工、交叉验证和整合。这让我开始思考,能不能用LangGraph这个工具,搭建一个多智能体协作系统,让不同的AI角色各司其职,共同完成一项研究。
这个项目的核心,就是构建一个由三个AI智能体组成的虚拟研究团队。它们不是简单的三个聊天机器人并行运行,而是通过一个有向图(Graph)来定义工作流,让信息、任务和决策在它们之间有序流转。想象一下,你有一个“研究主管”(Research Director),负责拆解任务和制定计划;一个“网络研究员”(Web Researcher),负责根据指令去互联网上爬取和筛选信息;还有一个“分析写作员”(Analyst & Writer),负责对获取的信息进行深度分析、交叉验证,并最终整合成一份高质量的报告。LangGraph的作用,就是为这三个角色搭建一个沟通协作的“办公室”和“工作流程看板”。
我选择LangGraph,是因为它本质上是一个用于构建有状态、多参与者应用的工作流库。它基于LangChain,但更专注于用“图”的思维来编排智能体之间的交互。每个智能体是一个节点(Node),节点之间的连线(Edge)定义了任务流转的条件和路径。这比写一堆复杂的if-else逻辑或者用队列来管理状态要清晰和强大得多。对于需要多步骤、有条件分支、甚至可能循环(比如“信息不足,需要再次搜索”)的研究任务来说,这种图结构再合适不过了。
2. 系统架构与智能体角色设计
2.1 为什么是三个智能体?角色分工的底层逻辑
在设计之初,我尝试过两个智能体(一个搜索,一个写作)和四个智能体(增加一个专门做数据清洗的),最终定稿为三个,这是基于任务复杂度和协作效率的平衡点。
研究主管(Director Agent) :这是整个系统的“大脑”和“项目经理”。它的核心职责是任务理解与规划。当你输入一个研究主题,比如“评估向量数据库Weaviate在2024年的技术优势与落地挑战”时,研究主管不会立刻去搜索。它会先进行思考拆解:这个主题可以分解为哪几个子问题?(例如:1. Weaviate的核心技术原理与最新版本特性;2. 与Pinecone、Chroma等竞品的对比维度;3. 在真实业务场景中的成功案例与遇到的典型问题;4. 社区生态与学习成本。)然后,它会生成一个初步的研究大纲和搜索查询词列表。这个智能体需要最强的逻辑分析和规划能力,我通常为它配置能力最强的模型(如GPT-4 Turbo),并赋予一个详细的系统提示词(System Prompt),明确其“指挥官”身份和思考框架。
网络研究员(Researcher Agent) :这是系统的“手和脚”,负责执行信息获取。它接收来自研究主管的、结构化的搜索指令(例如:“请搜索‘Weaviate vs Pinecone performance benchmark 2024’并获取前三篇相关技术博客或评测文章”)。这个智能体需要集成可靠的网络搜索工具。我使用的是Tavily Search API,因为它能直接返回结构化的搜索结果(包含标题、链接、摘要,甚至关键点提取),比单纯返回一堆链接更易于后续处理。研究员智能体的提示词会强调“准确性优先”、“来源甄别”(优先选择官方文档、知名技术社区、权威博客)和“信息摘要”,它不仅要获取链接,还要对每个结果进行一两句话的提炼。
分析写作员(Writer Agent) :这是系统的“心脏”,负责价值创造。它接收来自研究主管的大纲和来自网络研究员的信息碎片(摘要、链接)。它的工作不是简单拼接,而是真正的分析综合:对比不同来源的信息,识别共识与冲突点,评估信息的可信度,按照逻辑重新组织信息,并用专业、清晰的文字撰写成报告。这个智能体需要强大的推理和写作能力,同样会配置高性能模型。它的提示词会要求它注重“批判性思维”、“引用溯源”(在报告中注明关键论点的来源)和“结构化输出”(使用清晰的标题、列表和表格)。
注意 :三个智能体的模型配置可以相同,也可以不同。一个实用的技巧是,对“研究主管”和“分析写作员”使用更强大(也更贵)的模型,以确保规划和分析的质量;对“网络研究员”可以使用性价比更高的模型,因为它的任务相对标准化。这需要在成本与效果之间取得平衡。
2.2 LangGraph工作流编排:状态机与协作循环
LangGraph的核心是围绕一个共享的“状态”(State)字典来运作。在我的设计里,这个状态字典包含了整个研究任务的生命周期信息:
from typing import TypedDict, List, Annotated
import operator
class ResearchState(TypedDict):
# 初始输入
original_query: str
# 研究主管产出
research_plan: str
search_queries: List[str]
# 网络研究员产出
gathered_info: List[dict] # 每个元素包含‘url’, ‘title’, ‘summary’
# 分析写作员产出
analysis_report: str
# 用于控制流程的标志位
needs_refinement: bool # 报告是否需要进一步优化
refinement_feedback: str # 优化指令
工作流(Graph)的构建如下:
-
入口节点(Research Director Node) :工作流启动后,首先进入研究主管节点。该节点读取
original_query,调用研究主管智能体,生成research_plan和search_queries,并更新到状态中。 -
并行搜索节点(Parallel Research Node) :这是一个关键设计。研究主管可能生成多个搜索查询(比如“技术原理”、“竞品对比”、“案例”)。与其串行执行,不如让网络研究员并行处理所有查询。LangGraph支持“映射”(
map)操作,可以并发地对search_queries列表中的每个查询执行搜索子图,并将结果聚合到gathered_info列表中。这大大提升了信息收集的效率。 -
分析写作节点(Writer Node) :当所有并行搜索完成后,工作流进入分析写作节点。该节点接收完整的
research_plan和gathered_info,调用分析写作员智能体,生成初步的analysis_report。 -
质量检查与循环边(Quality Check Edge) :到这里,一个简单流程就结束了。但高质量的研究往往需要迭代。我设计了一个“质量检查”路由逻辑:在分析写作节点之后,并不直接结束,而是将状态传递给一个路由函数。这个函数可以是一个简单的规则(如“如果报告字数少于500字,则需细化”),也可以调用一个额外的“评审智能体”来评估报告完整性。如果评估认为报告需要改进,则将
needs_refinement设为True,并在refinement_feedback中填入修改意见(如“请更深入地对比A和B的查询延迟数据”)。然后,工作流会带着反馈意见, 重新跳转回研究主管或分析写作员节点 ,开启新一轮的细化循环。这个循环可以设定最大次数,避免无限循环。 -
结束节点(End Node) :当质量检查通过(
needs_refinement为False)或达到最大循环次数时,工作流进入结束节点,输出最终的analysis_report。
这个由节点和条件边构成的有向图,完美刻画了研究团队“规划->执行->分析->评审->再规划”的协作闭环。LangGraph自动负责在节点间传递和更新这个状态字典,开发者只需关注每个节点的业务逻辑和路由规则。
3. 核心实现细节与避坑指南
3.1 智能体提示词工程:塑造专业角色
智能体的能力边界和行为模式,极大程度上由系统提示词(System Prompt)决定。写一个好的提示词不是下指令,而是“雇佣”一个专家。
研究主管的提示词核心要素 :
- 角色定位 :“你是一位经验丰富的技术研究主管,擅长将模糊的需求转化为可执行的研究计划。”
- 任务拆解方法论 :明确要求其使用如“5W1H”(What, Why, Who, When, Where, How)或“背景-问题-方案-评估”等框架来分解问题。
- 输出格式指令 :严格要求其以特定JSON格式输出,包含
plan和queries两个字段,其中queries是一个搜索字符串列表。这便于后续程序化处理。 - 示例 :提供一个例子,展示如何将“云原生数据库趋势”拆解为计划和一个包含“云原生 database scalability 2024”、“serverless database pros and cons”等查询词的列表。
网络研究员的提示词核心要素 :
- 准确性要求 :“你提供的每一则信息摘要,都必须严格基于给定的搜索结果内容,不得编造或推断。”
- 来源评估 :“优先总结来自官方网站、GitHub仓库、知名技术媒体(如TechCrunch, The New Stack)或核心开发者博客的信息。”
- 摘要规范 :“用不超过两句话概括该结果的核心观点或事实,并保留关键数据(如版本号、性能指标)。”
分析写作员的提示词核心要素 :
- 综合与批判 :“你需要对比多个来源的信息。如果发现观点冲突,应在报告中指出,并尝试根据来源可信度进行分析。”
- 引用格式 :“在报告中,对于重要的结论或数据,使用上标标记来源序号,例如‘据报告[1]显示...’,并在报告末尾列出所有参考来源的标题和链接。”
- 结构化 :“报告必须包含摘要、核心内容(分小节论述)与总结三部分。核心内容部分使用二级标题,重要对比项使用表格呈现。”
实操心得 :提示词需要反复调试。一个有效的方法是,先用一个简单的任务跑通全流程,然后检查每个智能体的输出在哪里偏离了预期。常见问题包括:研究主管的查询词过于宽泛或狭窄;网络研究员摘要丢失关键信息;分析写作员忽略了信息冲突。针对性地修改提示词,加入更明确的约束或示例,效果立竿见影。
3.2 状态管理与信息流设计
状态字典的设计决定了工作流的灵活性与复杂度。初期我犯过一个错误:把所有的中间信息都塞进状态里,导致字典过于臃肿,且节点间依赖混乱。
清晰的状态划分 :
- 输入层 :
original_query。保持不变,作为溯源依据。 - 规划层 :
research_plan,search_queries。由研究主管产生,是后续所有节点的“蓝图”。 - 数据层 :
gathered_info。由网络研究员填充,是系统的“原材料仓库”。每个信息项应设计为结构体,例如{“query”: “用于搜索的查询词”, “url”: “…”, “title”: “…”, “content”: “…”},方便追溯和引用。 - 输出层 :
analysis_report。最终产物。 - 控制层 :
needs_refinement,refinement_feedback。用于控制循环的“开关”和“指令”。
信息流的单向性与可追溯性 :理想情况下,信息流应尽可能单向。例如, gathered_info 只由网络研究员节点写入,分析写作员节点只读取。这减少了状态冲突的可能。同时,在 gathered_info 中保留生成该信息的 query ,在 analysis_report 中要求标注引用来源序号,这些都极大地增强了最终报告的可解释性和可信度。
3.3 工具集成与异步处理优化
搜索工具的选择与封装 :Tavily API是个不错的选择,但直接将其调用写在智能体节点里会降低可维护性。更好的做法是抽象一个 SearchTool 类,封装API调用、错误处理、结果去重和基础清洗(如过滤掉明显是广告的链接)。然后将这个工具绑定到网络研究员智能体。这样,如果未来需要更换搜索API(比如用Serper或自定义的爬虫),只需修改这个工具类,智能体节点代码无需变动。
并行处理的实现 :利用LangGraph的 StateGraph 的 add_node 和 add_edge 构建主图,对于并行搜索,可以使用 langgraph.graph.StateGraph 的 add_conditional_edges 或更高级的 Pregel API中的并发原语。我的做法是,创建一个名为 parallel_research 的节点,在这个节点的函数内部,使用 asyncio.gather 并发地调用多个网络研究员子任务。这要求你的搜索工具函数是异步的( async ),或者使用线程池。并发数需要根据你使用的LLM API的速率限制和搜索API的配额来合理设置,通常3-5个并发查询是安全和高效的。
错误处理与重试机制 :网络请求和API调用总可能失败。必须在关键节点(尤其是网络研究员节点)添加健壮的错误处理。例如,使用 tenacity 库为搜索函数添加重试装饰器,当遇到网络超时或API限流时自动重试。对于重试后仍失败的单个查询,应在 gathered_info 中记录一个错误标记,而不是让整个工作流崩溃。分析写作员在生成报告时,可以提及“在查询X时未能获取到有效信息”,这比直接忽略或导致系统挂掉都要好。
4. 从搭建到调优:全流程实操记录
4.1 环境搭建与基础依赖安装
这个项目基于Python,核心库是 langgraph 和 langchain 。建议使用Python 3.10或以上版本,并创建一个新的虚拟环境。
# 创建并激活虚拟环境
python -m venv venv
source venv/bin/activate # Linux/macOS
# venv\Scripts\activate # Windows
# 安装核心库
pip install langgraph langchain langchain-openai langchain-community
# 安装搜索工具依赖(以Tavily为例)
pip install tavily-python
# 安装异步请求库(如果需要)
pip install aiohttp httpx
# 可选:用于更美观地打印状态
pip install rich
接下来,你需要准备API密钥。至少需要两类:
- LLM提供商API密钥 :如OpenAI的API Key。如果你使用Anthropic或Groq,则安装对应的LangChain集成包并获取相应密钥。
- 搜索API密钥 :如Tavily的API Key。去其官网注册即可获得免费额度。
将密钥设置在环境变量中是安全且方便的做法:
export OPENAI_API_KEY="sk-..."
export TAVILY_API_KEY="tvly-..."
# 或者在代码中通过os.environ设置
4.2 构建智能体与工作流代码实现
以下是一个高度精简但结构完整的核心代码框架,展示了如何将上述设计落地:
import os
from typing import TypedDict, List, Annotated
import operator
from langgraph.graph import StateGraph, END
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, SystemMessage
from langchain_core.output_parsers import JsonOutputParser
from pydantic import BaseModel, Field
import asyncio
from tavily import TavilyClient
# --- 1. 定义状态 ---
class ResearchState(TypedDict):
original_query: str
research_plan: str = “”
search_queries: List[str] = []
gathered_info: List[dict] = []
analysis_report: str = “”
needs_refinement: bool = False
refinement_feedback: str = “”
# --- 2. 定义智能体(简化版,实际应有更复杂的提示词)---
llm_gpt4 = ChatOpenAI(model=“gpt-4-turbo-preview”, temperature=0.2)
llm_gpt35 = ChatOpenAI(model=“gpt-3.5-turbo”, temperature=0.1)
class ResearchPlan(BaseModel):
plan: str = Field(description=“详细的研究计划”)
queries: List[str] = Field(description=“具体的搜索查询词列表”)
parser = JsonOutputParser(pydantic_object=ResearchPlan)
def create_director_agent(query: str) -> ResearchPlan:
system_prompt = “””你是一位技术研究主管...(详细提示词)...请以以下JSON格式输出:{format_instructions}“””.format(format_instructions=parser.get_format_instructions())
messages = [SystemMessage(content=system_prompt), HumanMessage(content=f“研究主题:{query}”)]
response = llm_gpt4.invoke(messages)
return parser.parse(response.content)
def research_director_node(state: ResearchState) -> dict:
“”“研究主管节点:生成计划和查询词。”“”
print(f“🧠 研究主管正在分析任务:{state[‘original_query’]}”)
plan_result = create_director_agent(state[‘original_query’])
return {
“research_plan”: plan_result.plan,
“search_queries”: plan_result.queries
}
async def async_search(query: str, tavily_client: TavilyClient) -> List[dict]:
“”“异步搜索函数。”“”
try:
results = tavily_client.search(query, max_results=3)
return [{“query”: query, “url”: r[“url”], “title”: r[“title”], “content”: r[“content”]} for r in results[“results”]]
except Exception as e:
print(f“搜索查询‘{query}’时出错:{e}”)
return []
async def parallel_research_node(state: ResearchState) -> dict:
“”“并行研究节点。”“”
queries = state[‘search_queries’]
print(f“🔍 网络研究员开始并行执行{len(queries)}个搜索查询...”)
tavily_client = TavilyClient(api_key=os.environ[“TAVILY_API_KEY”])
# 并发执行所有搜索
tasks = [async_search(q, tavily_client) for q in queries]
all_results = await asyncio.gather(*tasks)
# 扁平化结果列表
gathered_info = [item for sublist in all_results for item in sublist if item]
print(f“✅ 信息收集完成,共获得{len(gathered_info)}条信息片段。”)
return {“gathered_info”: gathered_info}
def analysis_writer_node(state: ResearchState) -> dict:
“”“分析写作节点。”“”
print(“✍️ 分析写作员开始整合报告...”)
plan = state[‘research_plan’]
info = state[‘gathered_info’]
# 构建给写作智能体的提示
writer_prompt = f“””基于以下研究计划和收集的信息,撰写一份详细的技术研究报告。
研究计划:{plan}
收集的信息:{info}
报告要求:结构清晰、论点有据、引用来源。报告末尾列出所有参考链接。“””
messages = [SystemMessage(content=“你是一位严谨的技术分析师...”), HumanMessage(content=writer_prompt)]
response = llm_gpt4.invoke(messages)
return {“analysis_report”: response.content}
def quality_check_router(state: ResearchState) -> str:
“”“质量检查路由:决定下一步是结束还是优化。”“”
report = state[‘analysis_report’]
# 这里可以实现更复杂的检查逻辑,比如调用另一个LLM评估报告质量
# 此处简化为:如果报告字数太少或包含‘需要更多信息’字样,则要求优化
if len(report) < 800 or “需要更多信息” in report:
print(“⚠️ 报告质量未达标,进入优化循环。”)
return “refine”
else:
print(“🎉 报告质量合格,流程结束。”)
return “end”
def refinement_node(state: ResearchState) -> dict:
“”“优化节点:根据反馈生成新的指令。”“”
# 这里可以是一个简单的规则,也可以调用一个“评审智能体”
feedback = “报告对技术原理的阐述深度不足,请补充更多关于架构细节的内容。”
return {
“needs_refinement”: True,
“refinement_feedback”: feedback,
“search_queries”: [state[‘original_query’] + “ architecture details”] # 生成新的搜索查询
}
# --- 3. 构建工作流图 ---
workflow = StateGraph(ResearchState)
# 添加节点
workflow.add_node(“director”, research_director_node)
workflow.add_node(“researcher”, parallel_research_node)
workflow.add_node(“writer”, analysis_writer_node)
workflow.add_node(“refiner”, refinement_node)
# 设置边
workflow.set_entry_point(“director”)
workflow.add_edge(“director”, “researcher”)
workflow.add_edge(“researcher”, “writer”)
# 条件边:从writer出来后,根据quality_check_router的结果决定去向
workflow.add_conditional_edges(
“writer”,
quality_check_router,
{
“end”: END,
“refine”: “refiner”
}
)
workflow.add_edge(“refiner”, “researcher”) # 优化后,重新进行研究
# 编译图
app = workflow.compile()
# --- 4. 运行工作流 ---
async def main():
initial_state = {“original_query”: “向量数据库Weaviate的核心技术优势与适用场景分析”}
# 注意:运行包含异步节点的图需要使用异步接口
async for step in app.astream(initial_state):
node_name = next(iter(step))
print(f”节点 ‘{node_name}’ 执行完成。”)
if __name__ == “__main__”:
asyncio.run(main())
这段代码勾勒出了整个系统的骨架。在实际开发中,你需要大幅充实每个智能体的提示词,完善错误处理,并可能增加更多节点(如一个专门格式化最终报告的“美化节点”)。
4.3 调试、评估与迭代优化
系统搭建完成后,真正的挑战才开始。你需要用一系列不同复杂度的问题去测试它。
常见问题与调试技巧 :
-
智能体偏离角色 :表现为研究主管生成的查询词不相关,或者分析写作员写起了诗歌。这是提示词不清晰导致的。 解决 :在提示词中强化角色指令,并使用“少样本学习”(Few-shot Learning),在提示词中提供1-2个完美的输入输出示例。
-
信息丢失或循环 :网络研究员返回的信息过于简略,导致分析写作员无料可写,质量检查路由不断触发优化循环。 解决 :首先检查搜索API返回的内容是否完整,可以打印出
gathered_info查看。其次,强化网络研究员提示词中的“摘要”要求,规定摘要必须包含核心事实和数据。最后,为质量检查路由设置最大循环次数(例如3次),避免无限循环。 -
上下文长度超限 :当收集的信息很多时,
gathered_info的文本长度可能超过LLM的上下文窗口。 解决 :实现一个“信息筛选”节点。在传递给分析写作员之前,先用一个智能体对gathered_info进行去重、排序和摘要,只保留与当前research_plan最相关的核心信息。或者,采用“分而治之”策略,让写作员先分部分撰写,再汇总。 -
成本与速度优化 :使用GPT-4运行整个流程成本较高且速度较慢。 优化 :a) 将模型分级,如前所述。b) 缓存(Cache)搜索结果和智能体响应。对于相同的搜索查询,直接使用缓存结果。LangChain提供了多种缓存集成。c) 优化提示词,让输出更简洁精准,减少不必要的token消耗。
评估方法 :
- 人工评估 :对输出报告的质量、相关性和结构进行评分。
- 自动化指标 :可以计算报告与收集信息之间的ROUGE分数(衡量内容覆盖度),或使用另一个LLM作为“裁判”,根据预设标准(如完整性、准确性、清晰度)对报告进行打分。
- 流程监控 :记录每个节点的执行时间、token消耗和API调用次数,用于性能分析和成本核算。
5. 进阶思考与应用场景拓展
构建一个基础可用的多智能体研究系统只是起点。在此基础上,有无数可以深化和扩展的方向:
智能体专业化与扩展 :目前的三个智能体是通用型的。你可以创建更专业化的智能体,例如:
- 学术论文研究员 :专门爬取和解析arXiv、Google Scholar的论文,理解其方法论和结论。
- 社交媒体感知员 :监测Twitter、Reddit、Hacker News上关于某个话题的讨论,捕捉技术趋势和社区情绪。
- 数据提取与可视化员 :从收集的信息中提取结构化数据(如性能对比表格),并生成图表描述代码(如Matplotlib或Plotly代码片段)。
动态工作流与决策 :当前的工作流是预定义的。更高级的系统可以根据任务难度动态调整流程。例如,对于简单查询,可能只需要“研究主管”->“分析写作员”两个节点;对于复杂任务,则自动启用包含并行搜索和多次评审的完整流程。这可以通过在“研究主管”节点评估任务复杂度,并动态修改后续的图路由来实现。
记忆与持续学习 :让系统拥有“记忆”。可以将每个项目的最终报告、中间产生的有价值信息(如精选的参考资料链接)存入一个向量数据库。当处理新任务时,先让“研究主管”在记忆库中进行相似性搜索,看看是否有历史经验可以借鉴,实现“越用越聪明”。
应用场景远不止技术调研 :
- 商业竞品分析 :输入竞争对手公司名,系统自动收集其产品动态、融资新闻、用户评价、招聘技术栈,产出竞品分析报告。
- 每日信息简报 :设定几个固定关注领域(如“AI安全”、“Web3监管”),系统每天自动运行,收集最新资讯并生成简报。
- 内容创作助手 :为视频博主或自媒体人工作。输入一个热点话题,系统负责收集背景资料、寻找争议点、提供正反方论据,甚至生成视频脚本大纲。
- 内部知识问答 :结合企业内部的文档库(通过RAG),当员工提出复杂问题时,系统可以协调多个智能体分别从不同文档库检索、综合信息,给出全面答案。
构建这样一个系统的过程,本身就是一个深刻理解AI智能体协作潜能的过程。它不再是一个简单的问答工具,而是一个可以定制、可以扩展、可以自动化的虚拟团队。你会发现,最大的挑战和乐趣,不在于编写调用API的代码,而在于设计智能体之间的协作协议、信息交换格式和决策逻辑——这本质上是在进行一种新型的软件架构设计。
更多推荐


所有评论(0)