STORM范式概述
STORM(Structured Topic-based Outline and Research Machine)是一个由大型语言模型(LLM)驱动的自动化研究与内容生成框架,最初由Stanford OVAL实验室提出,用于从零开始生成类似维基百科的文章。在LangGraph的实现中,STORM被重构为一个基于LangGraph的多智能体工作流,结合LangChain生态的工具,强调结构化研究和内容生成。
STORM 主要包含以下几个阶段:
生成初步提纲 + 调研相关主题
识别独特视角
“访谈主题专家”
完善提纲(参考文献)
撰写章节,然后撰写文章
专家访谈阶段由角色扮演文章作者和研究专家进行。“专家”能够查询外部知识并回答尖锐问题,并将引用的来源保存到向量存储中,以便后续的完善阶段能够合成完整的文章。

STORM范式是一种多智能体协作的典型实现,核心目标是通过分解任务、调用外部工具和迭代优化,生成高质量、带引用的研究文章。其设计理念可以总结为:
- 任务分解:将复杂的研究和写作任务分解为多个子任务(如主题探索、大纲生成、内容撰写)。
- 多智能体协作:通过LangGraph的状态图(StateGraph)定义不同智能体角色(如研究员、写作者),实现协作。
- 外部工具集成:利用搜索引擎(如Tavily)获取实时信息,增强内容的全面性和准确性。
- 迭代优化:通过多轮对话和反馈,逐步完善大纲和文章内容。

1.2 STORM范式的核心组件
- 主题探索(Topic Exploration):
- 通过与LLM对话,生成与主题相关的关键问题,扩展研究方向。
- 调用外部搜索引擎(如Tavily)收集参考资料。
- 大纲生成(Outline Generation):
- 基于主题和搜索结果,生成结构化的大纲,包含主要章节和子主题。
- 通过多角度提问,确保大纲覆盖主题的多个方面。
- 内容生成(Content Generation):
- 根据大纲,逐章节生成文章内容,并为每部分添加引用。
- 通过LLM的润色功能,提升内容的逻辑性和可读性。
- 多智能体工作流:
- 使用LangGraph的状态图管理不同智能体的协作,例如“研究员”负责信息收集,“写作者”负责内容生成。
- 状态图维护全局状态(如主题、搜索结果、大纲、文章),确保任务连贯性。
1.3 STORM范式的AI Agent特性
- 多智能体架构:通过LangGraph的StateGraph,定义多个智能体角色,每个角色专注于特定任务(如搜索、生成),实现协作。
- 状态管理:LangGraph的状态图维护任务的全局状态(如当前大纲、文章内容),支持动态更新和条件分支。
- 工具调用:通过LangChain的工具调用机制,集成外部API(如Tavily搜索),增强Agent的环境感知能力。
- 迭代推理:通过多轮对话和反馈,STORM模拟专家讨论,逐步优化输出,类似于Agent的自我反思(self-reflection)。
- 模块化设计:LangGraph的工作流允许开发者自定义智能体、工具或Prompt,适合不同应用场景。
1.4 STORM范式与AI Agent开发的关联
- 多智能体协作:通过定义不同角色(如研究员、写作者),实现复杂任务的分工协作,适合构建分布式Agent系统。
- 状态驱动的工作流:LangGraph的状态图提供了一种声明式的工作流定义方式,开发者可以用类似方法管理Agent的状态和决策。
- 工具集成:STORM通过Tavily搜索API获取实时数据,开发者可扩展为更多工具(如数据库、知识图谱)以增强功能。
- Prompt工程:STORM依赖精心设计的Prompt模板,开发者可以借鉴其结构化Prompt设计,优化Agent的输出质量。
- 可扩展性:LangGraph的模块化设计允许开发者替换LLM、工具或工作流逻辑,适配特定需求。
以下开始进行主要的源代码解释
数据结构定义
STORM 的工作流需要维护一个状态对象,用于在节点间传递数据。代码定义了 StormState 作为状态类型:
from typing import TypedDict, List, Dict, Optional
class StormState(TypedDict):
topic: str
initial_research: Dict
perspectives: List[Dict]
questions: List[Dict]
search_results: List[Dict]
outline: Dict
article: Dict
- topic: 输入的主题(如“人工智能的历史”)。
- initial_research: 初步研究结果,包含主题概述和背景信息。
- perspectives: 主题的多视角列表(如历史、技术、伦理)。
- questions: 为每个视角生成的提问,用于指导检索。
- search_results: 检索工具返回的相关信息。
- outline: 文章大纲,包含章节和子章节。
- article: 最终生成的文章内容。
这种状态设计符合 LangGraph 的状态图理念,允许节点更新和传递复杂的数据结构。
2.3 核心组件与工作流
STORM 的实现分为多个节点,每个节点负责工作流的一个阶段。以下是主要节点的分析:
2.3.1 初步研究(Initial Research)
第一步是理解输入主题并生成初步研究。代码定义了一个 initial_research 节点:
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
llm = ChatOpenAI(model="gpt-4o", temperature=0.7)
initial_research_prompt = ChatPromptTemplate.from_template(
"""You are a research assistant tasked with providing a brief overview of {topic}.
Provide a concise summary (100-150 words) and identify 3-5 key perspectives for further exploration.
Format the output as:
<summary>...</summary>
<perspectives>...</perspectives>
"""
)
initial_research_chain = initial_research_prompt | llm | StrOutputParser()
def initial_research(state: StormState):
topic = state["topic"]
result = initial_research_chain.invoke({"topic": topic})
summary = re.search(r"<summary>(.*?)</summary>", result, re.DOTALL).group(1).strip()
perspectives = re.search(r"<perspectives>(.*?)</perspectives>", result, re.DOTALL).group(1).strip()
return {
"initial_research": {"summary": summary},
"perspectives": [{"name": p.strip()} for p in perspectives.split("\n") if p.strip()]
}
- Prompt: 要求 LLM 生成主题的简要概述(100-150 字)和 3-5 个关键视角。
- Output Parser: 使用正则表达式提取 <summary> 和 <perspectives>。
- Node: initial_research 更新状态中的 initial_research 和 perspectives 字段。
2.3.2 视角提问(Generate Questions)
第二步是为每个视角生成具体问题,指导后续检索。代码定义了一个 generate_questions 节点:
question_prompt = ChatPromptTemplate.from_template(
"""Given the topic '{topic}' and perspective '{perspective}',
generate 2-3 specific questions to guide research.
Format the output as:
<questions>...</questions>
"""
)
question_chain = question_prompt | llm | StrOutputParser()
def generate_questions(state: StormState):
topic = state["topic"]
perspectives = state["perspectives"]
questions = []
for perspective in perspectives:
result = question_chain.invoke({"topic": topic, "perspective": perspective["name"]})
q_list = re.search(r"<questions>(.*?)</questions>", result, re.DOTALL).group(1).strip()
questions.append({"perspective": perspective["name"], "questions": q_list.split("\n")})
return {"questions": questions}
- Prompt: 为每个视角生成 2-3 个具体问题。
- Node: generate_questions 遍历视角,生成问题列表,更新状态中的 questions 字段。
2.3.3 信息检索(Search)
第三步是使用检索工具获取相关信息。代码集成了维基百科作为检索工具:
from langchain_community.utilities import WikipediaAPIWrapper
wikipedia = WikipediaAPIWrapper()
def search(state: StormState):
questions = state["questions"]
search_results = []
for q_group in questions:
perspective = q_group["perspective"]
for question in q_group["questions"]:
try:
result = wikipedia.run(question)
search_results.append({"perspective": perspective, "question": question, "result": result})
except:
search_results.append({"perspective": perspective, "question": question, "result": "No results found"})
return {"search_results": search_results}
- Tool: 使用 WikipediaAPIWrapper 执行检索,基于生成的提问。
- Node: search 遍历每个视角的问题,调用维基百科 API,收集结果并更新状态中的 search_results。
- Error Handling: 简单处理检索失败的情况,返回“No results found”。
2.3.4 大纲生成(Generate Outline)
第四步是基于检索结果和初步研究生成文章大纲:
outline_prompt = ChatPromptTemplate.from_template(
"""Given the topic '{topic}', initial research, perspectives, and search results,
generate a structured article outline.
Format the output as:
<outline>
<section>...</section>
<section>...</section>
</outline>
"""
)
outline_chain = outline_prompt | llm | StrOutputParser()
def generate_outline(state: StormState):
topic = state["topic"]
initial_research = state["initial_research"]
perspectives = state["perspectives"]
search_results = state["search_results"]
result = outline_chain.invoke({
"topic": topic,
"initial_research": initial_research,
"perspectives": perspectives,
"search_results": search_results
})
outline = re.search(r"<outline>(.*?)</outline>", result, re.DOTALL).group(1).strip()
return {"outline": {"sections": outline.split("\n")}}
- Prompt: 要求 LLM 整合所有信息,生成结构化大纲。
- Node: generate_outline 更新状态中的 outline 字段,包含章节列表。
2.3.5 文章生成(Generate Article)
最后一步是生成完整文章:
article_prompt = ChatPromptTemplate.from_template(
"""Given the topic '{topic}', outline, and research data,
write a detailed article (300-500 words).
Format the output as:
<article>...</article>
"""
)
article_chain = article_prompt | llm | StrOutputParser()
def generate_article(state: StormState):
topic = state["topic"]
outline = state["outline"]
initial_research = state["initial_research"]
search_results = state["search_results"]
result = article_chain.invoke({
"topic": topic,
"outline": outline,
"initial_research": initial_research,
"search_results": search_results
})
article = re.search(r"<article>(.*?)</article>", result, re.DOTALL).group(1).strip()
return {"article": {"content": article}}
- Prompt: 要求 LLM 基于大纲和研究数据生成文章。
- Node: generate_article 更新状态中的 article 字段。
2.4 状态图构建
LangGraph 的核心是 StateGraph,代码将其用于协调上述步骤:
from langgraph.graph import StateGraph, END
workflow = StateGraph(StormState)
workflow.add_node("initial_research", initial_research)
workflow.add_node("generate_questions", generate_questions)
workflow.add_node("search", search)
workflow.add_node("generate_outline", generate_outline)
workflow.add_node("generate_article", generate_article)
workflow.set_entry_point("initial_research")
workflow.add_edge("initial_research", "generate_questions")
workflow.add_edge("generate_questions", "search")
workflow.add_edge("search", "generate_outline")
workflow.add_edge("generate_outline", "generate_article")
workflow.add_edge("generate_article", END)
graph = workflow.compile()
- Nodes: 五个节点分别对应初步研究、提问生成、检索、大纲生成和文章生成。
- Edges: 定义了线性执行顺序:initial_research -> generate_questions -> search -> generate_outline -> generate_article -> END.
- Compilation: workflow.compile() 生成可执行的 LangGraph 图。
2.5 示例运行
代码提供了一个示例主题并运行工作流:
state = {"topic": "The History of Artificial Intelligence"}
result = graph.invoke(state)
print("Outline:")
for section in result["outline"]["sections"]:
print(section)
print("\nArticle:")
print(result["article"]["content"])
- Input: 主题为“The History of Artificial Intelligence”。
- Output: 最终状态包含初步研究、视角、提问、检索结果、大纲和文章。
示例输出可能如下(具体取决于 LLM 和检索结果):
Outline:
- Introduction
- Early Concepts and Foundations
- The AI Boom and Modern Developments
- Ethical and Societal Impacts
Article:
The history of artificial intelligence (AI) spans decades, evolving from theoretical concepts to transformative technologies. ...
RA/SD 衍生者AI训练营。发布者:稻草人,转载请注明出处:https://www.shxcj.com/archives/9644