本文将手把手带你用LangChain + LangGraph框架,构建一个功能完整的DeepResearch多智能体应用——输入一个研究主题,自动完成关键词规划、网络搜索、报告撰写全流程。
前言
自从OpenAI发布DeepResearch以来,"AI自动做研究"成为了最热门的应用方向之一。它的核心魅力在于:你只需提出一个问题,AI就能自动搜索互联网、整理信息、生成一份万字级别的研究报告。今天我们就用最简洁的代码,借助LangChain和LangGraph这两个主流框架,从零搭建一个Mini版的DeepResearch系统。全文代码不到200行,但涵盖了任务规划、工具调用、结构化输出、Pipeline串联等核心概念,非常适合入门学习。
一、先看效果
报告阶段:整合所有搜索结果,生成一篇结构完整、内容详实的中文Markdown研究报告最终输出的报告包含执行摘要、引言、五大场景分析、挑战与风险、未来展望和参考文献,篇幅超过3000字。
二、技术栈选型
| | |
|---|
| | LLM应用开发框架,提供Chain链式调用、Prompt模板等 |
| | Agent编排框架,使用其预构建API create_react_agent |
| | |
| | |
| | |
| | |
为什么选DeepSeek? 性价比高,中文能力强,API价格远低于GPT-4。为什么选Tavily? 专为AI Agent设计的搜索API,自带网页抓取和摘要功能。
三、架构设计:Pipeline-Agent模式
我们采用Pipeline-Agent(顺序管线)架构,将整个研究流程拆分为三个独立的智能体,按顺序依次执行:用户提问 → [规划Agent] → [搜索Agent x N] → [报告Agent] → 研究报告
三个Agent各干什么?
接收用户的原始问题,从多个角度拆解出5~7个搜索关键词。为什么不直接搜索原问题?因为单一查询容易结果同质化,无法支撑内容丰富、结构完整的长篇报告。通过多角度扩展,才能确保报告的覆盖度和深度。拿着关键词列表,逐个执行网络搜索。它借助LangGraph的create_react_agent,能够自主调用Tavily搜索工具、获取结果、提炼摘要。整合所有搜索摘要,先列大纲,再撰写完整的Markdown格式报告,输出不少于1500字的中文深度分析。
四、代码详解
Step 1:环境准备
DEEPSEEK_API_KEY=sk-你的deepseek密钥TAVILY_API_KEY=tvly-你的tavily密钥
pip install python-dotenv pydantic langchain-deepseek langchain langchain-core langgraph langchain-tavily
Step 2:导入依赖 & 初始化模型
import osfrom dotenv import load_dotenvfrom pydantic import BaseModelfrom langchain_deepseek import ChatDeepSeekfrom langchain_core.prompts import ChatPromptTemplatefrom langgraph.prebuilt import create_react_agentfrom langchain_tavily import TavilySearchload_dotenv(override=True)model = ChatDeepSeek( model_name='deepseek-chat', api_key=os.getenv(”DEEPSEEK_API_KEY”))
知识点:load_dotenv(override=True) 会自动读取 .env 文件中的环境变量,override=True 表示覆盖系统中已有的同名变量。
Step 3:任务规划Agent —— 用Pydantic约束LLM输出
这是本项目最值得学习的技巧之一:结构化输出(Structured Output)。定义搜索条目的数据模型class WebSearchItem(BaseModel): query: str# 搜索关键词 reason: str# 为什么这个搜索很重要# 定义搜索计划的容器class WebSearchPlan(BaseModel): searches: list[WebSearchItem]# 搜索列表# 规划提示词PLANNER_INSTRUCTIONS = ( ”You are a helpful research assistant. Given a query, come up with ” ”a set of web searches to perform to best answer the query. ” ”Output between 5 and 7 terms to query for.”)planner_prompt = ChatPromptTemplate.from_messages([ (”system”, PLANNER_INSTRUCTIONS), (”human”, ”{query}”)])# 关键:用 with_structured_output 约束LLM输出格式planner_chain = planner_prompt | model.with_structured_output(WebSearchPlan)
核心原理:with_structured_output(WebSearchPlan) 会告诉LLM:"你的输出必须严格符合 WebSearchPlan 这个JSON结构"。这样LLM返回的不再是自由文本,而是可以直接用Python操作的对象。Step 4:网络搜索Agent —— 用LangGraph的ReAct模式
SEARCH_INSTRUCTIONS = ( ”You are a research assistant. Given a search term, you search the web ” ”for that term and produce a concise summary of the results. ” ”The summary must be 2-3 paragraphs and less than 300 words. ” ”Capture the main points. Write succinctly.”)search_tool = TavilySearch(max_results=5, topic=”general”)使用预构建的ReAct Agentsearch_agent = create_react_agent( model, prompt=SEARCH_INSTRUCTIONS, tools=[search_tool])
核心原理:create_react_agent 实现了经典的Reasoning + Acting循环:LLM思考 → 调用Tavily搜索 → 获取结果 → 继续思考 → 生成摘要
整个过程完全自主,你不需要手写工具调用的循环逻辑。Step 5:报告生成Agent
WRITER_PROMPT = ( ”You are a senior researcher tasked with writing a cohesive report. ” ”First come up with an outline, then generate the full report. ” ”Output in markdown format, at least 1500 words. 最终报告采用中文输出.”)class ReportData(BaseModel): short_summary: str报告摘要 markdown_report: str# 完整报告 follow_up_questions: list[str]# 后续研究建议writer_prompt = ChatPromptTemplate.from_messages([ ('system', WRITER_PROMPT), ('human', '{query}')])writer_chain = writer_prompt | model.with_structured_output(ReportData)
Step 6:串联全流程
def deepresearch(query: str): ”””输入研究主题,自动完成搜索规划、搜索和报告撰写”””第一步:规划搜索关键词 print('[1/3] 正在规划搜索关键词...') search_plan = planner_chain.invoke({'query': query}) print(f'[1/3] 规划完成,共 {len(search_plan.searches)} 个搜索主题')# 第二步:逐个执行搜索 print('[2/3] 正在执行网络搜索...') search_results = [] for item in search_plan.searches: result = search_agent.invoke({”messages”: [ {”role”: ”user”, ”content”: f”Search: {item.query}\nReason: {item.reason}”} ]}) search_results.append(str(result['messages'][-1].content)) print(f'[2/3] 搜索完成,获得 {len(search_results)} 条结果')# 第三步:生成报告 print('[3/3] 正在生成研究报告...') all_results = '\n'.join(search_results) final_query = f'Original query: {query}\nResearch results: {all_results}' report = writer_chain.invoke({'query': final_query}) print(report.markdown_report)# 运行!deepresearch('AI在教育方面的应用场景')
五、六大核心知识点总结
1. LCEL链式组合
chain = prompt | model.with_structured_output(OutputModel)
用 | 管道符把组件串成一条链,是LangChain最核心的编程范式。2. Pydantic结构化输出
通过 BaseModel 定义数据模型 + with_structured_output() 约束,让LLM输出从"自由文本"变为"结构化对象",可直接用 .field_name 访问字段。3. ReAct Agent预构建图
create_react_agent 一行代码创建具备"思考-行动-观察"循环能力的Agent,自动完成工具调用。4. Prompt分层设计
三套Prompt各司其职,互不干扰。每套Prompt都精确约束了输出格式、长度和语言,这是Prompt Engineering的最佳实践。5. 降级容错策略
当结构化输出解析失败时,自动降级为非结构化调用,保证系统可用性。这是真实工程场景中的必备技巧。6. Pipeline函数职责分离
每个函数只做一件事:plan_searches、search、perform_searches、write_report,便于单独测试和替换。
六、踩坑记录
| | |
|---|
ModuleNotFoundError: langchain.prompts | | 改用 from langchain_core.prompts import ChatPromptTemplate |
| DeepSeek在长文本输出时JSON Schema遵循不够严格 | |
create_react_agent | LangGraph V1.0+ 已将其迁移至 langchain.agents | 可改用 from langchain.agents import create_agent |
七、后续优化方向
引入LangGraph StateGraph:当前用的是纯Python函数串联,后续可升级为有状态的图编排,支持条件分支和循环并行搜索:当前7个关键词是串行搜索,可以用 asyncio 并行执行,大幅提速增加反思环节:让Agent对搜索结果进行质量评估,不够好就重新搜索报告分段生成:将长报告拆分为多个章节分别生成,避免单次输出过长导致质量问题
写在最后
这个项目虽然代码量不大,但麻雀虽小、五脏俱全。它完整展示了如何从零构建一个多智能体协作系统,涵盖了规划、工具调用、结构化输出、Pipeline编排等AI Agent开发的核心能力。无论你是刚接触LangChain/LangGraph的新手,还是想快速搭建DeepResearch类应用的开发者,都可以从这个项目中获得启发。完整代码已开源,关注公众号回复"DeepResearch"获取源码。
如果本文对你有帮助,欢迎点赞、在看、转发三连,你的支持是我持续创作的最大动力!