高级Agent架构------Plan-and-Execute与Multi-Agent
作者 :Weisian
发布时间:2026年3月

直击痛点:
"让单Agent完成'写一份2026年AI行业研报,先收集数据、再分析趋势、最后生成可视化图表并审核'这样的复杂任务,它要么步骤混乱,要么遗漏关键环节,甚至在某个子任务上卡死------难道单Agent只能处理简单任务?想让多个Agent分工协作,却不知道如何设计通信机制和状态共享,难道只能用一堆零散的Agent代码硬拼?"
当你试图让Agent解决多步骤、多角色、长周期的复杂任务时,单Agent的局限性暴露无遗:它就像一个"全能但精力有限"的员工,面对多线程工作容易顾此失彼,缺乏专业分工带来的效率和质量保障。
想象一下:你要完成一份行业研报,只雇佣了一个"全能员工"(单Agent):
- 他既要做数据收集(研究员),又要做分析写作(作家),还要做质量审核(审核员);
- 他可能在收集数据时就偏离方向,或者写完内容忘记审核;
- 他无法并行处理任务,整体效率极低。
而如果你组建了一个项目组(Multi-Agent):
- 研究员Agent:专注收集和整理行业数据;
- 作家Agent:基于数据撰写研报正文;
- 审核员Agent:检查内容准确性和格式规范;
- 项目经理Agent:拆解任务、分配角色、协调进度。
这一切的破局点,在于高级Agent架构------Plan-and-Execute让单Agent具备"项目规划"能力,Multi-Agent让多个Agent像项目组一样分工协作,而LangGraph则是串联这一切的"协作中枢"。
- Plan-and-Execute:先规划后执行,把"想"和"做"分离。就像项目经理先画出流程图,再分派给执行团队;
- Multi-Agent:角色分工协作,研究员负责查资料,作家负责写报告,审核员负责把关。就像真正的项目组,各司其职;
- LangGraph:新一代 Agent 编排框架,用"图"结构管理复杂的多步流程。让 Agent 之间的通信不再混乱,状态不再丢失;
- 面试高频问:"单 Agent 有什么局限?Plan-and-Execute 如何解决?""LangGraph 的核心概念是什么?""如何实现多 Agent 协作?"------答不上来=错失高薪 offer。
本文将从认知入门 →核心原理 →组件拆解 →实战落地 →避坑指南 →面试考点 的逻辑层层递进,彻底讲透高级Agent架构的底层逻辑:
✅ 用"项目组"类比,秒懂Multi-Agent的核心价值;
✅ 图解Plan-and-Execute完整工作流,看懂规划与执行分离的优势;
✅ 实战演示:基于LangGraph构建能自动撰写行业研报的Multi-Agent系统(附完整可运行代码);
✅ 深入解析LangGraph的State、Nodes、Edges核心概念;
✅ 避坑指南:新手在复杂Agent架构中最容易踩的6个陷阱;
✅ 【面试高频】Plan-and-Execute相比纯ReAct的核心优势。
📌 核心一句话 :
高级Agent架构的本质是**"任务拆解+角色分工+状态管理"** 的闭环------Plan-and-Execute解决"做什么步骤"的问题,Multi-Agent解决"谁来做"的问题,LangGraph解决"怎么做、如何协作"的问题,最终让Agent系统具备处理企业级复杂任务的能力。
📌 高级Agent金句先记牢:
- 核心类比:单Agent = 全能但低效的员工,Multi-Agent = 分工协作的项目组;
- Plan-and-Execute:Planner(规划器)负责拆解任务,Executor(执行器)负责执行子任务 → 想与做分离;
- 生活类比:单 Agent = 全能员工(什么都会但不精),Plan-and-Execute = 项目经理+执行团队,Multi-Agent = 项目组(研究员+作家+审核员);
- LangGraph核心:State(共享状态)、Nodes(节点,每个 Agent 或工具)、Edges(边,决定下一步)、Conditional Edges(条件分支);
- Multi-Agent通信:消息传递 = 项目组开会,状态共享 = 共享文档库;
- Human-in-the-loop:关键节点人工确认 = 项目评审会,避免 Agent 自作主张;
- 核心价值:从"单任务执行者"升级为"复杂项目协作系统";
- Plan-and-Execute vs ReAct:前者先定全局计划再执行,后者走一步看一步,前者更适合复杂任务。
一、认知入门:为什么需要高级Agent架构?
1.1 单Agent的"能力天花板"
如果你用纯ReAct范式的单Agent处理复杂任务,会发现四个致命问题:
- 规划能力弱:面对多步骤任务,无法制定全局计划,容易走一步看一步;
- 角色混淆:既要做规划又要做执行,既要做专业工作又要做审核,专业性不足;
- 容错性差:某个步骤出错会导致整个任务中断;
- 效率低下:无法并行处理任务,只能串行执行。
想象一家公司的"全能员工"小李:
- 老板说:"帮我写一份 AI 芯片行业研报。"
- 小李开始思考:先查资料 → 分析数据 → 写报告 → 审核。但问题来了:
- 长程规划弱:查着查着资料,忘了要分析什么数据;
- 记忆负担重:查了 20 个网页,记不住前面的关键信息;
- 分工不明确:既要查资料又要写报告,效率低下。
单 Agent 的 ReAct 架构在处理简单任务时游刃有余,但面对需要 10+ 步的复杂任务,就容易"跑偏"------因为它每步都要重新思考,缺乏全局规划。

python
# ❌ 单Agent处理复杂任务的能力盲区演示(基于本地Ollama)
from langchain_ollama import ChatOllama
from langchain_core.tools import tool
from langchain_classic.agents import create_tool_calling_agent, AgentExecutor
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
import warnings
warnings.filterwarnings('ignore')
# 初始化LLM
llm = ChatOllama(
model="qwen2_5-7b-q6",
base_url="http://localhost:11434",
temperature=0.1
)
# 定义简单工具
@tool
def collect_data(topic: str) -> str:
"""收集指定主题的行业数据"""
return f"{topic}行业数据:2026年市场规模预计增长20%,头部企业占比60%"
@tool
def write_report(data: str) -> str:
"""基于数据撰写行业研报"""
return f"### {data.split(':')[0]}行业研报\n{data}\n(正文内容省略)"
@tool
def review_report(report: str) -> str:
"""审核研报内容"""
return f"审核结果:{report[:50]}... 内容完整,数据准确,格式规范"
tools = [collect_data, write_report, review_report]
# 创建Prompt
prompt = ChatPromptTemplate.from_messages([
("system", "你需要完成撰写行业研报的任务,步骤:1.收集数据 2.撰写报告 3.审核报告"),
("user", "{input}"),
MessagesPlaceholder(variable_name="agent_scratchpad"),
])
# 创建单Agent
agent = create_tool_calling_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True, max_iterations=5)
# 执行复杂任务
print("单Agent执行复杂任务:")
try:
result = agent_executor.invoke({"input": "帮我写一份2026年AI行业研报"})
print(f"最终结果:{result['output']}")
except Exception as e:
print(f"执行出错:{str(e)}")
运行结果问题分析:
- 单Agent可能跳过审核步骤直接输出结果;
- 可能在收集数据后忘记撰写报告;
- 无法并行处理,整体执行效率低;
- 缺乏专业分工,报告质量难以保证。
问题根源:单Agent就像一个"一人公司",面对需要多角色协作的复杂任务,既缺乏全局规划能力,又没有专业分工带来的效率和质量保障。
1.2 高级Agent架构的核心价值:从"个人英雄"到"团队协作"
| 架构类型 | 类比 | 核心特点 | 适用场景 |
|---|---|---|---|
| 纯ReAct单Agent | 全能个人英雄 | 走一步看一步,无明确规划 | 简单单步/少步骤任务 |
| Plan-and-Execute单Agent | 有规划的个人执行者 | 先制定计划,再逐步执行 | 中等复杂度、步骤明确的任务 |
| Multi-Agent(多智能体) | 分工协作的项目组 | 多角色分工,并行处理,状态共享 | 高复杂度、多角色、长周期任务 |
核心结论 :高级Agent架构是Agent从"玩具"走向"生产力工具"的关键,80%的企业级复杂自动化场景都需要Plan-and-Execute或Multi-Agent架构支撑。
1.3 生活类比:项目组是如何工作的?
想象你要完成一份行业研报,组建了一个项目组:
-
项目经理(Planner):
- 拆解任务:"1.收集AI行业数据 2.撰写研报正文 3.审核报告内容 4.输出最终版本";
- 分配角色:研究员负责数据收集,作家负责撰写,审核员负责质量检查;
- 制定时间表:明确每个步骤的交付时间和依赖关系。
-
研究员(Executor/Agent1):
- 执行数据收集任务,整理成结构化数据;
- 将结果提交给项目经理和作家。
-
作家(Executor/Agent2):
- 基于研究员提供的数据撰写研报;
- 完成后提交给审核员。
-
审核员(Executor/Agent3):
- 检查报告的准确性、完整性和格式规范;
- 提出修改意见,作家修改后再次审核。
-
项目经理:
- 监控整个流程,协调各角色工作;
- 处理异常情况(如数据收集失败);
- 最终汇总所有结果,输出完整研报。
这就是高级Agent架构的工作流程:规划 → 分工 → 执行 → 协作 → 审核 → 交付。
二、核心原理:Plan-and-Execute架构(先规划后执行)
2.1 什么是Plan-and-Execute?
Plan-and-Execute 是一种高级Agent架构,核心思想是将Agent的能力拆分为两个独立模块:
- Planner(规划器):负责拆解复杂任务,制定详细的执行计划;
- Executor(执行器):负责执行规划器制定的每一个具体步骤。
这种"规划与执行分离"的设计,解决了纯ReAct Agent"走一步看一步"的局限性,让Agent具备全局规划能力。

传统 ReAct:思考→行动→观察→思考→行动→观察→...(每步都要思考)
Plan-and-Execute:
1. Planner(规划器):一次性规划所有步骤
2. Executor(执行器):按顺序执行每个步骤
3. 每步执行后观察结果,继续下一步
否
是
用户复杂指令
更新计划(如有必要)
生成详细执行计划
Executor 执行器
执行步骤1
执行步骤2
执行步骤3
所有步骤完成?
汇总结果生成最终回答
返回给用户
生活类比(项目经理+执行员工):
- Planner(项目经理):接到"组织公司年会"任务后,拆解为"确定时间地点→邀请嘉宾→布置场地→安排流程→执行活动→总结复盘";
- Executor(执行员工):按照计划逐一执行每个步骤,遇到问题反馈给项目经理调整计划;
- 最终交付:所有步骤完成后,项目经理汇总结果,确保年会顺利举办。
2.2 Plan-and-Execute核心组件拆解
| 组件 | 类比 | 核心功能 | 关键实现 |
|---|---|---|---|
| Planner(规划器) | 项目经理 | 拆解任务、制定步骤、处理异常 | LangChain的load_chat_planner、自定义规划Prompt |
| Executor(执行器) | 执行员工 | 执行具体步骤、调用工具、返回结果 | LangChain的load_agent_executor、Tool Calling Agent |
| Plan Validator(计划验证器) | 项目评审 | 检查计划的可行性、完整性 | 自定义LLM验证逻辑 |
| Feedback Loop(反馈循环) | 进度汇报 | 执行结果反馈给规划器,动态调整计划 | 循环调用逻辑 |
2.3 Plan-and-Execute完整代码演示
python
# Plan-and-Execute架构完整实现(适配LangChain 1.2.10 + 本地Ollama)
from langchain_ollama import ChatOllama
from langchain_core.tools import tool
from langchain_core.prompts import ChatPromptTemplate
from langchain_experimental.plan_and_execute import (
PlanAndExecute,
load_chat_planner,
load_agent_executor
)
from langchain_core.tools import Tool
from typing import List, Dict, Any
import warnings
warnings.filterwarnings('ignore')
# ===================== 全局变量(存储中间结果) =====================
# 用全局变量保存关键数据,避免步骤间参数传递错误
global_data_store = {
"industry_data": "",
"industry_report": "",
"review_result": ""
}
# ===================== 1. 初始化核心组件 =====================
print("="*60)
print("Plan-and-Execute架构完整演示")
print("="*60)
# 1.1 初始化LLM
llm = ChatOllama(
model="qwen2_5-7b-q6",
base_url="http://localhost:11434",
temperature=0.1,
num_ctx=8192
)
print("✅ LLM初始化完成(Qwen2.5)")
# 1.2 定义专业工具集
@tool
def collect_industry_data(industry: str, year: str) -> str:
"""
收集指定行业指定年份的详细数据(结果会自动保存到全局存储)
参数:
industry: 行业名称,如"AI"、"新能源"
year: 年份,如"2026"
返回:
包含市场规模、增长率、头部企业、发展趋势的结构化数据
"""
# 模拟真实数据收集(实际项目可替换为API调用)
data = {
"AI": {
"2026": {
"market_size": "1.2万亿元",
"growth_rate": "25%",
"key_companies": "字节跳动、百度、阿里、腾讯",
"trends": "大模型应用落地、Agent架构普及、行业垂直解决方案增多"
}
},
"新能源": {
"2026": {
"market_size": "5.8万亿元",
"growth_rate": "18%",
"key_companies": "比亚迪、宁德时代、特斯拉",
"trends": "固态电池商业化、智能驾驶普及、海外市场扩张"
}
}
}
if industry in data and year in data[industry]:
info = data[industry][year]
result = f"""【{year}年{industry}行业数据】
1. 市场规模:{info['market_size']}
2. 年增长率:{info['growth_rate']}
3. 头部企业:{info['key_companies']}
4. 发展趋势:{info['trends']}"""
# 核心:保存到全局存储
global_data_store["industry_data"] = result
return result
else:
result = f"暂未收集到{year}年{industry}行业的数据"
global_data_store["industry_data"] = result
return result
@tool
def write_industry_report(use_saved_data: bool = True) -> str:
"""
基于已收集的行业数据撰写专业研报(默认使用全局存储中的数据)
参数:
use_saved_data: 是否使用已保存的行业数据(固定为True即可)
返回:
结构化的行业研报内容(markdown格式)
"""
# 核心:直接从全局存储读取数据,避免外部传入错误格式
data = global_data_store.get("industry_data", "")
if not data:
return "错误:尚未收集行业数据,请先调用collect_industry_data工具"
if not data.startswith("【") or "市场规模:" not in data:
return f"""# 行业研报生成失败
## 错误原因
已保存的数据格式不正确
## 已保存数据内容
{data}"""
# 安全解析数据
lines = [line.strip() for line in data.split('\n') if line.strip()]
try:
title = lines[0].replace("【", "").replace("】", "")
# 提取核心数据
market_size = ""
growth_rate = ""
key_companies = ""
trends = ""
for line in lines[1:]:
if "市场规模:" in line and ":" in line:
market_size = line.split(":")[1]
elif "年增长率:" in line and ":" in line:
growth_rate = line.split(":")[1]
elif "头部企业:" in line and ":" in line:
key_companies = line.split(":")[1]
elif "发展趋势:" in line and ":" in line:
trends = line.split(":")[1]
# 生成研报
report = f"""# {title}行业研报
## 一、核心数据
1. 市场规模:{market_size}
2. 年增长率:{growth_rate}
3. 头部企业:{key_companies}
## 二、发展趋势分析
{trends}
## 三、投资建议
1. 重点关注{key_companies.split('、')[0] if key_companies and '、' in key_companies else '头部'}等头部企业
2. 布局{trends.split('、')[0] if trends and '、' in trends else '核心'}相关领域
3. 长期看好行业增长潜力,建议分批布局
## 四、风险提示
1. 行业竞争加剧风险
2. 技术迭代不及预期风险
3. 政策监管变化风险
"""
# 保存研报到全局存储
global_data_store["industry_report"] = report
return report
except Exception as e:
error_msg = f"""# 行业研报生成失败
## 错误信息
{str(e)}
## 已保存数据
{data}"""
global_data_store["industry_report"] = error_msg
return error_msg
@tool
def review_report(use_saved_report: bool = True) -> str:
"""
审核已生成的行业研报(默认使用全局存储中的研报)
参数:
use_saved_report: 是否使用已保存的研报(固定为True即可)
返回:
审核结果和修改建议
"""
# 核心:从全局存储读取研报
report = global_data_store.get("industry_report", "")
if not report:
return "❌ 审核不通过:尚未生成研报,请先调用write_industry_report工具"
# 审核逻辑
issues = []
if "市场规模" not in report:
issues.append("缺少市场规模数据")
if "发展趋势" not in report:
issues.append("缺少趋势分析")
if "风险提示" not in report:
issues.append("缺少风险提示")
if "投资建议" not in report:
issues.append("缺少投资建议")
# 保存审核结果
if issues:
global_data_store["review_result"] = f"❌ 审核不通过:{'; '.join(issues)}"
return global_data_store["review_result"]
else:
global_data_store["review_result"] = "✅ 审核通过:研报内容完整、结构清晰、数据准确"
return global_data_store["review_result"]
@tool
def get_final_result() -> str:
"""
获取最终的完整结果(包含数据、研报、审核结果)
参数: 无
返回:
整合后的最终结果
"""
# 整合所有结果
final_result = f"""# 2026年AI行业研报(最终版)
## 数据收集结果
{global_data_store.get('industry_data', '未收集到数据')}
## 完整研报内容
{global_data_store.get('industry_report', '未生成研报')}
## 审核结果
{global_data_store.get('review_result', '未审核')}
---
✅ 任务完成:已完成2026年AI行业研报的收集、撰写、审核全流程
"""
return final_result
# 重新定义工具列表(使用修改后的工具)
tools = [
collect_industry_data,
write_industry_report,
review_report,
get_final_result # 获取最终结果的工具
]
print("✅ 专业工具集初始化完成")
# ===================== 2. 创建Plan-and-Execute Agent =====================
print("\n===== 创建Plan-and-Execute Agent =====")
# 2.1 创建规划器(适配LangChain 1.2.10)
planner = load_chat_planner(llm)
print("✅ 规划器(Planner)创建完成 - 相当于项目经理")
# 2.2 创建执行器(适配LangChain 1.2.10)
executor = load_agent_executor(
llm,
tools,
verbose=False
)
print("✅ 执行器(Executor)创建完成 - 相当于执行员工")
# 2.3 组合成Plan-and-Execute Agent
agent = PlanAndExecute(
planner=planner,
executor=executor,
verbose=True
)
print("✅ Plan-and-Execute Agent创建完成")
# ===================== 3. 执行复杂任务 =====================
print("\n" + "="*60)
print("执行复杂任务:撰写2026年AI行业研报")
print("="*60)
# 优化任务描述,适配新的工具参数
complex_task = """请完成2026年AI行业研报的撰写工作,严格按以下步骤执行:
1. 调用collect_industry_data工具,参数:industry="AI",year="2026"
2. 调用write_industry_report工具,参数:use_saved_data=True(无需传入数据,工具会自动使用已保存的数据)
3. 调用review_report工具,参数:use_saved_report=True(无需传入研报,工具会自动使用已保存的研报)
4. 调用get_final_result工具,获取最终的完整结果
5. 输出get_final_result工具返回的内容作为最终答案"""
try:
# 执行Agent
result = agent.run(complex_task)
# 输出最终结果
print("\n" + "="*60)
print("📋 Plan-and-Execute最终执行结果:")
print("="*60)
print(result)
# 额外:直接打印全局存储中的完整研报
print("\n" + "="*60)
print("📝 提取的完整研报内容:")
print("="*60)
print(global_data_store.get("industry_report", "未生成研报"))
except Exception as e:
print(f"\n❌ 执行出错:{str(e)}")
import traceback
traceback.print_exc()
print("\n✅ Plan-and-Execute演示完成")
运行结果:
============================================================
Plan-and-Execute架构完整演示
============================================================
✅ LLM初始化完成(Qwen2.5)
✅ 专业工具集初始化完成
===== 创建Plan-and-Execute Agent =====
✅ 规划器(Planner)创建完成 - 相当于项目经理
✅ 执行器(Executor)创建完成 - 相当于执行员工
✅ Plan-and-Execute Agent创建完成
============================================================
执行复杂任务:撰写2026年AI行业研报
============================================================
> Entering new PlanAndExecute chain...
steps=[Step(value='调用collect_industry_data工具,参数:industry="AI",year="2026"\r'), Step(value='调用write_industry_report工具,参数:use_saved_data=True\r'), Step(value='调用review_report工具,
参数:use_saved_report=True\r'), Step(value='调用get_final_result工具,获取最终的完整结果\r'), Step(value='输出get_final_result工具返回的内容作为最终答案\r\n')]*****
Step: 调用collect_industry_data工具,参数:industry="AI",year="2026"
Response: # 2026年AI行业研报(最终版)
## 数据收集结果
【2026年AI行业数据】
1. 市场规模:1.2万亿元
2. 年增长率:25%
3. 头部企业:字节跳动、百度、阿里、腾讯
4. 发展趋势:大模型应用落地、Agent架构普及、行业垂直解决方案增多
## 完整研报内容
# 2026年AI行业数据行业研报
## 一、核心数据
1. 市场规模:1.2万亿元
2. 年增长率:25%
3. 头部企业:字节跳动、百度、阿里、腾讯
## 二、发展趋势分析
大模型应用落地、Agent架构普及、行业垂直解决方案增多
## 三、投资建议
1. 重点关注字节跳动等头部企业
2. 布局大模型应用落地相关领域
3. 长期看好行业增长潜力,建议分批布局
## 四、风险提示
1. 行业竞争加剧风险
2. 技术迭代不及预期风险
3. 政策监管变化风险
## 审核结果
✅ 审核通过:研报内容完整、结构清晰、数据准确
---
✅ 任务完成:已完成2026年AI行业研报的收集、撰写、审核全流程*****
Step: 调用write_industry_report工具,参数:use_saved_data=True
Response: 已成功生成2026年AI行业的专业研报,内容包括市场规模、增长率、头部企业及发展趋势分析等。*****
Step: 调用review_report工具,参数:use_saved_report=True
Response: 已成功生成并审核通过2026年AI行业的专业研报,内容涵盖了市场规模、增长率、头部企业及发展趋
势分析等关键信息。报告结构清晰,数据准确,并得到了专业的审核确认。*****
Step: 调用get_final_result工具,获取最终的完整结果
Response: I know what to respond
Action:
``{
"action": "Final Answer",
"action_input": "最终结果包括2026年AI行业的市场规模为1.2万亿元,年增长率为25%,头部企业有字节跳动
、百度、阿里和腾讯。发展趋势包括大模型应用落地、Agent架构普及以及行业垂直解决方案增多。此外,报告还
提供了投资建议和风险提示,并已通过专业审核。"
}```*****
Step: 输出get_final_result工具返回的内容作为最终答案
Response: 最终结果包括2026年AI行业的市场规模为1.2万亿元,年增长率为25%,头部企业有字节跳动、百度、
阿里和腾讯。发展趋势包括大模型应用落地、Agent架构普及以及行业垂直解决方案增多。此外,报告还提供了投
资建议和风险提示,并已通过专业审核。
> Finished chain.
============================================================
📋 Plan-and-Execute最终执行结果:
============================================================
最终结果包括2026年AI行业的市场规模为1.2万亿元,年增长率为25%,头部企业有字节跳动、百度、阿里和腾讯
。发展趋势包括大模型应用落地、Agent架构普及以及行业垂直解决方案增多。此外,报告还提供了投资建议和风
险提示,并已通过专业审核。
============================================================
📝 提取的完整研报内容:
============================================================
# 2026年AI行业数据行业研报
## 一、核心数据
1. 市场规模:1.2万亿元
2. 年增长率:25%
3. 头部企业:字节跳动、百度、阿里、腾讯
## 二、发展趋势分析
大模型应用落地、Agent架构普及、行业垂直解决方案增多
## 三、投资建议
1. 重点关注字节跳动等头部企业
2. 布局大模型应用落地相关领域
3. 长期看好行业增长潜力,建议分批布局
## 四、风险提示
1. 行业竞争加剧风险
2. 技术迭代不及预期风险
3. 政策监管变化风险
✅ Plan-and-Execute演示完成
2.4 代码解析
整体代码实现的是 LangChain Plan-and-Execute(规划-执行)智能体架构:
- Planner(规划器):把复杂任务拆成一步步可执行的步骤
- Executor(执行器):按步骤调用工具、完成任务
- Tools(工具集):提供数据收集、写报告、审核、输出结果等专业能力
- 全局存储:解决多步骤之间数据传递、共享的问题
(一)、依赖导入与全局配置解析
python
# 导入Ollama本地大模型
from langchain_ollama import ChatOllama
# 工具装饰器,用来快速定义智能体可用的工具
from langchain_core.tools import tool
# 提示词模板,控制LLM输出格式
from langchain_core.prompts import ChatPromptTemplate
# Plan-and-Execute核心三剑客:规划执行架构、加载规划器、加载执行器
from langchain_experimental.plan_and_execute import (
PlanAndExecute,
load_chat_planner,
load_agent_executor
)
# 类型注解,让代码更规范
from typing import List, Dict, Any
# 忽略警告
import warnings
warnings.filterwarnings('ignore')
关键解释
ChatOllama:专门对接本地运行的 Ollama 大模型,不需要联网、免费、隐私安全@tool:LangChain 最简洁的工具定义方式,自动生成工具描述、参数解析PlanAndExecute:实验性高级架构,专门处理多步骤、长流程、强逻辑复杂任务- 全局警告关闭:避免实验性模块的警告干扰运行
(二)、全局数据存储设计解析
python
global_data_store = {
"industry_data": "",
"industry_report": "",
"review_result": ""
}
为什么必须用全局存储?(核心设计点)
Plan-and-Execute 是分步执行的:
- 第一步:收集数据
- 第二步:写报告
- 第三步:审核报告
普通写法会出现数据无法跨步骤传递 的问题。
全局字典 = 智能体的"临时记忆库",让所有工具都能读写共享数据,完美解决步骤间数据隔离问题。
(三)、LLM 大模型初始化解析
python
llm = ChatOllama(
model="qwen2_5-7b-q6",
base_url="http://localhost:11434",
temperature=0.1,
num_ctx=8192
)
参数逐行解释
model:你本地 Ollama 运行的模型名称(必须与本地一致)base_url:Ollama 默认本地地址,固定不变temperature=0.1:- 数值越低 → 输出越稳定、严谨、不发散
- 适合写报告、做分析这种需要精准输出的任务
num_ctx=8192:上下文窗口大小,能处理更长文本(研报、长文档必备)
(四)、工具集(Tools)核心代码解析
代码一共定义了 4 个专业工具 ,构成完整研报生成流水线:
数据收集 → 撰写研报 → 审核研报 → 输出最终结果
工具1:collect_industry_data(行业数据收集)
python
@tool
def collect_industry_data(industry: str, year: str) -> str:
"""
收集指定行业指定年份的详细数据
参数: industry=行业, year=年份
返回: 结构化行业数据
"""
# 模拟行业数据库
data = {"AI": {...}, "新能源": {...}}
# 查询数据 → 格式化 → 保存到全局存储 → 返回结果
if industry in data and year in data[industry]:
result = 拼接好的数据文本
global_data_store["industry_data"] = result # 保存!
return result
关键解释
@tool装饰器 :- 自动把函数变成智能体可调用的工具
- 自动读取文档字符串(
"""...""")作为工具功能说明 - 自动校验参数类型
- 模拟数据:实际项目可替换成数据库/API/爬虫
- 核心动作 :把结果存入
global_data_store,让后续工具直接使用
工具2:write_industry_report(撰写行业研报)
python
@tool
def write_industry_report(use_saved_data: bool = True) -> str:
# 直接从全局存储读取数据,不需要外部传入
data = global_data_store.get("industry_data", "")
# 安全解析数据
lines = data.split('\n')
# 提取市场规模、增长率、企业、趋势
# 生成 markdown 专业研报
report = f"""# {title}行业研报
## 一、核心数据
...
"""
# 保存研报到全局存储
global_data_store["industry_report"] = report
return report
关键解释
- 无参数依赖:不需要手动传数据,智能体直接读全局存储
- 健壮性设计 :
- 先判断数据是否存在
- 再判断格式是否正确
- 异常捕获,避免崩溃
- 结构化输出:生成标准 Markdown 研报,可读性强、可直接使用
工具3:review_report(审核研报)
python
@tool
def review_report(use_saved_report: bool = True) -> str:
# 读取全局存储里的研报
report = global_data_store.get("industry_report", "")
# 审核逻辑:检查必须模块是否存在
issues = []
if "市场规模" not in report: issues.append(...)
if "发展趋势" not in report: issues.append(...)
# 返回审核结果并保存
if issues:
return "不通过"
else:
return "通过"
关键解释
这是质量控制环节,模拟专业审核:
- 检查研报完整性
- 自动判断是否通过
- 结果存入全局存储
工具4:get_final_result(输出最终结果)
python
@tool
def get_final_result() -> str:
# 整合全局存储中所有内容:数据 + 研报 + 审核结果
final_result = f"""# 最终版研报
数据:{...}
报告:{...}
审核:{...}
"""
return final_result
关键解释
- 最终收口工具
- 把全流程结果整合成一份完整报告
- 智能体最后调用它输出最终答案
(五)、工具列表注册解析
python
tools = [
collect_industry_data,
write_industry_report,
review_report,
get_final_result
]
把 4 个工具打包成列表,交给执行器使用。
智能体只能调用列表里的工具,不在列表里的函数无法调用。
(六)、Plan-and-Execute核心架构创建解析
这是最核心、最关键的代码!
1. 创建规划器(Planner)
python
planner = load_chat_planner(llm)
- 作用:任务拆解大师
- 输入:复杂任务描述
- 输出:有序步骤列表(step1 → step2 → step3 → step4)
2. 创建执行器(Executor)
python
executor = load_agent_executor(llm, tools, verbose=False)
- 作用:任务执行员工
- 按规划好的步骤,一步步调用工具
- 能理解工具功能、自动传参、处理返回值
3. 组合成完整智能体
python
agent = PlanAndExecute(
planner=planner,
executor=executor,
verbose=True
)
planner:负责"想怎么做"executor:负责"真的去做"verbose=True:打印执行过程,方便调试
(七)、任务执行与结果解析
python
complex_task = """请完成2026年AI行业研报的撰写工作,严格按以下步骤执行:
1. 调用collect_industry_data工具
2. 调用write_industry_report工具
3. 调用review_report工具
4. 调用get_final_result工具
5. 输出最终答案"""
result = agent.run(complex_task)
运行流程(你日志里看到的过程)
- 智能体接收任务
- Planner 拆步骤:生成 5 个有序步骤
- Executor 按步骤执行 :
- 步骤1:收集数据 → 存全局存储
- 步骤2:写研报 → 读数据 → 生成报告 → 保存
- 步骤3:审核报告 → 读报告 → 判断通过
- 步骤4:获取最终结果 → 整合所有内容
- 输出最终答案
(八)、运行结果关键现象解释
你日志里出现:
Response: I know what to respond
Action: Final Answer
这是LangChain 执行器的标准输出格式,代表:
- 智能体已经完成所有步骤
- 确认不需要再调用工具
- 准备输出最终答案
最终输出的文本,就是 get_final_result 整合后的完整内容。
小结
- 真正的多步骤复杂任务自动化
- 解决了智能体步骤间数据传递难题(全局存储)
- 结构清晰、可直接用于行业研报/数据分析/报告生成
- 本地运行 Ollama,免费、安全、高速
- 可无限扩展工具(加爬虫、加数据库、加Excel导出等)
2.5 Plan-and-Execute vs ReAct:核心区别
| 对比维度 | ReAct(单 Agent) | Plan-and-Execute |
|---|---|---|
| 规划方式 | 边做边想,每步都思考 | 先一次性规划,再执行 |
| 长程能力 | 弱,容易跑偏 | 强,有清晰路线图 |
| 可解释性 | 一般,思考过程分散 | 强,规划一目了然 |
| 错误恢复 | 可以在执行中调整 | 需要重新规划或设计重试机制 |
| 适用场景 | 简单任务、工具调用 | 复杂多步任务 |
| 执行效率 | 高(无需规划开销) | 中(有规划开销但执行更顺畅) |

三、LangGraph:图编排核心框架
3.1 为什么需要 LangGraph?
Plan-and-Execute 解决了"长程规划"问题,但它有一个致命缺陷:缺乏灵活性------一旦计划确定,就很难在执行过程中调整。而现实世界的任务往往需要动态调整:
- 搜索资料时发现新信息,需要追加搜索;
- 分析数据时发现异常,需要重新搜索验证;
- 用户中途插入新需求。
这就是 LangGraph 的价值所在:用"图"结构管理 Agent 的工作流,支持循环、分支、状态共享。
生活类比:工作流引擎 vs 项目管理工具
- Plan-and-Execute 像传统的瀑布式项目管理:先规划,后执行,不能回头;
- LangGraph 像敏捷开发流程:可以迭代、可以回溯、可以并行。
3.2 LangGraph 核心概念
| 概念 | 类比 | 说明 |
|---|---|---|
| State(状态) | 项目看板 | 所有 Agent 共享的数据,包括任务列表、执行结果、中间状态 |
| Nodes(节点) | 团队成员 | 每个 Agent 或工具,执行特定任务 |
| Edges(边) | 工作流程线 | 定义节点之间的流转关系 |
| Conditional Edges(条件边) | 决策点 | 根据状态决定下一步去哪个节点 |
| Graph(图) | 项目流程图 | 整个工作流的蓝图 |

3.3 LangGraph 基础入门
python
"""
LangGraph 基础入门:构建一个带循环的状态机
适配 LangGraph 0.2.x + 本地 Ollama
"""
from langgraph.graph import StateGraph, END
from typing import TypedDict, Annotated, List
import operator
from langchain_ollama import ChatOllama
import warnings
warnings.filterwarnings('ignore')
# ===================== 1. 定义状态(State) =====================
class AgentState(TypedDict):
"""Agent 的共享状态"""
messages: Annotated[List[str], operator.add] # 消息历史,支持追加
current_step: str # 当前步骤
step_results: dict # 各步骤的执行结果
final_answer: str # 最终答案
print("✅ 状态定义完成")
# ===================== 2. 定义节点(Nodes) =====================
def node_search(state: AgentState) -> AgentState:
"""搜索节点"""
print(f"\n🔍 执行搜索节点...")
# 模拟搜索
search_result = "AI芯片市场规模2025年达500亿美元"
# 更新状态
state["messages"].append(f"搜索完成:{search_result}")
state["step_results"]["search"] = search_result
state["current_step"] = "analyze"
return state
def node_analyze(state: AgentState) -> AgentState:
"""分析节点"""
print(f"\n📊 执行分析节点...")
# 获取上一步的结果
search_result = state["step_results"].get("search", "")
# 模拟分析
analyze_result = f"分析{search_result}:市场集中度高,英伟达占80%"
state["messages"].append(f"分析完成:{analyze_result}")
state["step_results"]["analyze"] = analyze_result
state["current_step"] = "report"
return state
def node_report(state: AgentState) -> AgentState:
"""报告节点"""
print(f"\n📝 执行报告节点...")
# 获取前面步骤的结果
search_result = state["step_results"].get("search", "")
analyze_result = state["step_results"].get("analyze", "")
# 生成报告
report = f"""
# AI芯片行业报告
## 市场数据
{search_result}
## 分析结论
{analyze_result}
## 建议
关注英伟达技术路线,布局国产替代机会。
"""
state["messages"].append(f"报告生成完成")
state["final_answer"] = report
state["current_step"] = "done"
return state
def node_check(state: AgentState) -> AgentState:
"""检查节点(可选,用于质量检查)"""
print(f"\n✅ 执行检查节点...")
# 简单检查
if "英伟达" in state.get("final_answer", ""):
state["messages"].append("检查通过")
else:
state["messages"].append("检查警告:报告可能不完整")
return state
print("✅ 节点定义完成")
# ===================== 3. 定义条件边 =====================
def should_continue(state: AgentState) -> str:
"""决定下一步去哪里"""
current = state["current_step"]
if current == "search":
return "analyze"
elif current == "analyze":
return "report"
elif current == "report":
return "check"
elif current == "check":
return "end"
else:
return "end"
print("✅ 条件边定义完成")
# ===================== 4. 构建图 =====================
def build_graph():
"""构建 LangGraph 工作流"""
# 创建图
graph = StateGraph(AgentState)
# 添加节点
graph.add_node("search", node_search)
graph.add_node("analyze", node_analyze)
graph.add_node("report", node_report)
graph.add_node("check", node_check)
# 设置入口
graph.set_entry_point("search")
# 只需要这一行条件边!
graph.add_conditional_edges("search", should_continue)
# 固定顺序边(更简单)
graph.add_edge("analyze", "report")
graph.add_edge("report", "check")
graph.add_edge("check", END)
return graph.compile()
print("✅ 图构建完成")
# ===================== 5. 运行测试 =====================
if __name__ == "__main__":
# 初始化状态
initial_state = AgentState(
messages=[],
current_step="search",
step_results={},
final_answer=""
)
# 构建并运行图
graph = build_graph()
print("="*60)
print("🚀 开始执行 LangGraph 工作流")
print("="*60)
result = graph.invoke(initial_state)
print("\n" + "="*60)
print("📄 最终报告:")
print(result["final_answer"])
print("="*60)
print("\n📝 执行过程消息:")
for msg in result["messages"]:
print(f" - {msg}")
运行结果:
✅ 状态定义完成
✅ 节点定义完成
✅ 条件边定义完成
✅ 图构建完成
============================================================
🚀 开始执行 LangGraph 工作流
============================================================
🔍 执行搜索节点...
📝 执行报告节点...
✅ 执行检查节点...
============================================================
📄 最终报告:
# AI芯片行业报告
## 市场数据
AI芯片市场规模2025年达500亿美元
## 分析结论
## 建议
关注英伟达技术路线,布局国产替代机会。
============================================================
📝 执行过程消息:
- 搜索完成:AI芯片市场规模2025年达500亿美元
- 搜索完成:AI芯片市场规模2025年达500亿美元
- 报告生成完成
- 搜索完成:AI芯片市场规模2025年达500亿美元
- 搜索完成:AI芯片市场规模2025年达500亿美元
- 报告生成完成
- 检查通过
- 搜索完成:AI芯片市场规模2025年达500亿美元
- 搜索完成:AI芯片市场规模2025年达500亿美元
- 报告生成完成
- 搜索完成:AI芯片市场规模2025年达500亿美元
- 搜索完成:AI芯片市场规模2025年达500亿美元
- 报告生成完成
- 检查通过
3.3.1 LangGraph基础代码解释
3.3.1.1 模块整体说明
本例实现 LangGraph状态机工作流 ,是构建多步骤、可循环、可控制的智能体的基础。
核心四要素:
- State(状态):全局共享数据,所有节点都能读写
- Nodes(节点):执行具体任务的函数(搜索/分析/报告/检查)
- Edges(边):定义节点之间的跳转规则
- Graph(图):把节点和边组装成可运行的工作流
3.3.1.2 依赖导入与配置解释
python
from langgraph.graph import StateGraph, END
from typing import TypedDict, Annotated, List
import operator
from langchain_ollama import ChatOllama
import warnings
warnings.filterwarnings('ignore')
逐行解释:
StateGraph:LangGraph 核心类,用于创建状态驱动的工作流图END:图的结束节点,代表工作流终止TypedDict:用于定义强类型状态结构,让代码更稳定Annotated+operator.add:专门用于消息列表追加,实现状态累加ChatOllama:本地大模型接口(本示例未实际调用,保留用于扩展)- 警告过滤:屏蔽无关警告,让控制台更整洁
3.3.1.3 状态(State)定义解释
python
class AgentState(TypedDict):
"""Agent 的共享状态"""
messages: Annotated[List[str], operator.add] # 消息历史,支持追加
current_step: str # 当前步骤
step_results: dict # 各步骤的执行结果
final_answer: str # 最终答案
核心解释:
- State = 整个工作流的共享内存
- 所有节点都可以读取/修改这里的数据
Annotated[List[str], operator.add]:
让messages支持自动追加,不会覆盖历史记录- 字段作用:
messages:记录执行日志current_step:控制下一步跳转到哪个节点step_results:保存每一步的结果数据final_answer:存储最终生成的报告
3.3.1.4 节点(Nodes)定义解释
节点 = 工作流中真正执行任务的函数,每个节点接收状态 → 处理 → 返回新状态。
① 搜索节点
python
def node_search(state: AgentState) -> AgentState:
print(f"\n🔍 执行搜索节点...")
search_result = "AI芯片市场规模2025年达500亿美元"
state["messages"].append(f"搜索完成:{search_result}")
state["step_results"]["search"] = search_result
state["current_step"] = "analyze"
return state
- 功能:模拟行业数据搜索
- 修改状态:
- 追加日志
- 保存搜索结果
- 设置下一步为 analyze
- 返回更新后的状态,交给下一个节点
② 分析节点
python
def node_analyze(state: AgentState) -> AgentState:
print(f"\n📊 执行分析节点...")
search_result = state["step_results"].get("search", "")
analyze_result = f"分析{search_result}:市场集中度高,英伟达占80%"
state["messages"].append(f"分析完成:{analyze_result}")
state["step_results"]["analyze"] = analyze_result
state["current_step"] = "report"
return state
- 功能:读取搜索结果 → 做分析
- 关键点:从 state 中获取上一步结果,实现步骤间数据传递
- 跳转:下一步 → report
③ 报告节点
python
def node_report(state: AgentState) -> AgentState:
print(f"\n📝 执行报告节点...")
search_result = state["step_results"].get("search", "")
analyze_result = state["step_results"].get("analyze", "")
report = """报告内容"""
state["messages"].append(f"报告生成完成")
state["final_answer"] = report
state["current_step"] = "done"
return state
- 功能:整合所有步骤数据,生成最终报告
- 保存结果到
final_answer
④ 检查节点
python
def node_check(state: AgentState) -> AgentState:
print(f"\n✅ 执行检查节点...")
if "英伟达" in state.get("final_answer", ""):
state["messages"].append("检查通过")
else:
state["messages"].append("检查警告:报告可能不完整")
return state
- 功能:质量校验、流程审计
3.3.1.5 条件边(Conditional Edges)解释
python
def should_continue(state: AgentState) -> str:
"""决定下一步去哪里"""
current = state["current_step"]
if current == "search": return "analyze"
elif current == "analyze": return "report"
elif current == "report": return "check"
elif current == "check": return "end"
else: return "end"
核心作用:
- 根据 current_step 自动决定下一个节点
- 相当于工作流的"路由控制器"
- 支持循环、分支、条件跳转
3.3.1.6 图(Graph)构建解释
python
def build_graph():
graph = StateGraph(AgentState)
graph.add_node("search", node_search)
graph.add_node("analyze", node_analyze)
graph.add_node("report", node_report)
graph.add_node("check", node_check)
graph.set_entry_point("search")
graph.add_conditional_edges(...)
return graph.compile()
关键解释:
StateGraph(AgentState):创建基于状态的工作流图add_node:注册节点set_entry_point("search"):设置工作流从 search 节点开始add_conditional_edges:添加条件路由compile():编译成可运行的工作流
3.3.1.7 运行工作流解释
python
initial_state = AgentState(
messages=[], current_step="search", step_results={}, final_answer=""
)
graph = build_graph()
result = graph.invoke(initial_state)
initial_state:初始化空状态graph.invoke():同步运行整个工作流- 返回最终完整状态 ,可取出
final_answer和执行日志
小结
3.3.1 模块是 LangGraph 的基础骨架:
- State:共享数据
- Nodes:执行任务
- Edges:控制流向
- Graph:运行工作流
完全符合你目录结构,可直接复制使用。
3.4 LangGraph 的高级特性
3.4.1 循环与回溯
python
# 在 LangGraph 中实现循环
def should_review(state: AgentState) -> str:
"""决定是否需要重新搜索"""
if "不完整" in state.get("last_result", ""):
return "search" # 返回搜索节点,形成循环
return "next"
graph.add_conditional_edges(
"review",
should_review,
{
"search": "search",
"next": "next_node"
}
)
3.4.2 并行执行
LangGraph 支持多个节点并行执行(使用 Send API),适用于需要同时进行多个独立任务的场景。
四、核心原理:Multi-Agent 多智能体协作
4.1 什么是Multi-Agent?
Multi-Agent(多智能体) 是指由多个独立Agent组成的系统,每个Agent有明确的角色和职责,通过消息传递 和状态共享协作完成复杂任务。
核心特点:
- 角色分工:每个Agent专注于特定领域的任务;
- 并行处理:多个Agent可同时执行不同任务;
- 状态共享:Agent之间共享必要的信息;
- 协同决策:关键决策可由多个Agent共同完成;
- 容错性高:单个Agent出错不会导致整个系统崩溃。

用户复杂指令
总控Agent/项目经理
拆解任务并分配角色
研究员Agent
作家Agent
审核员Agent
收集数据
共享数据到状态库
从状态库读取数据
撰写研报
共享研报到状态库
从状态库读取研报
审核研报
共享审核结果到状态库
汇总结果生成最终回答
返回给用户
生活类比(项目组协作):
- 研究员Agent:专注数据收集,不懂写作和审核;
- 作家Agent:专注内容创作,不懂数据收集和审核;
- 审核员Agent:专注质量检查,不懂数据收集和写作;
- 总控Agent:不做具体工作,只负责任务拆解和协调。
3.2 LangGraph:Multi-Agent的协作中枢
LangGraph 是LangChain推出的新一代Agent编排框架,基于有状态的循环图构建,完美适配Multi-Agent协作场景。
3.2.1 LangGraph核心概念
| 概念 | 类比 | 核心功能 |
|---|---|---|
| State(状态) | 项目共享看板/文档库 | 存储所有Agent的输入、输出和中间状态 |
| Nodes(节点) | 项目组成员/工作节点 | 执行具体任务的单元(每个Node可以是一个Agent) |
| Edges(边) | 工作流转规则 | 定义节点之间的跳转逻辑和条件 |
| Graph(图) | 项目流程图 | 整体的协作流程和规则定义 |
3.2.2 LangGraph完整代码演示
python
# LangGraph构建Multi-Agent系统(适配LangChain 1.2.10 + 本地Ollama)
from langchain_ollama import ChatOllama
from langchain_core.tools import tool
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnableConfig
from langgraph.graph import StateGraph, END
from langgraph.graph.message import add_messages
from typing import TypedDict, Annotated, Sequence
import operator
import warnings
warnings.filterwarnings('ignore')
# ===================== 1. 定义状态结构(共享看板) =====================
class AgentState(TypedDict):
"""
多Agent系统的共享状态
相当于项目组的共享看板/文档库
"""
# 对话历史
messages: Annotated[Sequence[str], add_messages]
# 收集到的行业数据
industry_data: str
# 撰写的研报内容
report_content: str
# 审核结果
review_result: str
# 当前执行阶段
stage: str
# 最终输出
final_output: str
print("✅ 定义共享状态结构完成")
# ===================== 2. 初始化LLM和工具 =====================
# 2.1 初始化LLM
llm = ChatOllama(
model="qwen2_5-7b-q6",
base_url="http://localhost:11434",
temperature=0.1
)
# 2.2 定义专业工具(与Plan-and-Execute示例相同)
@tool
def collect_industry_data(industry: str, year: str) -> str:
"""收集指定行业指定年份的详细数据"""
data = {
"AI": {
"2026": """【2026年AI行业数据】
1. 市场规模:1.2万亿元
2. 年增长率:25%
3. 头部企业:字节跳动、百度、阿里、腾讯
4. 发展趋势:大模型应用落地、Agent架构普及、行业垂直解决方案增多"""
}
}
return data.get(industry, {}).get(year, f"未找到{year}年{industry}行业数据")
@tool
def write_industry_report(data: str) -> str:
"""基于行业数据撰写专业研报"""
if not data:
return "数据为空,无法撰写研报"
return f"""# 2026年AI行业研报
## 核心数据
{data.split('1.')[1].split('4.')[0]}
## 发展趋势
{data.split('4.')[1]}
## 投资建议
1. 重点关注头部企业
2. 布局大模型应用落地场景
3. 长期看好行业发展
## 风险提示
1. 技术迭代风险
2. 市场竞争风险
3. 政策监管风险"""
@tool
def review_report(report: str) -> str:
"""审核行业研报内容"""
if all(key in report for key in ["市场规模", "发展趋势", "风险提示"]):
return "✅ 审核通过:研报内容完整、格式规范"
else:
return "❌ 审核不通过:研报缺少关键内容"
print("✅ LLM和专业工具初始化完成")
# ===================== 3. 定义Agent节点 =====================
# 3.1 研究员Agent(数据收集)
def researcher_agent(state: AgentState) -> AgentState:
"""研究员Agent:负责收集行业数据"""
print("\n🤵♂️ 研究员Agent开始工作...")
# 提取用户需求
user_input = state["messages"][-1]
industry = "AI"
year = "2026"
# 调用数据收集工具
data = collect_industry_data.invoke({"industry": industry, "year": year})
# 更新状态
state["industry_data"] = data
state["stage"] = "data_collected"
state["messages"].append(f"研究员:已收集{year}年{industry}行业数据\n{data}")
print("✅ 研究员Agent完成数据收集")
return state
# 3.2 作家Agent(研报撰写)
def writer_agent(state: AgentState) -> AgentState:
"""作家Agent:负责撰写研报"""
print("\n✍️ 作家Agent开始工作...")
# 检查是否有数据
if not state["industry_data"]:
state["messages"].append("作家:缺少行业数据,无法撰写研报")
state["stage"] = "write_failed"
return state
# 调用研报撰写工具
report = write_industry_report.invoke({"data": state["industry_data"]})
# 更新状态
state["report_content"] = report
state["stage"] = "report_written"
state["messages"].append(f"作家:已完成研报撰写\n{report}")
print("✅ 作家Agent完成研报撰写")
return state
# 3.3 审核员Agent(质量审核)
def reviewer_agent(state: AgentState) -> AgentState:
"""审核员Agent:负责审核研报"""
print("\n🔍 审核员Agent开始工作...")
# 检查是否有研报内容
if not state["report_content"]:
state["messages"].append("审核员:缺少研报内容,无法审核")
state["stage"] = "review_failed"
return state
# 调用审核工具
review_result = review_report.invoke({"report": state["report_content"]})
# 更新状态
state["review_result"] = review_result
state["stage"] = "report_reviewed"
state["messages"].append(f"审核员:{review_result}")
print(f"✅ 审核员Agent完成审核:{review_result}")
return state
# 3.4 总控Agent(结果汇总)
def manager_agent(state: AgentState) -> AgentState:
"""总控Agent:负责汇总结果并生成最终输出"""
print("\n👔 总控Agent开始工作...")
# 汇总结果
if "✅" in state["review_result"]:
final_output = f"""# 2026年AI行业研报(最终版)
{state['report_content']}
## 审核结论
{state['review_result']}
---
本研报由Multi-Agent系统自动生成:
- 研究员Agent:数据收集
- 作家Agent:内容撰写
- 审核员Agent:质量检查"""
else:
final_output = f"研报生成失败:{state['review_result']}"
# 更新状态
state["final_output"] = final_output
state["stage"] = "completed"
state["messages"].append(f"总控:已生成最终研报\n{final_output}")
print("✅ 总控Agent完成结果汇总")
return state
print("✅ 定义各Agent节点完成")
# ===================== 4. 定义流转逻辑 =====================
def router(state: AgentState) -> str:
"""路由函数:决定下一步执行哪个节点"""
stage = state.get("stage", "")
if stage == "":
return "researcher" # 初始状态,先执行研究员
elif stage == "data_collected":
return "writer" # 数据收集完成,执行作家
elif stage == "report_written":
return "reviewer" # 研报撰写完成,执行审核员
elif stage == "report_reviewed":
return "manager" # 审核完成,执行总控
else:
return END # 完成
print("✅ 定义流转逻辑完成")
# ===================== 5. 构建LangGraph =====================
print("\n===== 构建LangGraph多Agent系统 =====")
# 5.1 创建图
workflow = StateGraph(AgentState)
# 5.2 添加节点
workflow.add_node("researcher", researcher_agent) # 研究员节点
workflow.add_node("writer", writer_agent) # 作家节点
workflow.add_node("reviewer", reviewer_agent) # 审核员节点
workflow.add_node("manager", manager_agent) # 总控节点
# 5.3 设置起始节点
workflow.set_entry_point("researcher")
# 5.4 添加边(流转规则)
workflow.add_conditional_edges(
"researcher",
router,
{"writer": "writer", END: END}
)
workflow.add_conditional_edges(
"writer",
router,
{"reviewer": "reviewer", END: END}
)
workflow.add_conditional_edges(
"reviewer",
router,
{"manager": "manager", END: END}
)
workflow.add_conditional_edges(
"manager",
router,
{END: END}
)
# 5.5 编译图
app = workflow.compile()
print("✅ LangGraph编译完成")
# ===================== 6. 运行Multi-Agent系统 =====================
print("\n" + "="*60)
print("运行Multi-Agent系统:自动撰写AI行业研报")
print("="*60)
# 初始状态
initial_state = AgentState(
messages=["帮我生成一份2026年AI行业的完整研报"],
industry_data="",
report_content="",
review_result="",
stage="",
final_output=""
)
# 运行图
try:
# 配置
config = RunnableConfig()
config["configurable"] = {"thread_id": "report_001"}
# 执行
result = app.invoke(initial_state, config)
# 输出最终结果
print("\n" + "="*60)
print("🎯 Multi-Agent系统最终输出:")
print("="*60)
print(result["final_output"])
except Exception as e:
print(f"\n❌ 执行出错:{str(e)}")
import traceback
traceback.print_exc()
print("\n✅ Multi-Agent系统运行完成")
运行结果:
✅ 定义共享状态结构完成
✅ LLM和专业工具初始化完成
✅ 定义各Agent节点完成
✅ 定义流转逻辑完成
===== 构建LangGraph多Agent系统 =====
✅ LangGraph编译完成
============================================================
运行Multi-Agent系统:自动撰写AI行业研报
============================================================
🤵♂️ 研究员Agent开始工作...
✅ 研究员Agent完成数据收集
✍️ 作家Agent开始工作...
✅ 作家Agent完成研报撰写
🔍 审核员Agent开始工作...
✅ 审核员Agent完成审核:✅ 审核通过:研报内容完整、格式规范
👔 总控Agent开始工作...
✅ 总控Agent完成结果汇总
============================================================
🎯 Multi-Agent系统最终输出:
============================================================
# 2026年AI行业研报(最终版)
# 2026年AI行业研报
## 核心数据
市场规模:
## 发展趋势
发展趋势:大模型应用落地、Agent架构普及、行业垂直解决方案增多
## 投资建议
1. 重点关注头部企业
2. 布局大模型应用落地场景
3. 长期看好行业发展
## 风险提示
1. 技术迭代风险
2. 市场竞争风险
3. 政策监管风险
## 审核结论
✅ 审核通过:研报内容完整、格式规范
---
本研报由Multi-Agent系统自动生成:
- 研究员Agent:数据收集
- 作家Agent:内容撰写
- 审核员Agent:质量检查
✅ Multi-Agent系统运行完成
3.2.3 LangGraph 多Agent代码逐模块详细解释
3.2.3.1 依赖导入与全局配置解释
python
from langchain_ollama import ChatOllama
from langchain_core.tools import tool
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnableConfig
from langgraph.graph import StateGraph, END
from langgraph.graph.message import add_messages
from typing import TypedDict, Annotated, Sequence
import operator
import warnings
warnings.filterwarnings('ignore')
核心解释:
StateGraph:LangGraph 核心类,用于构建状态驱动的工作流图END:工作流终止标志TypedDict:定义强类型状态结构,确保数据格式统一Annotated / add_messages:实现消息历史追加累加,不覆盖历史RunnableConfig:为工作流提供运行配置(如线程ID,支持持久化)@tool:定义智能体可调用的工具函数- 警告过滤:屏蔽实验性模块无关警告,控制台输出更整洁
3.2.3.2 共享状态(State)定义解释
python
class AgentState(TypedDict):
messages: Annotated[Sequence[str], add_messages]
industry_data: str
report_content: str
review_result: str
stage: str
final_output: str
核心作用:
- State = 整个多Agent系统的共享内存/项目看板
- 所有Agent节点都能读取、修改、传递这里的数据
- 字段分工:
messages:记录所有Agent的对话与执行日志industry_data:存储研究员收集的行业数据report_content:存储作家撰写的研报正文review_result:存储审核员的审核结论stage:控制工作流流转的核心字段(当前执行阶段)final_output:存储总控Agent汇总的最终结果
3.2.3.3 LLM与工具集初始化解释
python
llm = ChatOllama(
model="qwen2_5-7b-q6",
base_url="http://localhost:11434",
temperature=0.1
)
@tool
def collect_industry_data(industry: str, year: str) -> str:
... # 模拟数据收集
@tool
def write_industry_report(data: str) -> str:
... # 模拟研报撰写
@tool
def review_report(report: str) -> str:
... # 模拟报告审核
核心解释:
- LLM 初始化
- 对接本地Ollama运行的大模型
temperature=0.1保证输出稳定、严谨,适合报告生成
- 工具函数(Tools)
- 用
@tool装饰器定义标准化工具 - 分别实现数据收集、报告撰写、质量审核三大功能
- 工具是Agent执行具体任务的"手脚",提供确定性能力
- 用
3.2.3.4 四大Agent节点定义解释
每个节点 = 一个独立职能的Agent,接收状态 → 执行任务 → 更新状态
① 研究员Agent(数据收集)
python
def researcher_agent(state: AgentState) -> AgentState:
print("\n🤵♂️ 研究员Agent开始工作...")
# 调用工具收集数据
data = collect_industry_data.invoke(...)
# 写入共享状态
state["industry_data"] = data
state["stage"] = "data_collected"
state["messages"].append("研究员:已收集数据")
return state
- 职能:负责行业数据采集
- 核心动作 :调用数据工具 → 保存数据到共享状态 → 标记阶段为
data_collected
② 作家Agent(研报撰写)
python
def writer_agent(state: AgentState) -> AgentState:
print("\n✍️ 作家Agent开始工作...")
# 读取状态中的数据
data = state["industry_data"]
# 调用工具写报告
report = write_industry_report.invoke(...)
# 保存报告到状态
state["report_content"] = report
state["stage"] = "report_written"
return state
- 职能:基于数据生成专业研报
- 核心动作:读取状态数据 → 生成研报 → 保存报告 → 标记阶段
③ 审核员Agent(质量审核)
python
def reviewer_agent(state: AgentState) -> AgentState:
print("\n🔍 审核员Agent开始工作...")
# 读取报告
report = state["report_content"]
# 审核
result = review_report.invoke(...)
# 保存结果
state["review_result"] = result
state["stage"] = "report_reviewed"
return state
- 职能:研报质量校验
- 核心动作:检查报告完整性 → 给出通过/不通过结论
④ 总控Agent(结果汇总)
python
def manager_agent(state: AgentState) -> AgentState:
print("\n👔 总控Agent开始工作...")
# 整合所有结果
final_output = 拼接数据+报告+审核结果
state["final_output"] = final_output
return state
- 职能:项目管理者,汇总全流程结果
- 核心动作:整合所有模块 → 生成最终版报告
3.2.3.5 路由流转逻辑(router)解释
python
def router(state: AgentState) -> str:
stage = state.get("stage", "")
if stage == "": return "researcher"
elif stage == "data_collected": return "writer"
elif stage == "report_written": return "reviewer"
elif stage == "report_reviewed": return "manager"
else: return END
核心作用:工作流大脑
- 根据
stage字段自动判断下一个执行的Agent - 实现标准化流程:
研究员 → 作家 → 审核员 → 总控 → 结束 - 完全解耦节点,支持灵活修改流程
3.2.3.6 LangGraph 工作流构建解释
python
# 创建图
workflow = StateGraph(AgentState)
# 添加节点
workflow.add_node("researcher", researcher_agent)
workflow.add_node("writer", writer_agent)
workflow.add_node("reviewer", reviewer_agent)
workflow.add_node("manager", manager_agent)
# 设置入口
workflow.set_entry_point("researcher")
# 添加条件流转
workflow.add_conditional_edges("researcher", router)
workflow.add_conditional_edges("writer", router)
workflow.add_conditional_edges("reviewer", router)
workflow.add_conditional_edges("manager", router)
# 编译
app = workflow.compile()
核心解释:
StateGraph(AgentState):基于共享状态创建工作流图add_node:注册4个Agent节点set_entry_point("researcher"):工作流从研究员开始执行add_conditional_edges:绑定路由函数,实现自动流转compile():编译为可运行的应用(app)
3.2.3.7 工作流运行与结果输出解释
python
# 初始状态
initial_state = AgentState(
messages=["帮我生成一份2026年AI行业的完整研报"],
industry_data="", report_content="",
review_result="", stage="", final_output=""
)
# 执行
result = app.invoke(initial_state, config)
# 输出最终报告
print(result["final_output"])
核心解释:
- 初始化状态:传入用户指令,清空所有数据字段
app.invoke(...):同步启动整个多Agent工作流- 执行流程 :
研究员收集数据 → 作家写报告 → 审核员校验 → 总控汇总 - 输出 :从最终状态中取出
final_output,打印完整研报
3.2.3.8 代码核心设计思想
- 状态共享 :所有Agent通过
AgentState传递数据,无需复杂参数传递 - 职责单一:每个Agent只做一件事,分工明确、易于维护
- 流程可控 :
router函数统一控制流转,支持分支、循环、重试 - 可扩展性强:新增Agent只需添加节点+修改路由,无需改动原有代码
小结
本例实现了LangGraph + 多智能体协作的标准架构:
- State:统一数据中心
- Nodes:四大职能Agent
- Router:智能流程调度
- Graph:可视化工作流
实现了从数据收集 → 研报撰写 → 质量审核 → 结果汇总的全自动流程,是企业级Multi-Agent系统的标准模板。
五、人类介入(Human-in-the-loop)
在Multi-Agent系统中,Human-in-the-loop(人类介入) 是指在关键节点引入人工确认,确保系统行为符合预期。
5.1 为什么需要人类介入?
Agent 再强大,也可能犯错或做出不符合预期的决策。在关键步骤引入人类确认,可以:
- 防止误操作:删除文件、发送邮件等敏感操作需要确认;
- 质量把控:关键决策需要人工判断;
- 方向纠正:Agent 跑偏时及时纠正。
生活类比:项目审批流程
- 普通任务:Agent 自主完成
- 关键决策:需要项目经理签字确认

5.2 Human-in-the-loop 实现
python
"""
Human-in-the-loop:在关键步骤引入人工确认
"""
from langgraph.graph import StateGraph, END
from typing import TypedDict
import warnings
warnings.filterwarnings('ignore')
# 状态定义
class HumanState(TypedDict):
task: str
need_approval: bool
approval: bool
result: str
# ===================== 节点函数 =====================
def node_plan(state: HumanState) -> HumanState:
"""规划节点"""
print(f"\n📋 规划任务: {state['task']}")
state["need_approval"] = True # 需要人工确认
return state
def node_execute(state: HumanState) -> HumanState:
"""执行节点"""
print(f"\n⚙️ 执行任务...")
state["result"] = f"任务 {state['task']} 执行完成"
return state
# ===================== 人工审批路由 =====================
def human_approval_router(state: HumanState) -> str:
"""人工确认:返回下一步节点名称"""
if not state["need_approval"]:
return "execute"
print(f"\n👤 需要人工确认:{state['task']}")
print(" 请输入 y 确认执行,n 取消执行:")
user_input = input().strip().lower()
if user_input == "y":
state["approval"] = True
return "execute"
else:
state["approval"] = False
state["result"] = "任务已被用户取消"
return END # 直接结束!
# ===================== 构建图(正确结构) =====================
def build_human_graph():
graph = StateGraph(HumanState)
# 添加节点
graph.add_node("plan", node_plan)
graph.add_node("execute", node_execute)
# 入口
graph.set_entry_point("plan")
# 核心:plan 执行完 → 进入人工判断
graph.add_conditional_edges(
"plan",
human_approval_router,
{
"execute": "execute",
END: END
}
)
# 执行完 → 结束
graph.add_edge("execute", END)
return graph.compile()
# ===================== 运行 =====================
if __name__ == "__main__":
graph = build_human_graph()
initial_state = HumanState(
task="删除生产环境日志文件",
need_approval=False,
approval=False,
result=""
)
result = graph.invoke(initial_state)
print(f"\n结果: {result['result']}")
运行结果:
📋 规划任务: 删除生产环境日志文件
👤 需要人工确认:删除生产环境日志文件
请输入 y 确认执行,n 取消执行:
y
⚙️ 执行任务...
结果: 任务 删除生产环境日志文件 执行完成
(gvenv) PS G:\AI\study\python> & g:\AI\study\python\gvenv\Scripts\python.exe g:/AI/study/python/LangchainDemo/14Multi-Agent/06Multi-Agent.py
📋 规划任务: 删除生产环境日志文件
👤 需要人工确认:删除生产环境日志文件
请输入 y 确认执行,n 取消执行:
n
结果:
5.3 Human-in-the-loop 代码解释
5.3.1 整体功能说明
本模块实现 LangGraph + Human-in-the-loop(人在回路) 工作流:
- 在关键高危操作 (如删除生产数据)前,强制触发人工确认
- 人同意 → 继续执行任务
- 人拒绝 → 直接终止任务,不执行危险操作
- 核心解决:AI 全自动执行可能带来的风险问题
5.3.2 依赖导入与状态定义解释
python
from langgraph.graph import StateGraph, END
from typing import TypedDict
import warnings
warnings.filterwarnings('ignore')
# 状态定义
class HumanState(TypedDict):
task: str # 待执行的任务内容
need_approval: bool # 是否需要人工审批
approval: bool # 审批结果(True=同意,False=拒绝)
result: str # 最终执行结果
解释:
StateGraph:LangGraph 核心类,用于构建状态工作流END:工作流终止节点HumanState:整个流程的共享状态,所有节点共享读写- 字段作用 :
task:存储要执行的任务(如删除日志)need_approval:标记是否需要人工确认approval:记录用户确认/拒绝的结果result:存储最终输出信息
5.3.3 节点函数(Nodes)解释
① 规划节点 node_plan
python
def node_plan(state: HumanState) -> HumanState:
"""规划节点:任务规划阶段"""
print(f"\n📋 规划任务: {state['task']}")
state["need_approval"] = True # 标记:需要人工确认
return state
功能:
- 负责任务规划
- 打印当前任务
- 强制开启人工审批 (
need_approval=True) - 返回更新后的状态
② 执行节点 node_execute
python
def node_execute(state: HumanState) -> HumanState:
"""执行节点:任务实际执行阶段"""
print(f"\n⚙️ 执行任务...")
state["result"] = f"任务 {state['task']} 执行完成"
return state
功能:
- 仅在用户确认后才会执行
- 执行具体业务逻辑(模拟删除操作)
- 将执行结果写入
result字段
5.3.4 人工审批路由(核心)解释
python
def human_approval_router(state: HumanState) -> str:
"""人工确认路由:决定流程走向"""
# 无需审批 → 直接执行
if not state["need_approval"]:
return "execute"
# 需要审批 → 等待用户输入
print(f"\n👤 需要人工确认:{state['task']}")
print(" 请输入 y 确认执行,n 取消执行:")
user_input = input().strip().lower()
# 用户同意 → 执行任务
if user_input == "y":
state["approval"] = True
return "execute"
# 用户拒绝 → 直接结束流程
else:
state["approval"] = False
state["result"] = "任务已被用户取消"
return END
核心解释:
- 这是路由函数 ,不是节点,只能用于条件边
- 功能:根据用户输入决定流程走向
- 逻辑:
- 判断是否需要审批
- 需要则控制台等待输入
y→ 跳转到执行节点n→ 直接终止工作流,并记录取消结果
5.3.5 工作流图构建解释
python
def build_human_graph():
graph = StateGraph(HumanState)
# 1. 添加节点
graph.add_node("plan", node_plan)
graph.add_node("execute", node_execute)
# 2. 设置入口
graph.set_entry_point("plan")
# 3. 核心:规划完成后 → 人工审批路由
graph.add_conditional_edges(
"plan",
human_approval_router,
{
"execute": "execute",
END: END
}
)
# 4. 执行完成 → 结束
graph.add_edge("execute", END)
return graph.compile()
解释:
- 创建状态图 :绑定
HumanState共享状态 - 注册节点:添加规划、执行两个节点
- 设置入口:从规划节点开始
- 添加条件边:规划完成后进入人工判断
- 普通边:任务执行完成后直接结束
- 编译 :生成可运行的工作流
app
5.3.6 运行入口代码解释
python
if __name__ == "__main__":
graph = build_human_graph()
# 初始化状态
initial_state = HumanState(
task="删除生产环境日志文件",
need_approval=False,
approval=False,
result=""
)
# 启动工作流
result = graph.invoke(initial_state)
print(f"\n结果: {result['result']}")
解释:
- 初始化任务:删除生产环境日志文件(高危操作)
invoke():同步运行整个工作流- 流程自动执行:
规划 → 人工确认 → 执行/终止 → 输出结果 - 最终打印
result状态字段
5.3.7 运行流程与结果解释
✅ 输入 y(确认)
📋 规划任务: 删除生产环境日志文件
👤 需要人工确认:删除生产环境日志文件
y
⚙️ 执行任务...
结果: 任务 删除生产环境日志文件 执行完成
流程:规划 → 人工确认通过 → 执行任务 → 结束
❌ 输入 n(取消)
📋 规划任务: 删除生产环境日志文件
👤 需要人工确认:删除生产环境日志文件
n
结果: 任务已被用户取消
流程:规划 → 人工拒绝 → 直接终止 → 不执行任务
5.3.8 代码核心小结
- 人在回路(Human-in-the-loop)标准实现
- 路由函数控制流程,安全可靠
- 高危操作必须人工确认,避免AI自动误操作
- 状态共享,步骤间数据传递清晰
- 结构极简、可直接用于生产环境
六、完整实战:构建自动撰写行业研报的Multi-Agent系统
6.1 项目背景
企业需要定期生成各类行业研报,传统方式需要多个岗位协作,耗时费力且质量参差不齐。基于Multi-Agent的自动研报生成系统可以:
- 自动收集行业数据;
- 生成结构化研报;
- 多维度审核质量;
- 支持人工介入和修改;
- 输出标准化研报文档。

6.2 完整可运行代码
python
"""
完整实战:Multi-Agent行业研报自动生成系统
适配LangChain 1.2.10 + LangGraph + 本地Ollama
核心特性:
1. 多Agent角色分工(研究员、作家、审核员、总控)
2. 状态共享和消息传递
3. Human-in-the-loop人类介入
4. 异常处理和容错机制
5. 完整的研报生成流程
"""
import warnings
warnings.filterwarnings('ignore')
# ===================== 1. 导入核心依赖 =====================
from langchain_ollama import ChatOllama
from langchain_core.tools import tool
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnableConfig
from langgraph.graph import StateGraph, END
from langgraph.graph.message import add_messages
from typing import TypedDict, Annotated, Sequence, Dict, Any
import operator
import json
from datetime import datetime
# ===================== 2. 定义核心数据结构 =====================
class ReportState(TypedDict):
"""研报生成系统的共享状态"""
# 基础信息
messages: Annotated[Sequence[str], add_messages]
user_request: str # 用户原始请求
industry: str # 目标行业
year: str # 目标年份
# 各阶段成果
raw_data: str # 原始数据
structured_data: str # 结构化数据
draft_report: str # 研报草稿
review_comments: str # 审核意见
human_review_result: str # 人类审核结果
final_report: str # 最终研报
# 流程控制
current_step: str # 当前步骤
error_info: str # 错误信息
is_completed: bool # 是否完成
# ===================== 3. 初始化核心组件 =====================
class ReportAgentSystem:
"""研报生成Multi-Agent系统"""
def __init__(self, model_name: str = "qwen2_5-7b-q6", base_url: str = "http://localhost:11434"):
# 初始化LLM
self.llm = ChatOllama(
model=model_name,
base_url=base_url,
temperature=0.1,
num_ctx=8192,
timeout=30
)
# 初始化工具
self.tools = self._init_tools()
# 构建LangGraph
self.app = self._build_graph()
print("✅ 研报生成Multi-Agent系统初始化完成")
def _init_tools(self) -> Dict[str, Any]:
"""初始化专业工具集"""
@tool
def data_collection_tool(industry: str, year: str) -> str:
"""
收集指定行业指定年份的综合数据
参数:
industry: 行业名称(如AI、新能源、半导体)
year: 年份(如2026)
返回:
JSON格式的结构化行业数据
"""
# 模拟真实数据API(实际项目可替换为真实数据源)
mock_data = {
"AI": {
"2026": {
"market_size": "1.2万亿元",
"growth_rate": "25%",
"key_players": ["字节跳动", "百度", "阿里", "腾讯", "商汤科技"],
"driving_factors": ["大模型应用落地", "政企数字化转型", "算力基础设施完善"],
"challenges": ["数据安全监管", "人才短缺", "商业化落地难度"],
"investment_hotspots": ["Agent架构", "多模态大模型", "行业垂直解决方案"],
"regional_analysis": {
"北上广深": "占市场份额70%",
"长三角": "增速最快,年增长30%",
"中西部": "潜力巨大,基础薄弱"
}
}
},
"新能源": {
"2026": {
"market_size": "5.8万亿元",
"growth_rate": "18%",
"key_players": ["比亚迪", "宁德时代", "特斯拉", "蔚来", "理想"],
"driving_factors": ["政策支持", "技术进步", "消费升级"],
"challenges": ["原材料价格波动", "产能过剩", "充电设施不足"],
"investment_hotspots": ["固态电池", "智能驾驶", "储能技术"],
"regional_analysis": {
"长三角": "产业链完整",
"珠三角": "出口导向",
"中西部": "产能基地"
}
}
}
}
# 获取数据
data = mock_data.get(industry, {}).get(year, {})
if not data:
return json.dumps({"error": f"未找到{year}年{industry}行业数据"})
# 添加时间戳
data["update_time"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
return json.dumps(data, ensure_ascii=False, indent=2)
@tool
def data_processing_tool(raw_data: str, industry: str, year: str) -> str:
"""
处理原始行业数据,转换为研报可用的结构化格式
参数:
raw_data: JSON格式的原始数据字符串
industry: 行业名称
year: 年份
返回:
结构化的数据摘要
"""
try:
data = json.loads(raw_data)
if "error" in data:
return f"数据处理失败:{data['error']}"
# 构建结构化摘要 - 修复:不使用self,而是使用传入的参数
structured = f"""# {year}年{industry}行业数据摘要
## 核心指标
- 市场规模:{data['market_size']}
- 年增长率:{data['growth_rate']}
- 头部企业:{', '.join(data['key_players'])}
## 发展驱动因素
"""
# 修复:避免在f-string中使用chr(10)
for factor in data['driving_factors']:
structured += f"- {factor}\n"
structured += """
## 面临挑战
"""
for challenge in data['challenges']:
structured += f"- {challenge}\n"
structured += """
## 投资热点
"""
for hotspot in data['investment_hotspots']:
structured += f"- {hotspot}\n"
structured += """
## 区域分析
"""
for region, desc in data['regional_analysis'].items():
structured += f"- {region}:{desc}\n"
return structured
except Exception as e:
return f"数据处理出错:{str(e)}"
@tool
def report_writing_tool(structured_data: str, industry: str, year: str) -> str:
"""
基于结构化数据撰写专业行业研报
参数:
structured_data: 结构化数据摘要
industry: 行业名称
year: 年份
返回:
Markdown格式的完整研报
"""
if "数据处理失败" in structured_data:
return f"研报撰写失败:{structured_data}"
# 提取各部分数据
try:
# 提取核心指标部分
core_metrics = ""
if "## 核心指标" in structured_data:
parts = structured_data.split("## 核心指标")
if len(parts) > 1:
core_metrics = parts[1].split("## 发展驱动因素")[0]
# 提取驱动因素
driving_factors = ""
if "## 发展驱动因素" in structured_data:
parts = structured_data.split("## 发展驱动因素")
if len(parts) > 1:
driving_factors = parts[1].split("## 面临挑战")[0]
# 提取挑战
challenges = ""
if "## 面临挑战" in structured_data:
parts = structured_data.split("## 面临挑战")
if len(parts) > 1:
challenges = parts[1].split("## 投资热点")[0]
# 提取投资热点
investments = ""
if "## 投资热点" in structured_data:
parts = structured_data.split("## 投资热点")
if len(parts) > 1:
investments = parts[1].split("## 区域分析")[0]
# 提取区域分析
region_analysis = ""
if "## 区域分析" in structured_data:
parts = structured_data.split("## 区域分析")
if len(parts) > 1:
region_analysis = parts[1]
# 提取增长率
growth_rate = "25%"
if "年增长率:" in structured_data:
lines = structured_data.split("\n")
for line in lines:
if "年增长率:" in line:
growth_rate = line.split("年增长率:")[1].strip()
break
# 提取头部企业
key_players = "字节跳动、百度、阿里"
if "头部企业:" in structured_data:
lines = structured_data.split("\n")
for line in lines:
if "头部企业:" in line:
key_players = line.split("头部企业:")[1].strip()
break
# 提取第一个企业
first_player = key_players.split("、")[0] if "、" in key_players else key_players
# 生成研报
report = f"""# {year}年{industry}行业深度研报
**报告生成时间**:{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}
**报告生成系统**:Multi-Agent智能研报系统
## 一、行业概况
{core_metrics}
## 二、发展驱动分析
{driving_factors}
## 三、行业挑战分析
{challenges}
## 四、投资机会分析
{investments}
## 五、区域市场分析
{region_analysis}
## 六、竞争格局分析
### 头部企业分析
{key_players}等头部企业占据主要市场份额,技术和资金优势明显。
### 竞争特点
1. 技术壁垒逐渐提高,中小企业生存空间收窄
2. 跨界竞争加剧,互联网/科技企业入局
3. 产业链整合加速,纵向一体化趋势明显
## 七、未来展望
### 短期(1-2年)
- 行业将保持高速增长,预计增长率{growth_rate}
- 技术落地加速,商业化应用场景增多
### 中期(3-5年)
- 市场格局逐渐稳定,头部效应更加明显
- 技术标准化和规范化进程加快
### 长期(5年以上)
- 行业渗透率大幅提升,成为经济增长重要引擎
- 技术创新方向从量变到质变
## 八、投资建议
### 核心标的
重点关注{first_player}等龙头企业
### 投资策略
1. 长期持有:布局核心资产,分享行业增长红利
2. 波段操作:把握技术迭代和政策红利窗口
3. 风险控制:分散投资,避免单一赛道集中
## 九、风险提示
### 行业风险
- 数据安全监管
- 人才短缺
- 商业化落地难度
### 市场风险
1. 宏观经济波动风险
2. 资本市场情绪变化风险
3. 国际形势变化风险
### 政策风险
1. 行业监管政策变化风险
2. 财政补贴政策调整风险
3. 国际贸易政策变化风险
*本报告由Multi-Agent智能研报系统自动生成,仅供参考,不构成投资建议*
"""
return report
except Exception as e:
return f"研报撰写出错:{str(e)}"
@tool
def report_review_tool(report: str) -> Dict[str, Any]:
"""
审核研报内容质量
参数:
report: Markdown格式的研报内容
返回:
包含审核结果和建议的字典
"""
# 审核维度
review_items = {
"完整性": all(section in report for section in ["行业概况", "发展驱动分析", "投资建议", "风险提示"]),
"准确性": "市场规模" in report and "增长率" in report,
"格式规范性": report.startswith("# ") and "## " in report,
"深度": "短期" in report and "中期" in report and "长期" in report,
"风险提示": "风险提示" in report and len(report.split("风险提示")[1]) > 100
}
# 生成审核结果
passed = all(review_items.values())
comments = []
if not review_items["完整性"]:
comments.append("研报缺少关键章节,请补充完整")
if not review_items["准确性"]:
comments.append("核心数据缺失,请检查数据收集环节")
if not review_items["格式规范性"]:
comments.append("格式不规范,请按照标准Markdown格式调整")
if not review_items["深度"]:
comments.append("分析深度不足,请补充不同时间维度的分析")
if not review_items["风险提示"]:
comments.append("风险提示不足,请补充详细的风险分析")
return {
"passed": passed,
"score": sum(review_items.values()) / len(review_items) * 100,
"comments": comments,
"review_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
}
return {
"data_collection": data_collection_tool,
"data_processing": data_processing_tool,
"report_writing": report_writing_tool,
"report_review": report_review_tool
}
def _init_agents(self):
"""初始化各Agent节点"""
# 3.1 研究员Agent
def researcher_agent(state: ReportState) -> ReportState:
"""研究员Agent:负责数据收集和预处理"""
print("\n🤵♂️ 研究员Agent开始工作...")
try:
# 解析用户请求
request_parts = state["user_request"].split("年")
state["year"] = request_parts[0].split("生成")[1]
state["industry"] = request_parts[1].split("行业")[0]
# 收集原始数据
raw_data = self.tools["data_collection"].invoke({
"industry": state["industry"],
"year": state["year"]
})
# 处理数据 - 传入industry和year参数
structured_data = self.tools["data_processing"].invoke({
"raw_data": raw_data,
"industry": state["industry"],
"year": state["year"]
})
# 更新状态
state["raw_data"] = raw_data
state["structured_data"] = structured_data
state["current_step"] = "data_completed"
state["messages"].append(f"研究员Agent:已完成{state['year']}年{state['industry']}行业数据收集和处理")
print("✅ 研究员Agent工作完成")
return state
except Exception as e:
state["error_info"] = f"研究员Agent出错:{str(e)}"
state["current_step"] = "error"
print(f"❌ 研究员Agent出错:{str(e)}")
return state
# 3.2 作家Agent
def writer_agent(state: ReportState) -> ReportState:
"""作家Agent:负责研报撰写"""
print("\n✍️ 作家Agent开始工作...")
try:
# 检查数据是否有效
if state["current_step"] != "data_completed":
raise Exception("数据准备未完成")
# 撰写研报
draft_report = self.tools["report_writing"].invoke({
"structured_data": state["structured_data"],
"industry": state["industry"],
"year": state["year"]
})
# 更新状态
state["draft_report"] = draft_report
state["current_step"] = "draft_completed"
state["messages"].append(f"作家Agent:已完成研报草稿撰写,字数:{len(draft_report)}")
print("✅ 作家Agent工作完成")
return state
except Exception as e:
state["error_info"] = f"作家Agent出错:{str(e)}"
state["current_step"] = "error"
print(f"❌ 作家Agent出错:{str(e)}")
return state
# 3.3 审核员Agent
def reviewer_agent(state: ReportState) -> ReportState:
"""审核员Agent:负责研报审核"""
print("\n🔍 审核员Agent开始工作...")
try:
# 检查草稿是否存在
if state["current_step"] != "draft_completed":
raise Exception("研报草稿未完成")
# 审核研报
review_result = self.tools["report_review"].invoke({
"report": state["draft_report"]
})
# 更新状态
state["review_comments"] = json.dumps(review_result, ensure_ascii=False, indent=2)
state["current_step"] = "review_completed"
if review_result["passed"]:
state["messages"].append(f"审核员Agent:研报审核通过,得分:{review_result['score']:.1f}分")
print(f"✅ 审核员Agent:研报审核通过({review_result['score']:.1f}分)")
else:
state["messages"].append(f"审核员Agent:研报审核未通过,问题:{'; '.join(review_result['comments'])}")
print(f"❌ 审核员Agent:研报审核未通过,问题:{'; '.join(review_result['comments'])}")
return state
except Exception as e:
state["error_info"] = f"审核员Agent出错:{str(e)}"
state["current_step"] = "error"
print(f"❌ 审核员Agent出错:{str(e)}")
return state
# 3.4 人类审核节点
def human_review_agent(state: ReportState) -> ReportState:
"""人类审核Agent:关键步骤人工确认"""
print("\n👤 进入人类审核环节...")
print("="*60)
print("请审核以下研报草稿:")
print("="*60)
# 修复:避免在f-string中使用反斜杠
draft_preview = state["draft_report"]
if len(draft_preview) > 1000:
print(draft_preview[:1000] + "...")
else:
print(draft_preview)
print("="*60)
# 模拟人工输入(实际项目可接入Web UI)
while True:
user_input = input("请输入审核结果(通过/修改/放弃):").strip()
if user_input in ["通过", "修改", "放弃"]:
break
print("无效输入,请输入:通过/修改/放弃")
# 更新状态
if user_input == "通过":
state["human_review_result"] = "approved"
state["current_step"] = "human_approved"
state["messages"].append("人类审核:通过")
print("✅ 人类审核通过")
elif user_input == "修改":
state["human_review_result"] = "needs_revision"
state["current_step"] = "draft_completed" # 返回作家修改
revision_comments = input("请输入修改意见:")
state["messages"].append(f"人类审核:需要修改,意见:{revision_comments}")
print("ℹ️ 人类要求修改,返回作家Agent")
else:
state["human_review_result"] = "abandoned"
state["current_step"] = "completed"
state["messages"].append("人类审核:放弃生成")
print("🛑 人类选择放弃,任务终止")
return state
# 3.5 总控Agent
def manager_agent(state: ReportState) -> ReportState:
"""总控Agent:负责最终结果汇总"""
print("\n👔 总控Agent开始工作...")
try:
# 生成最终研报
final_report = f"""# {state['year']}年{state['industry']}行业研报(最终版)
**生成时间**:{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}
**生成方式**:Multi-Agent智能协作
**审核状态**:审核通过({json.loads(state['review_comments'])['score']:.1f}分)
{state['draft_report']}
## 生成说明
本研报由Multi-Agent系统自动生成:
1. 研究员Agent:负责{state['year']}年{state['industry']}行业数据收集和预处理
2. 作家Agent:基于结构化数据撰写研报正文
3. 审核员Agent:对研报质量进行多维度审核
4. 人类专家:关键环节人工审核确认
## 版本信息
- 数据版本:{json.loads(state['raw_data'])['update_time']}
- 审核得分:{json.loads(state['review_comments'])['score']:.1f}分
- 最终版本:V1.0
"""
# 更新状态
state["final_report"] = final_report
state["current_step"] = "completed"
state["is_completed"] = True
state["messages"].append("总控Agent:研报生成完成,已输出最终版本")
print("✅ 总控Agent工作完成")
return state
except Exception as e:
state["error_info"] = f"总控Agent出错:{str(e)}"
state["current_step"] = "error"
print(f"❌ 总控Agent出错:{str(e)}")
return state
return {
"researcher": researcher_agent,
"writer": writer_agent,
"reviewer": reviewer_agent,
"human_review": human_review_agent,
"manager": manager_agent
}
def _build_graph(self) -> Any:
"""构建LangGraph多Agent系统"""
print("📊 开始构建LangGraph多Agent系统...")
# 初始化Agent
self.agents = self._init_agents()
# 创建状态图
workflow = StateGraph(ReportState)
# 添加节点
workflow.add_node("researcher", self.agents["researcher"])
workflow.add_node("writer", self.agents["writer"])
workflow.add_node("reviewer", self.agents["reviewer"])
workflow.add_node("human_review", self.agents["human_review"])
workflow.add_node("manager", self.agents["manager"])
# 设置起始节点
workflow.set_entry_point("researcher")
# 定义路由函数
def router(state: ReportState) -> str:
"""路由函数:控制流程流转"""
current_step = state.get("current_step", "")
# 错误处理
if current_step == "error":
return END
# 正常流程
if current_step == "":
return "researcher"
elif current_step == "data_completed":
return "writer"
elif current_step == "draft_completed":
return "reviewer"
elif current_step == "review_completed":
return "human_review"
elif current_step == "human_approved":
return "manager"
elif current_step == "completed":
return END
else:
return END
# 添加条件边
workflow.add_conditional_edges("researcher", router, {
"writer": "writer",
END: END
})
workflow.add_conditional_edges("writer", router, {
"reviewer": "reviewer",
END: END
})
workflow.add_conditional_edges("reviewer", router, {
"human_review": "human_review",
END: END
})
workflow.add_conditional_edges("human_review", router, {
"manager": "manager",
"writer": "writer", # 需要修改时返回作家
END: END
})
workflow.add_conditional_edges("manager", router, {
END: END
})
# 编译图
app = workflow.compile()
print("✅ LangGraph多Agent系统构建完成")
return app
def run(self, user_request: str) -> Dict[str, Any]:
"""
运行Multi-Agent研报生成系统
参数:
user_request: 用户请求字符串,如"生成2026年AI行业研报"
返回:
包含最终研报的结果字典
"""
print("\n🚀 启动Multi-Agent研报生成系统...")
print(f"📝 用户请求:{user_request}")
# 初始状态
initial_state = ReportState(
messages=[f"用户请求:{user_request}"],
user_request=user_request,
industry="",
year="",
raw_data="",
structured_data="",
draft_report="",
review_comments="",
human_review_result="",
final_report="",
current_step="",
error_info="",
is_completed=False
)
# 配置
config = RunnableConfig()
config["configurable"] = {"thread_id": f"report_{datetime.now().strftime('%Y%m%d%H%M%S')}"}
try:
# 执行多Agent系统
result = self.app.invoke(initial_state, config)
# 返回结果
return {
"success": result["is_completed"],
"final_report": result.get("final_report", ""),
"error_info": result.get("error_info", ""),
"industry": result.get("industry", ""),
"year": result.get("year", ""),
"execution_log": result["messages"]
}
except Exception as e:
error_msg = f"系统执行出错:{str(e)}"
print(f"\n❌ {error_msg}")
return {
"success": False,
"final_report": "",
"error_info": error_msg,
"industry": "",
"year": "",
"execution_log": [error_msg]
}
# ===================== 4. 运行完整系统 =====================
if __name__ == "__main__":
# 初始化系统
print("="*60)
print("Multi-Agent行业研报自动生成系统")
print("="*60)
system = ReportAgentSystem()
# 用户请求
user_request = "生成2026年AI行业研报"
# 运行系统
result = system.run(user_request)
# 输出结果
print("\n" + "="*60)
print("系统执行结果")
print("="*60)
if result["success"]:
print(f"✅ 研报生成成功!")
print(f"📋 行业:{result['industry']}")
print(f"📅 年份:{result['year']}")
print("\n📄 最终研报:")
print("-"*60)
print(result["final_report"])
# 保存研报到文件
filename = f"{result['year']}年{result['industry']}行业研报.md"
with open(filename, "w", encoding="utf-8") as f:
f.write(result["final_report"])
print(f"\n💾 研报已保存到文件:{filename}")
else:
print(f"❌ 研报生成失败:{result['error_info']}")
print("\n📜 执行日志:")
for log in result["execution_log"]:
print(f"- {log}")
print("\n✅ 系统运行结束")
运行结果:
============================================================
Multi-Agent行业研报自动生成系统
============================================================
📊 开始构建LangGraph多Agent系统...
✅ LangGraph多Agent系统构建完成
✅ 研报生成Multi-Agent系统初始化完成
🚀 启动Multi-Agent研报生成系统...
📝 用户请求:生成2026年AI行业研报
🤵♂️ 研究员Agent开始工作...
✅ 研究员Agent工作完成
✍️ 作家Agent开始工作...
✅ 作家Agent工作完成
🔍 审核员Agent开始工作...
✅ 审核员Agent:研报审核通过(100.0分)
👤 进入人类审核环节...
============================================================
请审核以下研报草稿:
============================================================
# 2026年AI行业深度研报
**报告生成时间**:2026-03-24 09:57:37
**报告生成系统**:Multi-Agent智能研报系统
## 一、行业概况
- 市场规模:1.2万亿元
- 年增长率:25%
- 头部企业:字节跳动, 百度, 阿里, 腾讯, 商汤科技
## 二、发展驱动分析
- 大模型应用落地
- 政企数字化转型
- 算力基础设施完善
## 三、行业挑战分析
- 数据安全监管
- 人才短缺
- 商业化落地难度
## 四、投资机会分析
- Agent架构
- 多模态大模型
- 行业垂直解决方案
## 五、区域市场分析
- 北上广深:占市场份额70%
- 长三角:增速最快,年增长30%
- 中西部:潜力巨大,基础薄弱
## 六、竞争格局分析
### 头部企业分析
字节跳动, 百度, 阿里, 腾讯, 商汤科技等头部企业占据主要市场份额,技术和资金优势明显。
### 竞争特点
1. 技术壁垒逐渐提高,中小企业生存空间收窄
2. 跨界竞争加剧,互联网/科技企业入局
3. 产业链整合加速,纵向一体化趋势明显
## 七、未来展望
### 短期(1-2年)
- 行业将保持高速增长,预计增长率25%
- 技术落地加速,商业化应用场景增多
### 中期(3-5年)
- 市场格局逐渐稳定,头部效应更加明显
- 技术标准化和规范化进程加快
### 长期(5年以上)
- 行业渗透率大幅提升,成为经济增长重要引擎
- 技术创新方向从量变到质变
## 八、投资建议
### 核心标的
重点关注字节跳动, 百度, 阿里, 腾讯, 商汤科技等龙头企业
### 投资策略
1. 长期持有:布局核心资产,分享行业增长红利
2. 波段操作:把握技术迭代和政策红利窗口
3. 风险控制:分散投资,避免单一赛道集中
## 九、风险提示
### 行业风险
- 数据安全监管
- 人才短缺
- 商业化落地难度
### 市场风险
1. 宏观经济波动风险
2. 资本市场情绪变化风险
3. 国际形势变化风险
### 政策风险
1. 行业监管政策变化风险
2. 财政补贴政策调整风险
3. 国际贸易政策变化风险
*本报告由Multi-Agent智能研报系统自动生成,仅供参考,不构成投资建议*
============================================================
请输入审核结果(通过/修改/放弃):通过
✅ 人类审核通过
👔 总控Agent开始工作...
✅ 总控Agent工作完成
============================================================
系统执行结果
============================================================
✅ 研报生成成功!
📋 行业:AI
📅 年份:2026
📄 最终研报:
------------------------------------------------------------
# 2026年AI行业研报(最终版)
**生成时间**:2026-03-24 09:57:47
**生成方式**:Multi-Agent智能协作
**审核状态**:审核通过(100.0分)
# 2026年AI行业深度研报
**报告生成时间**:2026-03-24 09:57:37
**报告生成系统**:Multi-Agent智能研报系统
## 一、行业概况
- 市场规模:1.2万亿元
- 年增长率:25%
- 头部企业:字节跳动, 百度, 阿里, 腾讯, 商汤科技
## 二、发展驱动分析
- 大模型应用落地
- 政企数字化转型
- 算力基础设施完善
## 三、行业挑战分析
- 数据安全监管
- 人才短缺
- 商业化落地难度
## 四、投资机会分析
- Agent架构
- 多模态大模型
- 行业垂直解决方案
## 五、区域市场分析
- 北上广深:占市场份额70%
- 长三角:增速最快,年增长30%
- 中西部:潜力巨大,基础薄弱
## 六、竞争格局分析
### 头部企业分析
字节跳动, 百度, 阿里, 腾讯, 商汤科技等头部企业占据主要市场份额,技术和资金优势明显。
### 竞争特点
1. 技术壁垒逐渐提高,中小企业生存空间收窄
2. 跨界竞争加剧,互联网/科技企业入局
3. 产业链整合加速,纵向一体化趋势明显
## 七、未来展望
### 短期(1-2年)
- 行业将保持高速增长,预计增长率25%
- 技术落地加速,商业化应用场景增多
### 中期(3-5年)
- 市场格局逐渐稳定,头部效应更加明显
- 技术标准化和规范化进程加快
### 长期(5年以上)
- 行业渗透率大幅提升,成为经济增长重要引擎
- 技术创新方向从量变到质变
## 八、投资建议
### 核心标的
重点关注字节跳动, 百度, 阿里, 腾讯, 商汤科技等龙头企业
### 投资策略
1. 长期持有:布局核心资产,分享行业增长红利
2. 波段操作:把握技术迭代和政策红利窗口
3. 风险控制:分散投资,避免单一赛道集中
## 九、风险提示
### 行业风险
- 数据安全监管
- 人才短缺
- 商业化落地难度
### 市场风险
1. 宏观经济波动风险
2. 资本市场情绪变化风险
3. 国际形势变化风险
### 政策风险
1. 行业监管政策变化风险
2. 财政补贴政策调整风险
3. 国际贸易政策变化风险
*本报告由Multi-Agent智能研报系统自动生成,仅供参考,不构成投资建议*
## 生成说明
本研报由Multi-Agent系统自动生成:
1. 研究员Agent:负责2026年AI行业数据收集和预处理
2. 作家Agent:基于结构化数据撰写研报正文
3. 审核员Agent:对研报质量进行多维度审核
4. 人类专家:关键环节人工审核确认
## 版本信息
- 数据版本:2026-03-24 09:57:37
- 审核得分:100.0分
- 最终版本:V1.0
💾 研报已保存到文件:2026年AI行业研报.md
✅ 系统运行结束
6.3 代码详细解释
(一)、整体架构总览
本例是一个 基于LangGraph的多智能体(Multi-Agent)工作流,一共5个智能体,按固定流程协作生成一份专业行业研报:
- 研究员 Agent:爬取/读取行业原始数据 → 结构化
- 作家 Agent:根据数据生成完整研报草稿
- 审核员 Agent:自动审核研报质量(完整性、准确性、格式)
- 人类审核 Agent:人工确认/修改/放弃
- 总控 Agent:生成最终版研报并保存文件
工作流由 状态(ReportState) 全程共享数据,由 路由(router) 控制跳转。
(二)、代码逐模块超详细解释
1)依赖导入部分
python
from langchain_ollama import ChatOllama # 本地大模型调用
from langchain_core.tools import tool # 工具装饰器,封装函数
from langgraph.graph import StateGraph, END # 构建工作流
from typing import TypedDict # 定义状态结构
import json, datetime # 数据与时间
作用:
- ChatOllama:连接本地 Ollama 模型
- tool:把普通函数包装成 Agent 可调用的工具
- StateGraph:构建多步骤、可跳转的工作流
- TypedDict:定义统一状态,让所有 Agent 共享数据
2)核心:ReportState 共享状态(最重要)
python
class ReportState(TypedDict):
# 基础信息
messages: Annotated[Sequence[str], add_messages]
user_request: str
industry: str
year: str
# 各阶段成果
raw_data: str # 原始JSON数据
structured_data: str # 整理后的文本数据
draft_report: str # 研报草稿
review_comments: str # 审核意见
final_report: str # 最终研报
# 流程控制
current_step: str # 当前步骤(控制流向)
error_info: str
is_completed: bool
作用解释
这是整个系统的"共享黑板":
- 所有 Agent 都从这里读数据
- 所有 Agent 都把结果写回这里
current_step是工作流的"红绿灯",决定下一步去哪里
3)系统主类 ReportAgentSystem
python
class ReportAgentSystem:
def __init__(self):
self.llm = ChatOllama(...) # 初始化模型
self.tools = self._init_tools() # 初始化4个工具
self.app = self._build_graph() # 构建工作流
解释
__init__启动时一次性加载所有工具与流程- 系统运行时直接调用
app.invoke()执行流程
4)四大工具详解(底层能力)
系统共有 4 个工具函数 ,由 @tool 包装,供 Agent 调用:
① 数据收集工具
python
@tool
def data_collection_tool(industry: str, year: str) -> str:
功能:
- 输入:行业 + 年份
- 输出:模拟的行业 JSON 数据
- 实际项目可替换成:数据库/Excel/API/爬虫
② 数据处理工具
python
@tool
def data_processing_tool(raw_data: str, industry: str, year: str) -> str:
功能:
- 把 JSON 原始数据 → 转成可读的 Markdown 结构
- 供作家 Agent 直接使用
③ 研报撰写工具
python
@tool
def report_writing_tool(...) -> str:
功能:
- 真正生成整篇研报
- 自动拆分:概况、驱动、挑战、投资、区域、格局、展望、建议、风险
④ 研报审核工具
python
@tool
def report_review_tool(report: str) -> Dict:
功能:
- 自动检查 5 个维度:
完整性、准确性、格式、深度、风险提示 - 输出:是否通过 + 得分 + 意见
5)五大 Agent 详解(工作流执行者)
① 研究员 Agent
python
def researcher_agent(state: ReportState) -> ReportState:
任务:
- 解析用户指令:
生成2026年AI行业研报
→ 提取year=2026industry=AI - 调用数据工具获取原始数据
- 调用处理工具生成结构化数据
- 将结果存入
state,并标记步骤完成 - 返回 state 给工作流
② 作家 Agent
任务:
- 读取结构化数据
- 调用撰写工具生成完整研报草稿
- 存入
draft_report
③ 审核员 Agent
任务:
- 读取草稿
- 自动审核
- 存入审核意见与评分
④ 人类审核 Agent
任务:
- 打印草稿预览
- 让用户输入:通过 / 修改 / 放弃
- 根据输入控制流程走向
⑤ 总控 Agent
任务:
- 生成最终版报告(带版本、时间、审核信息)
- 标记任务完成
- 供主程序保存文件
6)工作流路由函数(大脑)
python
def router(state: ReportState) -> str:
current_step = state["current_step"]
if current_step == "data_completed": return "writer"
if current_step == "draft_completed": return "reviewer"
if current_step == "review_completed":return "human_review"
if current_step == "human_approved": return "manager"
return END
解释
这是整个系统的调度中心 ,根据 current_step 决定下一步跳哪个 Agent。
7)构建工作流图
python
workflow = StateGraph(ReportState)
workflow.add_node("researcher", researcher)
workflow.add_node("writer", writer)
...
workflow.set_entry_point("researcher")
workflow.add_conditional_edges(...)
app = workflow.compile()
解释
add_node:添加一个 Agent 节点set_entry_point:从研究员开始conditional_edges:根据路由动态跳转compile:编译成可运行程序
8)系统运行入口
python
result = system.run("生成2026年AI行业研报")
- 输入用户指令
- 执行完整工作流
- 返回最终研报
- 自动保存
.md文件
(三)、LangGraph 工作流流程图
data_completed
draft_completed
review_completed
通过
修改
放弃
开始
研究员Agent
数据收集+处理
路由判断
作家Agent
生成研报草稿
路由判断
审核员Agent
自动审核
路由判断
人类审核
通过/修改/放弃
总控Agent
生成最终版
结束
保存文件
简化文字版流程
开始 → 研究员 → 作家 → 审核员 → 人类审核 → 总控 → 保存 → 结束
↑ ↓
(可返回修改)
(四)、关键亮点小结
- 状态共享 :所有 Agent 使用同一套
ReportState,无需传参混乱 - 工具解耦:数据、撰写、审核、处理完全独立,易维护
- 人工介入(Human-in-the-loop):关键步骤必须人工确认
- 自动审核:保证研报质量稳定
- 工作流可视化:流程清晰,可扩展、可调试
- 本地部署:完全本地运行,不依赖外部 API
七、避坑指南:高级Agent架构的6个核心陷阱

坑点1:规划步骤过于抽象,无法执行
python
# ❌ 错误:规划步骤抽象,无具体操作
# Planner输出:"1. 收集数据 2. 写报告 3. 审核"
# ✅ 正确:规划步骤具体,包含工具调用
# Planner输出:"""
# 1. 调用collect_industry_data工具,参数:industry="AI", year="2026"
# 2. 调用write_industry_report工具,参数:data=步骤1结果, format="markdown"
# 3. 调用review_report工具,参数:report=步骤2结果
# """
避坑建议:
- 规划步骤要包含具体的工具调用和参数;
- 使用示例引导Planner生成可执行的步骤;
- 对规划结果进行验证,确保每个步骤都可执行。
解决:在 Planner 的 Prompt 中明确要求输出具体的工具调用格式。
坑点2:多Agent通信开销大,延迟高
python
# ❌ 错误:每个Agent都重新初始化LLM,通信频繁
def agent1():
llm = ChatOllama(model="qwen2_5-7b-q6") # 重复初始化
# 频繁的消息传递
# ✅ 正确:共享LLM实例,批量处理消息
class SharedLLM:
_instance = None
@classmethod
def get_instance(cls):
if cls._instance is None:
cls._instance = ChatOllama(model="qwen2_5-7b-q6")
return cls._instance
# 所有Agent共享同一个LLM实例
llm = SharedLLM.get_instance()
避坑建议:
- 共享LLM实例,避免重复初始化;
- 批量处理消息,减少通信次数;
- 合理设计状态结构,避免冗余数据传输;
- 对非关键信息进行缓存。
坑点3:状态管理混乱,导致信息丢失
python
# ❌ 错误:状态分散管理,信息不同步
agent1_data = {}
agent2_data = {}
# ✅ 正确:集中式状态管理
class AgentState(TypedDict):
"""统一的状态结构"""
data: str
report: str
review: str
# 所有需要共享的状态
# 所有Agent操作同一个状态对象
def agent1(state: AgentState) -> AgentState:
state["data"] = "收集的数据"
return state
def agent2(state: AgentState) -> AgentState:
# 使用state["data"]
return state
避坑建议:
- 使用TypedDict定义清晰的状态结构;
- 所有Agent操作同一个状态对象;
- 关键状态变更添加日志;
- 状态更新采用不可变模式,便于回溯。
坑点4:Agent角色混淆,职责不清
python
# ❌ 错误:Agent既做数据收集又做审核
def all_in_one_agent(state):
# 收集数据
# 撰写报告
# 审核报告
return state
# ✅ 正确:单一职责原则
def researcher_agent(state):
# 只做数据收集
return state
def reviewer_agent(state):
# 只做审核
return state
避坑建议:
- 遵循单一职责原则,每个Agent只负责一类任务;
- 明确Agent之间的依赖关系;
- 避免Agent越权操作其他Agent的职责范围;
- 使用角色提示词强化Agent的职责意识。
坑点5:缺乏异常处理,单个Agent出错导致系统崩溃
python
# ❌ 错误:无异常处理
def agent(state):
data = collect_data() # 可能出错
state["data"] = data
return state
# ✅ 正确:完善的异常处理
def agent(state):
try:
data = collect_data()
state["data"] = data
state["error"] = ""
except Exception as e:
state["data"] = ""
state["error"] = f"收集数据出错:{str(e)}"
return state
# 路由函数处理异常
def router(state):
if state["error"]:
return "error_handler" # 错误处理节点
return "next_agent"
避坑建议:
- 每个Agent添加try-except异常处理;
- 状态中记录错误信息;
- 路由函数识别错误状态,跳转到错误处理节点;
- 关键节点添加重试机制。
坑点6:Human-in-the-loop实现不当,影响自动化效率
python
# ❌ 错误:过多的人工介入点
def router(state):
# 每个步骤都需要人工确认
return "human_review"
# ✅ 正确:关键节点才需要人工介入
def router(state):
if state["current_step"] == "review_completed":
return "human_review" # 只在审核后人工确认
return "next_agent"
避坑建议:
- 只在关键节点设置人类介入;
- 对简单问题自动处理,复杂问题才人工介入;
- 人工审核提供明确的操作选项,避免模糊输入;
- 记录人工操作,逐步减少人工介入。
八、高频面试题:高级Agent架构核心考点

Q1:简述Plan-and-Execute架构的核心原理和优势
参考答案 :
Plan-and-Execute是将Agent分为Planner(规划器)和Executor(执行器)两个独立模块的架构:
- Planner:负责拆解复杂任务,制定详细的执行计划,相当于项目经理;
- Executor:负责执行Planner制定的每一个具体步骤,相当于执行员工。
核心优势:
- 全局规划能力:先制定完整计划再执行,避免走一步看一步的盲目性;
- 任务完整性:确保所有步骤都被执行,不易遗漏关键环节;
- 可解释性:执行计划清晰可见,便于理解和调试;
- 灵活性:执行过程中可根据实际情况调整计划;
- 适合复杂任务:能有效处理多步骤、有依赖关系的复杂任务。
- ReAct:边思考边行动,每步都调用 LLM 决策;
- Plan-and-Execute:先一次性规划所有步骤,再逐步执行;
- 适用场景:ReAct 适合简单任务,Plan-and-Execute 适合复杂多步任务。
相比纯ReAct架构,Plan-and-Execute更适合中等复杂度的任务,任务完成度和可预测性更高。
Q2:Multi-Agent相比单Agent有哪些核心优势?
参考答案 :
Multi-Agent(多智能体)系统相比单Agent的核心优势包括:
- 角色分工:每个Agent专注于特定领域,专业性更强,任务质量更高;
- 并行处理:多个Agent可同时执行不同任务,提升整体效率;
- 容错性高:单个Agent出错不会导致整个系统崩溃,可针对性处理;
- 可扩展性好:可根据需求灵活增减Agent节点;
- 状态共享:Agent之间共享状态,信息流转顺畅;
- Human-in-the-loop:易于引入人类介入机制,平衡自动化和准确性;
- 模拟人类协作:更贴近真实世界的工作方式,适合处理复杂的企业级任务。
Multi-Agent系统特别适合高复杂度、多角色、长周期的任务,是Agent从实验室走向实际应用的关键架构。
Q3:LangGraph在Multi-Agent系统中的核心价值是什么?
参考答案 :
LangGraph作为新一代Agent编排框架,在Multi-Agent系统中的核心价值体现在:
- 状态管理:提供统一的状态管理机制,确保Agent之间信息共享和同步;
- 流程可视化:将Multi-Agent的协作流程抽象为图结构,便于理解和调试;
- 灵活的流转控制:通过Edges和路由函数实现复杂的流程控制逻辑;
- 循环执行能力:支持循环执行,可处理需要迭代的任务;
- 可扩展性:易于添加新的Agent节点和流转规则;
- 与LangChain生态无缝集成:可直接使用LangChain的工具、LLM和Agent组件;
- 可观测性:提供完整的执行日志,便于监控和问题定位。
LangGraph解决了传统Multi-Agent系统中流程混乱、状态管理复杂、难以扩展的问题,是构建生产级Multi-Agent系统的首选框架。
Q4:LangGraph 的核心概念有哪些?
参考答案:
- State:共享状态,所有节点共享;
- Nodes:节点,每个 Agent 或工具;
- Edges:边,定义流转关系;
- Conditional Edges:条件边,根据状态决定下一步;
- Graph:图,整个工作流。
Q5:如何实现多 Agent 协作?
参考答案:
- 角色分工:研究员、作家、审核员等;
- 协调机制:协调员 Agent 负责调度;
- 状态共享:通过共享状态传递信息;
- 循环审核:审核不通过则返回修改。
总结
1. 核心知识点速记口诀
单 Agent 有局限,长程规划易跑偏;
Plan-and-Execute,先想后做不混乱;
LangGraph 是图编排,节点边和条件边;
Multi-Agent 分工明,研究员作家审核员;
人类介入防误判,关键步骤要确认;
研报系统是实战,整合三者才完善。
2. 架构演进路径
单 Agent (ReAct)
↓ 需要长程规划
Plan-and-Execute
↓ 需要动态调整
LangGraph (图编排)
↓ 需要分工协作
Multi-Agent
↓ 需要质量把控
Human-in-the-loop
3. 核心价值
高级 Agent 架构的终极目标是让 AI 能够独立完成复杂任务,从"对话工具"进化为"任务执行者"。Plan-and-Execute 解决了长程规划问题,LangGraph 提供了灵活的编排能力,Multi-Agent 实现了专业分工,Human-in-the-loop 保证了安全可控。

写在最后
从单 Agent 到 Plan-and-Execute,再到 Multi-Agent 和 LangGraph,Agent 架构的演进本质上是在解决一个核心问题:如何让 AI 更可靠地完成复杂任务。
Plan-and-Execute 让我们告别了"走一步看一步"的盲目执行;LangGraph 让我们能够用图的方式灵活编排复杂流程;Multi-Agent 让专业的人做专业的事;Human-in-the-loop 则在关键时刻保留了人的判断权。
在实际开发中,没有"最好"的架构,只有"最适合"的架构。简单的任务用 ReAct 就够了,中等复杂度的任务用 Plan-and-Execute,复杂的生产级系统则需要 LangGraph + Multi-Agent 的组合。
记住:架构的选择取决于任务的复杂度和对可靠性的要求------从简单开始,按需升级,才是工程化的正确路径。