跳至主内容

2篇带有"langgraph"标签的帖子

查看所有标签

研究的未来是混合式的

· 8 min read
Assaf Elovic
Creator @ GPT Researcher and Tavily

Hyrbrid Research with GPT Researcher

过去几年,我们见证了旨在颠覆研究工作的新型AI工具爆发式增长。诸如ChatPDFConsensus专注于从文档中提取洞见,而Perplexity等工具则擅长从网络抓取信息。但关键在于:目前还没有任何工具能在统一的情境研究流程中同时整合网络和本地文档搜索功能。

这就是为什么我很高兴向大家介绍GPT Researcher的最新进展——现在能够对任何给定任务和文档进行混合研究。

网络驱动的研究往往缺乏具体情境,存在信息过载的风险,并可能包含过时或不可靠的数据。另一方面,本地驱动的研究仅限于历史数据和现有知识,可能形成组织内部的信息茧房,错失关键市场趋势或竞争对手动向。这两种方法若单独使用,都可能导致不完整或有偏见的见解,从而影响您做出全面知情决策的能力。

今天,我们将改变游戏规则。通过本指南的学习,您将掌握如何进行混合研究,结合网络与本地资源的双重优势,从而开展更全面、更相关且更具洞察力的研究工作。

为什么混合研究方法更有效

通过结合网络和本地资源,混合研究解决了这些限制并提供了几个关键优势:

  1. 基于本地文档的上下文: 本地文档提供了经过验证的、组织专属信息的基础。这使研究扎根于既定知识,降低了偏离核心概念或误解行业特定术语的风险。

    示例: 某制药公司在研究新药开发机会时,可以以其内部研究论文和临床试验数据为基础,然后通过网络补充最新的已发表研究和监管更新。

  2. 提高准确性:网络来源提供最新信息,而本地文档则提供历史背景。这种结合可以实现更准确的趋势分析和决策制定。

    示例:一家金融服务公司在分析市场趋势时,可以将其历史交易数据与实时市场新闻和社交媒体情绪分析相结合,从而做出更明智的投资决策。

  3. 减少偏见:通过同时利用网络和本地资源,我们降低了单一来源可能存在的偏见风险。

    示例:一家科技公司在评估其产品路线图时,可以平衡内部功能需求和使用数据与外部客户评价及竞争对手分析,确保获得全面的视角。

  4. 改进的规划和推理能力: 大型语言模型可以利用本地文档的上下文信息,更好地规划其网络研究策略,并对在线发现的信息进行推理。

    示例: 一个由AI驱动的市场研究工具可以利用公司过去的营销活动数据来指导其搜索当前市场趋势,从而获得更具相关性和可操作性的见解。

  5. 定制化洞察: 混合研究可以将专有信息与公共数据整合,从而产生独特的、针对特定组织的洞察。

    示例: 一家零售连锁企业可以将其销售数据与网络抓取的竞争对手定价和经济指标相结合,以优化其在不同地区的定价策略。

这些只是企业可以利用混合研究的几个用例示例,闲话少说——让我们开始构建吧!

构建混合研究助手

在深入细节之前,值得指出的是GPT Researcher具备开箱即用的混合研究能力!但为了真正理解其运作原理并让您更深入地了解整个过程,我们将剖析其内部机制。

GPT Researcher hybrid research

GPT Researcher根据本地文档自动生成的计划进行网络研究,如上图架构所示。然后从本地和网络数据中检索相关信息,生成最终的研究报告。

我们将探讨如何利用LangChain处理本地文档,这是GPT Researcher文档处理的核心组件。随后,我们将展示如何运用GPT Researcher开展混合研究,将网络搜索的优势与您的本地文档知识库相结合。

使用Langchain处理本地文档

LangChain提供了多种文档加载器,使我们能够处理不同类型的文件。在处理多样化的本地文档时,这种灵活性至关重要。以下是设置方法:

from langchain_community.document_loaders import (
PyMuPDFLoader,
TextLoader,
UnstructuredCSVLoader,
UnstructuredExcelLoader,
UnstructuredMarkdownLoader,
UnstructuredPowerPointLoader,
UnstructuredWordDocumentLoader
)
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma

def load_local_documents(file_paths):
documents = []
for file_path in file_paths:
if file_path.endswith('.pdf'):
loader = PyMuPDFLoader(file_path)
elif file_path.endswith('.txt'):
loader = TextLoader(file_path)
elif file_path.endswith('.csv'):
loader = UnstructuredCSVLoader(file_path)
elif file_path.endswith('.xlsx'):
loader = UnstructuredExcelLoader(file_path)
elif file_path.endswith('.md'):
loader = UnstructuredMarkdownLoader(file_path)
elif file_path.endswith('.pptx'):
loader = UnstructuredPowerPointLoader(file_path)
elif file_path.endswith('.docx'):
loader = UnstructuredWordDocumentLoader(file_path)
else:
raise ValueError(f"Unsupported file type: {file_path}")

documents.extend(loader.load())

return documents

# Use the function to load your local documents
local_docs = load_local_documents(['company_report.pdf', 'meeting_notes.docx', 'data.csv'])

# Split the documents into smaller chunks for more efficient processing
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
splits = text_splitter.split_documents(local_docs)

# Create embeddings and store them in a vector database for quick retrieval
embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_documents(documents=splits, embedding=embeddings)

# Example of how to perform a similarity search
query = "What were the key points from our last strategy meeting?"
relevant_docs = vectorstore.similarity_search(query, k=3)

for doc in relevant_docs:
print(doc.page_content)

使用GPT Researcher进行网络研究

既然我们已经学会了如何处理本地文档,现在让我们快速了解一下GPT Researcher的内部工作原理:

GPT Researcher Architecture

如上所示,GPT Researcher会根据给定的任务创建研究计划,通过生成潜在的研究查询来共同提供对该主题的客观且全面的概述。一旦生成这些查询,GPT Researcher会使用像Tavily这样的搜索引擎来查找相关结果。每个抓取的结果随后会被保存在向量数据库中。最后,检索与研究任务最相关的top k数据块以生成最终的研究报告。

GPT Researcher支持混合研究模式,该模式在检索最相关信息前会额外执行一个本地文档分块步骤(通过Langchain实现)。经过社区大量评估验证,我们发现混合研究能将最终结果的准确率提升40%以上!

使用GPT Researcher进行混合研究

现在您对混合研究的工作原理有了更深入的理解,让我们展示一下使用GPT Researcher可以多么轻松地实现这一目标。

步骤1:使用PIP安装GPT Researcher

pip install gpt-researcher

步骤2:设置环境

我们将使用OpenAI作为大语言模型供应商和Tavily作为搜索引擎来运行GPT Researcher。在继续之前,您需要获取两者的API密钥。然后,在您的CLI中按以下方式导出环境变量:

export OPENAI_API_KEY={your-openai-key}
export TAVILY_API_KEY={your-tavily-key}

步骤3:使用混合研究配置初始化GPT Researcher

GPT Researcher可以通过参数轻松初始化,以指示其进行混合研究。您可以开展多种形式的研究,前往文档页面了解更多信息。

要让GPT Researcher执行混合研究,您需要将所有相关文件包含在my-docs目录中(如果不存在则创建该目录),并如下所示将实例report_source设置为"hybrid"。一旦报告来源设置为混合模式,GPT Researcher将在my-docs目录中查找现有文档并将其纳入研究。如果不存在任何文档,它将忽略此操作。

from gpt_researcher import GPTResearcher
import asyncio

async def get_research_report(query: str, report_type: str, report_source: str) -> str:
researcher = GPTResearcher(query=query, report_type=report_type, report_source=report_source)
research = await researcher.conduct_research()
report = await researcher.write_report()
return report

if __name__ == "__main__":
query = "How does our product roadmap compare to emerging market trends in our industry?"
report_source = "hybrid"

report = asyncio.run(get_research_report(query=query, report_type="research_report", report_source=report_source))
print(report)

如上所示,我们可以运行以下示例的研究:

  • 研究任务:"我们的产品路线图与行业新兴市场趋势相比如何?"
  • 网络:当前市场趋势、竞争对手公告和行业预测
  • 本地:内部产品路线图文档和功能优先级列表

经过多次社区评估,我们发现这项研究的结果将调研质量和准确性提升了40%以上,并减少了50%的幻觉现象。更重要的是,如上所述,本地信息能帮助大语言模型改进规划推理能力,使其做出更优决策并调研更相关的网络资源。

但等等,还有更多!GPT Researcher还包含一个使用NextJS和Tailwind构建的时尚前端应用。要了解如何运行它,请查看文档页面。您可以轻松使用拖放文档功能来进行混合研究。

结论

混合研究代表了数据收集和决策制定领域的重大进步。通过利用GPT Researcher等工具,团队现在能够进行更全面、情境感知且可操作的研究。这种方法解决了单独使用网络或本地资源的局限性,提供了诸多优势,例如基于实境的上下文、更高的准确性、减少偏见、改进的规划与推理能力,以及定制化的洞察。

混合研究的自动化可以使团队做出更快、更数据驱动的决策,最终提高生产力,并在分析不断增长的非结构化和动态信息池中提供竞争优势。

如何构建终极研究多智能体助手

· 10 min read
Assaf Elovic
Creator @ GPT Researcher and Tavily

Header

学习如何使用LangGraph构建一个由专业AI智能体团队组成的自主研究助手

GPT Researcher 自首次发布仅过去一年,但构建、测试和部署智能体的方法已经发生了显著变化。这正是当前人工智能发展的本质和速度。从最初简单的零样本或少样本提示,迅速演变为智能体函数调用、RAG(检索增强生成),如今最终发展为智能体工作流(又称"流程工程")。

吴恩达最近表示:“我认为AI智能体工作流将在今年推动人工智能的重大进展——甚至可能超过下一代基础模型。这是一个重要趋势,我敦促所有从事AI工作的人都予以关注。”

在本文中,您将了解为什么多智能体工作流是当前的最佳标准,以及如何使用LangGraph构建最优的自主研究多智能体助手。

要跳过本教程,欢迎查看GPT Researcher x LangGraph的Github仓库。

LangGraph简介

LangGraph是LangChain的一个扩展,旨在创建智能体和多智能体流程。它增加了创建循环流程的能力,并内置了记忆功能——这两者对于构建智能体都是至关重要的特性。

LangGraph为开发者提供了高度的可控性,对于创建自定义智能体和流程至关重要。实际生产环境中几乎所有的智能体都会针对其试图解决的具体用例进行定制。LangGraph让您能够灵活创建任意自定义智能体,同时提供直观的开发者体验来实现这一目标。

寒暄到此为止,让我们开始构建吧!

构建终极自主研究智能体

通过利用LangGraph,研究过程的深度和质量可以得到显著提升,这得益于多个具备专业技能的智能体的协同工作。让每个智能体专注于并精通某一特定技能,能够实现更好的关注点分离、更高的可定制性,并随着项目规模的扩大而持续进行扩展开发。

受近期STORM论文的启发,本示例展示了AI智能体团队如何协作完成从规划到发布的给定主题研究。该示例还将利用领先的自主研究智能体GPT Researcher。

研究智能体团队

研究团队由七个LLM智能体组成:

  • 主编 — 监督研究过程并管理团队。这是使用LangGraph协调其他智能体的"主控"智能体。该智能体作为主要的LangGraph接口。
  • GPT Researcher — 一个专门化的自主智能体,能够对给定主题进行深入研究。
  • 编辑 — 负责规划研究大纲和结构。
  • 审阅者 — 根据给定标准验证研究结果的正确性。
  • 修订者 — 根据审阅者的反馈修订研究成果。
  • Writer — 负责编译和撰写最终报告。
  • 发布者 — 负责以多种格式发布最终报告。

架构

如下所示,自动化流程基于以下阶段:规划研究、数据收集与分析、审核与修订、撰写报告,最后发布:

Architecture

更具体地说,流程如下:

  • 浏览器 (gpt-researcher) — 根据给定的研究任务在互联网上进行初步调研。这一步骤对大型语言模型至关重要,使其能够基于最新相关信息规划研究流程,而不仅仅依赖预训练数据来处理特定任务或主题。

  • 编辑 — 根据初步研究规划报告大纲和结构。编辑还负责根据规划的大纲触发并行研究任务。

  • 针对每个大纲主题(并行处理):

    • 研究员 (gpt-researcher) — 对子主题进行深入研究并撰写初稿。该智能体底层使用GPT Researcher Python包,用于生成经过优化的、深入且基于事实的研究报告。
    • 审阅者 — 根据一组指南验证草稿的正确性,并向修订者提供反馈(如有需要)。
    • 修订者 — 根据评审反馈不断修改草稿,直至达到满意效果。
  • 撰写者 — 根据给定的研究发现,编译并撰写最终报告,包括引言、结论和参考文献部分。

  • 发布器 — 将最终报告发布为多种格式,如PDF、Docx、Markdown等。

  • 由于代码量庞大,我们不会深入探讨所有代码,而是主要聚焦于我发现的值得分享的有趣部分。

定义图状态

LangGraph最让我喜爱的功能之一是状态管理。在LangGraph中,状态通过结构化方法实现,开发者可以定义一个GraphState来封装应用程序的完整状态。图中的每个节点都可以修改这个状态,从而根据交互过程中不断变化的上下文生成动态响应。

就像任何技术设计的开始阶段,考虑整个应用程序的数据架构是关键。在本例中,我们将定义一个ResearchState如下:

class ResearchState(TypedDict):
task: dict
initial_research: str
sections: List[str]
research_data: List[dict]
# Report layout
title: str
headers: dict
date: str
table_of_contents: str
introduction: str
conclusion: str
sources: List[str]
report: str

如上所示,状态分为两个主要区域:研究任务和报告布局内容。当数据在智能体图中流转时,每个智能体会基于现有状态依次生成新数据,并更新状态以便后续与其他智能体在图中进行进一步处理。

然后我们可以用以下方式初始化图表:

from langgraph.graph import StateGraph
workflow = StateGraph(ResearchState)

使用LangGraph初始化图表 如上所述,多智能体开发的一大优势在于构建每个智能体使其具备专业化和限定范围的技能。让我们以使用GPT Researcher Python包的研究员智能体为例:

from gpt_researcher import GPTResearcher

class ResearchAgent:
def __init__(self):
pass

async def research(self, query: str):
# Initialize the researcher
researcher = GPTResearcher(parent_query=parent_query, query=query, report_type=research_report, config_path=None)
# Conduct research on the given query
await researcher.conduct_research()
# Write the report
report = await researcher.write_report()

return report

如上所示,我们已经创建了一个研究智能体的实例。现在假设我们对团队中的每个智能体都进行了同样的操作。在创建完所有智能体后,我们将使用LangGraph初始化图结构:

def init_research_team(self):
# Initialize skills
editor_agent = EditorAgent(self.task)
research_agent = ResearchAgent()
writer_agent = WriterAgent()
publisher_agent = PublisherAgent(self.output_dir)

# Define a Langchain StateGraph with the ResearchState
workflow = StateGraph(ResearchState)

# Add nodes for each agent
workflow.add_node("browser", research_agent.run_initial_research)
workflow.add_node("planner", editor_agent.plan_research)
workflow.add_node("researcher", editor_agent.run_parallel_research)
workflow.add_node("writer", writer_agent.run)
workflow.add_node("publisher", publisher_agent.run)

workflow.add_edge('browser', 'planner')
workflow.add_edge('planner', 'researcher')
workflow.add_edge('researcher', 'writer')
workflow.add_edge('writer', 'publisher')

# set up start and end nodes
workflow.set_entry_point("browser")
workflow.add_edge('publisher', END)

return workflow

如上所示,创建LangGraph图非常简单直接,主要由三个核心函数组成:add_node、add_edge和set_entry_point。通过这些主要函数,您可以先向图中添加节点,连接边,最后设置起始点。

重点检查:如果你一直在正确跟踪代码和架构,你会注意到上面的初始化中缺少了Reviewer和Reviser智能体。让我们深入探讨这个问题!

支持有状态并行化的图中图

这是我在使用LangGraph过程中最令人兴奋的部分!这个自主智能体的一个亮点功能是能够并行执行每项研究任务,并根据一组预定义的指导方针进行审查和修订。

了解如何在流程中利用并行工作是优化速度的关键。但如果所有智能体都向同一状态报告,该如何触发并行智能体工作?这可能导致最终数据报告中的竞争条件和不一致。为解决此问题,您可以创建一个子图,该子图将从主LangGraph实例触发。这个子图将为每次并行运行维护自己的状态,从而解决上述问题。

和之前一样,让我们定义LangGraph状态及其智能体。由于这个子图主要是审查和修改研究草稿,我们将用草稿信息来定义状态:

class DraftState(TypedDict):
task: dict
topic: str
draft: dict
review: str
revision_notes: str

正如DraftState所示,我们主要关注讨论的主题、审阅者以及修订说明,因为它们相互沟通以最终确定子主题研究报告。为了创建循环条件,我们将利用LangGraph的最后一个重要部分——条件边:

async def run_parallel_research(self, research_state: dict):
workflow = StateGraph(DraftState)

workflow.add_node("researcher", research_agent.run_depth_research)
workflow.add_node("reviewer", reviewer_agent.run)
workflow.add_node("reviser", reviser_agent.run)

# set up edges researcher->reviewer->reviser->reviewer...
workflow.set_entry_point("researcher")
workflow.add_edge('researcher', 'reviewer')
workflow.add_edge('reviser', 'reviewer')
workflow.add_conditional_edges('reviewer',
(lambda draft: "accept" if draft['review'] is None else "revise"),
{"accept": END, "revise": "reviser"})

通过定义条件边,如果审阅者存在审阅意见,图表将指向修订者,否则循环将以最终草案结束。如果回到我们构建的主图表,你会看到这个并行工作位于由ChiefEditor智能体调用的名为“researcher”的节点下。

运行研究助手 在确定智能体、状态和图表后,是时候运行我们的研究助手了!为了便于自定义,该助手通过给定的task.json文件运行:

{
"query": "Is AI in a hype cycle?",
"max_sections": 3,
"publish_formats": {
"markdown": true,
"pdf": true,
"docx": true
},
"follow_guidelines": false,
"model": "gpt-4-turbo",
"guidelines": [
"The report MUST be written in APA format",
"Each sub section MUST include supporting sources using hyperlinks. If none exist, erase the sub section or rewrite it to be a part of the previous section",
"The report MUST be written in spanish"
]
}

任务对象本身已经非常直观明了,但请注意如果follow_guidelines设为false,会导致图谱忽略修订步骤和已定义的指导原则。此外,max_sections字段定义了需要研究的子标题数量。设置较小的值将生成较短的报告。

运行该助手将生成最终的研究报告,支持Markdown、PDF和Docx等格式。

要下载并运行示例,请查看GPT Researcher与LangGraph的开源页面

下一步是什么?

展望未来,有许多令人兴奋的思考方向。人机协同是优化AI体验的关键。通过人类协助助手修订并聚焦于最恰当的研究计划、主题和提纲,将显著提升整体质量和体验。此外,在AI流程中始终注重人类干预,能确保结果的正确性、可控性和确定性。很高兴看到LangGraph已经原生支持这一功能,具体可参考此处。

此外,支持对网络和本地数据的研究对于许多商业和个人用例来说至关重要。

最后,可以投入更多努力来提升检索来源的质量,并确保最终报告以最优的故事线构建。

在LangGraph和多智能体协作领域向前迈进的一步将是助手能够根据给定任务动态规划和生成图。这一愿景将使助手能够仅为特定任务选择一部分智能体,并根据本文介绍的图基础规划其策略,从而开启一个充满可能性的全新世界。鉴于人工智能领域的创新速度,新一代颠覆性的GPT Researcher版本很快将会问世。期待未来带来的惊喜!

要了解该项目的持续进展和更新,请加入我们的Discord社区。一如既往,如果您有任何反馈或进一步的问题,请在下方留言!