跳转到主内容

2 篇带有“langgraph”标签的文章

查看所有标签

研究的未来是混合模式

·阅读时长 8 分钟
Assaf Elovic
GPT Researcher 和 Tavily 的创建者

Hyrbrid Research with GPT Researcher

在过去的几年里,我们见证了旨在颠覆研究领域的新型人工智能工具的爆炸式增长。其中一些工具,如 ChatPDFConsensus,专注于从文档中提取见解。另一些工具,如 Perplexity,则擅长在网络上搜索信息。但问题是:这些工具中没有一个能将网络搜索和本地文档搜索结合在单一的、有上下文的研究流程中。

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

由网络驱动的研究通常缺乏特定背景,存在信息过载的风险,并且可能包含过时或不可靠的数据。另一方面,由本地驱动的研究仅限于历史数据和现有知识,可能造成组织内部的回声室效应,并错过关键的市场趋势或竞争对手的动态。这两种方法如果孤立使用,都可能导致不完整或有偏见的见解,从而妨碍您做出充分知情的决策。

今天,我们将改变这一局面。在本指南的最后,您将学会如何进行混合研究,它结合了网络和本地两种方式的优点,使您能够进行更彻底、更相关、更有见地的研究。

为什么混合研究效果更好

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

  1. 有根据的背景:本地文档为研究提供了经过验证的、特定于组织的信息基础。这使研究植根于已有的知识,降低了偏离核心概念或误解行业特定术语的风险。

    示例:一家制药公司在研究新药开发机会时,可以将其内部研究论文和临床试验数据作为基础,然后用网上最新发表的研究和监管更新来补充。

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

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

  3. 减少偏见:通过同时从网络和本地来源获取信息,我们降低了任何单一来源中可能存在的偏见风险。

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

  4. 改进规划和推理:大语言模型(LLM)可以利用本地文档的背景信息,更好地规划其网络研究策略,并对在网上找到的信息进行推理。

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

  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 这样的搜索引擎来查找相关结果。每个抓取的结果都会被保存在一个向量数据库中。最后,检索与研究任务最相关的 k 个数据块,以生成最终的研究报告。

GPT Researcher 支持混合研究,这涉及一个额外的步骤,即在检索最相关的信息之前对本地文档进行分块(使用 Langchain 实现)。经过社区的大量评估,我们发现混合研究将最终结果的正确性提高了 40% 以上!

使用 GPT Researcher 运行混合研究

现在您对混合研究的工作原理有了更好的理解,让我们来演示一下使用 GPT Researcher 实现这一点是多么容易。

第一步:使用 PIP 安装 GPT Researcher

pip install gpt-researcher

第二步:设置环境

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

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

第三步:使用混合研究配置初始化 GPT Researcher

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

要让 GPT Researcher 运行混合研究,您需要将所有相关文件放在 my-docs 目录中(如果不存在,请创建它),并将实例的 report_source 设置为 "hybrid",如下所示。一旦报告源设置为 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分钟阅读
Assaf Elovic
GPT Researcher 和 Tavily 的创建者

Header

学习如何使用 LangGraph 和一个由专业 AI 代理组成的团队来构建一个自主研究助手

GPT Researcher 初次发布至今才一年,但构建、测试和部署 AI 代理的方法已经发生了显著的演变。这正是当前 AI 进步的本质和速度。从简单的零样本或少样本提示开始,迅速演变为代理函数调用、RAG,现在最终发展到代理工作流(即“流程工程”)。

吴恩达(Andrew Ng)最近表示:“我认为 AI 代理工作流今年将推动 AI 取得巨大进步——甚至可能超过下一代基础模型。这是一个重要的趋势,我敦促所有从事 AI 工作的人都关注它。”

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

要跳过本教程,请随时查看 GPT Researcher x LangGraph 的 Github 仓库。

LangGraph 简介

LangGraph 是 LangChain 的一个扩展,旨在创建智能体和多智能体工作流。它增加了创建循环流程的能力,并内置了内存——这两者都是创建智能体的重要属性。

LangGraph 为开发者提供了高度的可控性,对于创建自定义代理和流程至关重要。生产环境中的几乎所有代理都是针对其试图解决的特定用例进行定制的。LangGraph 让你能够灵活地创建任意定制的代理,同时为此提供了直观的开发者体验。

闲话少说,让我们开始构建吧!

构建终极自主研究代理

通过利用 LangGraph,可以利用多个具有专业技能的代理来显著提高研究的深度和质量。让每个代理只专注于一项特定技能,可以实现更好的关注点分离、可定制性,并随着项目的发展支持更大规模的进一步开发。

受近期 STORM 论文的启发,这个例子展示了一个 AI 智能体团队如何协同工作,对给定主题进行研究,从规划到发布。这个例子还将利用领先的自主研究智能体 GPT Researcher。

研究智能体团队

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

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

架构

如下图所示,自动化过程基于以下几个阶段:规划研究、数据收集与分析、审阅与修订、撰写报告以及最终发布

Architecture

更具体地说,过程如下

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

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

  • 针对每个大纲主题(并行进行)

    • 研究员(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 包的 Researcher 智能体为例

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

如上所示,我们已经创建了一个 Research 智能体的实例。现在让我们假设我们已经为团队中的每个智能体都做了同样的操作。在创建所有智能体之后,我们将用 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"})

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

运行研究助理 在最终确定智能体、状态和图之后,是时候运行我们的研究助理了!为了使其更易于定制,该助理通过一个给定的 `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"
]
}

任务对象(task object)的含义非常直观,但请注意,如果 `follow_guidelines` 为 false,将导致图忽略修订步骤和定义的指导方针。此外,`max_sections` 字段定义了要研究的子标题数量。设置较少的值将生成较短的报告。

运行该助手将生成一份最终的研究报告,格式包括 Markdown、PDF 和 Docx。

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

下一步是什么?

展望未来,有很多令人兴奋的事情值得思考。人在回路(Human in the loop)是优化 AI 体验的关键。让用户帮助助手修订并专注于正确的研究计划、主题和提纲,将提高整体质量和体验。总的来说,在整个 AI 流程中争取人类干预,可以确保正确性、控制感和确定性的结果。很高兴看到 LangGraph 已经原生支持这一点,如此处所示。

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

最后,可以做出更多努力来提高检索到来源的质量,并确保最终报告以最佳的故事情节构建。

LangGraph 和多代理协作的下一步将是助手能够根据给定任务动态地规划和生成图。这一愿景将允许助手为给定任务仅选择代理的子集,并根据本文中介绍的图的基本原理来规划其策略,从而开启一个全新的可能性世界。考虑到 AI 领域的创新速度,不久之后就会有新版本的、颠覆性的 GPT Researcher 推出。期待未来带来的惊喜!

要持续关注该项目的进展和更新,请加入我们的 Discord 社区。和往常一样,如果您有任何反馈或进一步的问题,请在下方评论!