跳转到主内容

4 篇标记为 "gpt-researcher" 的文章

查看所有标签

走进 GPT Researcher 的故事

·阅读时长 5 分钟
Elisha Kramer
GPT Researcher 核心贡献者

GPTR reflecting ourselves

巴诺书店之梦

我记得十几岁时,走进巴诺书店(Barnes & Noble),空气中弥漫着新书的墨香,我的指尖划过那些塑造思想、俘获人心的书脊。我曾对自己低语:总有一天,我的名字也会出现在这里。

对我来说,书籍不仅仅是故事——它们是人类经验的反映,是人们更清晰地认识自己的方式。莎士比亚曾说:“艺术的目的是把镜子照向自然。”这个想法深深地打动了我。艺术、写作和讲故事不仅仅是为了娱乐,它们是为了以新的方式理解我们自己。

但世界变了。书店逐渐消失,人们的注意力转移,小说——曾经是深度思考和反思的巅峰——让位于新的互动形式。那种漫长而沉浸式的阅读体验,被一种更动态、更具互动性的东西所取代。

踏上编程之旅:辛巴时刻

大约9年前,就像《狮子王》中的辛巴一样,我踏上了一段充满怀疑和不确定性的新旅程。我离开了我熟悉的写作世界,踏入了未知的编程领域。起初,它像一门外语——无尽的语法、毫无头绪的调试错误,以及在开发者世界里感觉自己像个冒牌货的沮丧时刻。

这段旅程很艰难——我努力寻找自己的位置,面临合同被取消,被现实打击的次数多到数不清。每一次拒绝,每一次错失的机会都让我怀疑自己是否走错了路。也许我注定不该去创造——也许我注定要留在故事的世界里。

即使我最终在 Fiverr 找到了一份使用 JavaScript、MySQL、HTML 和 CSS 的工作,我仍然觉得自己抛弃了作为一名作家的身份。

发现 GPT Researcher

大约一年前的一个晚上,在我深入研究人工智能的兔子洞时,我偶然发现了 GPT Researcher。这个概念立刻打动了我——人工智能不仅仅是一个工具,它是一种扩展人类知识、提炼我们的问题、并重塑我们进行研究方式的手段。

我联系了 Assaf,并没有抱太大期望。但他没有礼貌地致意了事,而是欢迎我加入。那一刻——看到我的第一个 commit 被合并——感觉就像我旧日梦想的回响。只是这一次,我不仅仅是在写故事。我正在构建一个能帮助他人发现自己故事的东西。

研究者魔镜中的恶毒女巫

大约在那个时候,我发现自己反复向 GPT Researcher 问同一个问题:

“Elisha Kramer 是谁?”

起初,它就像《白雪公主》里的魔镜,回答一些很笼统的东西,比如:“Elisha Kramer 是一位在 Web 开发方面有经验的软件工程师。”它从我的领英、GitHub 和 Udemy 个人资料中提取信息,描绘出我的职业形象。但后来,事情变得奇怪了。

我向 GPT Researcher 提交了更多的 commit,做出了更多的贡献。随着我不断编码,我问了一个不同的问题。

“GitHub 上的 ElishaKay 是谁?”

随着时间的推移,答案变了,因为 Researcher 会从网络搜索结果中抓取最新的信息源。

“ElishaKay 是一位活跃的开源贡献者,拥有多个代码仓库,在过去一年中有超过 500 次 commit。”

我的天哪!它在学习。又一个 commit。又一个新功能。又一行文档。是时候问得更具体些了。

“gpt-researcher 项目的 ElishaKay 是谁?”

“ElishaKay 是 GPT Researcher 的核心贡献者,通过重要的代码和文档贡献,改善了研究工作流并增强了 AI 检索能力。”

这下说到点子上了。但我还没结束。就像那个恶毒女巫一样,我一次又一次地回来。更多的 commit。更多的改进。更多的功能。

直到最后,我问道:

“跟我聊聊 gpt-researcher 以及改进它的建议”

然后 GPT Researcher 看着我,回答道:

“GPTR 是一个蓬勃发展的开源社区。最好的前进道路是继续投资于这个社区——通过代码贡献、文档改进和帮助新贡献者入门。这个项目的力量在于其协作性。”

就在那时我明白了——我不仅仅是在使用 GPT Researcher,我正在成为它故事的一部分。

AI:我们自身的镜子

这种不断演变的反馈帮助我构建了自己的自我叙事。GPT Researcher 不仅仅是在反映已知的信息——它还在整合我的工作和更广泛的互联网背景。

它在反映我自己的旅程,每一步都在提炼它,模糊了固定身份的幻象,拥抱了一个不断演变的自我。

每一次查询,每一次 commit,每一次改进,都在塑造这个工具——反过来,它也在塑造我。

以社区之力共建

GPT Researcher 不仅仅是一个工具。它是开源精神的反映,一个活生生的、不断演进的生态系统,在这里知识不是静态的,而是不断被提炼。它不只是在回答问题;它在进行对话,根据最新的贡献、研究和发现来塑造和重塑叙事。这不再仅仅关乎我个人。它关乎我们。一个由 138 名贡献者组成的网络。一个被 20,000 颗星关注的开源项目。一个推动人工智能驱动研究边界的集体运动。

每一位研究者、每一位开发者、每一个好奇心强的人,无论是提炼问题、贡献功能,还是与这个工具互动,都是一个更大整体的一部分。人工智能不只是一个吐出答案的黑匣子——它是一个帮助我们提炼自己思想、挑战假设、扩展我们理解的工具。这是一个迭代的过程,就像生活本身一样。我们提供的背景信息越多,我们得到的洞见就越好。我们参与得越多,它反映的就不仅仅是我们曾经的样子,更是我们正在成为的样子。

一个仍在书写的故事

所以,虽然我曾经梦想在巴诺书店的书脊上看到我的名字,但现在我看到了更伟大的东西。我的文字不局限于一本书——它们存在于每一行代码、每一次贡献、每一个提炼问题的研究者之中。我们不仅仅是用户。我们是建设者。这不仅仅是我的故事。这是我们的故事。而且,这个故事仍在书写中。

研究的未来是混合模式

·阅读时长 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}

步骤 3:使用混合研究配置初始化 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%。此外,如上所述,本地信息有助于大语言模型(LLM)改进规划推理,使其能够做出更好的决策并研究更相关的网络来源。

但等等,还有更多!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"
]
}

任务对象非常不言自明,但请注意,如果 `follow_guidelines` 为 false,则会导致图忽略修订步骤和定义的指导方针。此外,`max_sections` 字段定义了要研究多少个子标题。设置得少一些会生成更短的报告。

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

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

下一步是什么?

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

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

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

LangGraph 和多代理协作的下一步发展将是,助理可以根据给定的任务动态地规划和生成图。这一愿景将允许助理为特定任务只选择一部分代理,并根据本文中介绍的图基本原理来规划其策略,从而开启一个全新的可能性世界。鉴于 AI 领域的创新速度,不久就会推出一个颠覆性的新版 GPT Researcher。期待未来带来的一切!

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

我们如何构建 GPT Researcher

·7分钟阅读
Assaf Elovic
GPT Researcher 和 Tavily 的创建者

AutoGPT 发布后,我们立即对其进行了试用。脑海中出现的第一个用例是自主在线研究。对于手动研究任务,形成客观结论可能需要数周时间来找到合适的资源和信息。看到 AutoGPT 创建和执行任务的出色表现,让我思考了使用 AI 进行全面研究的巨大潜力,以及这对未来在线研究意味着什么。

但 AutoGPT 的问题在于它通常会陷入无限循环,几乎每一步都需要人为干预,不断失去对其进度的追踪,而且几乎从未真正完成任务。

尽管如此,在研究任务期间收集的信息和上下文都丢失了(例如,没有跟踪来源),有时还会产生幻觉。

利用 AI 进行在线研究的热情以及我发现的局限性,使我踏上了尝试解决这个问题并与世界分享我的工作的征程。就在这时,我创建了 GPT Researcher — 一个用于在线全面研究的开源自主代理。

在本文中,我们将分享引导我走向所提出解决方案的步骤。

从无限循环到确定性结果

解决这些问题的第一步是寻求一个更具确定性的解决方案,该方案最终能够保证在固定的时间范围内完成任何研究任务,而无需人为干预。

就在这时,我们偶然发现了最近的一篇论文 Plan and Solve。该论文旨在为上述挑战提供更好的解决方案。其思想相当简单,由两个部分组成:首先,制定一个计划,将整个任务分解成更小的子任务,然后根据计划执行这些子任务。

Planner-Excutor-Model

就研究而言,首先创建一个与任务相关的研究问题大纲,然后为每个大纲项目确定性地执行一个代理。这种方法通过将代理步骤分解为一组确定的、有限的任务,消除了任务完成的不确定性。一旦所有任务完成,代理就结束研究。

遵循这一策略,完成研究任务的可靠性提高到了100%。现在的挑战是,如何提高质量和速度?

追求客观和无偏见的结果

大语言模型(LLM)最大的挑战是缺乏事实性和无偏见的响应,这是由幻觉和过时的训练集(GPT 目前的训练数据集来自 2021 年)造成的。但具有讽刺意味的是,对于研究任务来说,优化的恰恰是这两个标准:事实性和偏见。

为了应对这些挑战,我们做了以下假设

  • 大数定律——更多的内容将导致更少偏见的结果。尤其是在收集得当的情况下。
  • 利用大语言模型对事实信息进行总结,可以显著提高结果的整体事实性。

在与大语言模型(LLM)进行了一段时间的实验后,我们可以说,基础模型擅长的领域是对给定内容的总结和改写。因此,理论上,如果 LLM 仅审查给定的内容并对其进行总结和改写,可能会显著减少幻觉的产生。

此外,假设给定的内容是无偏见的,或者至少包含了关于一个主题的各方观点和信息,那么改写后的结果也将是无偏见的。那么内容如何才能无偏见呢?答案是大数定律。换句话说,如果抓取了足够多的包含相关信息的网站,那么信息产生偏见可能性就会大大降低。所以想法是,抓取足够多的网站,以形成对任何主题的客观意见。

太好了!听起来,我们现在有了一个如何创建既确定、又真实、又无偏见的结果的想法。但是速度问题呢?

加快研究进程

AutoGPT 的另一个问题是它同步工作。其主要思想是创建一个任务列表,然后逐一执行。因此,假设一个研究任务需要访问 20 个网站,每个网站的抓取和总结大约需要一分钟,那么整个研究任务至少需要 20 分钟以上。这还是在它能够停止的前提下。但如果我们能够并行化代理工作呢?

通过利用 Python 的 asyncio 等库,代理任务已得到优化,可以并行工作,从而显著减少了研究时间。

# Create a list to hold the coroutine agent tasks
tasks = [async_browse(url, query, self.websocket) for url in await new_search_urls]

# Gather the results as they become available
responses = await asyncio.gather(*tasks, return_exceptions=True)

在上面的例子中,我们并行触发所有 URL 的抓取,只有在全部完成后,才继续执行任务。根据多次测试,一个平均的研究任务大约需要三分钟(!!)。这比 AutoGPT 快了 85%。

完成研究报告

最后,在收集了尽可能多关于给定研究任务的信息之后,挑战在于撰写一份关于它的综合报告。

在实验了几个 OpenAI 模型甚至开源模型后,我得出结论,目前最好的结果是由 GPT-4 实现的。任务很简单——为 GPT-4 提供所有汇总的信息作为上下文,并要求它根据原始研究任务撰写一份详细的报告。

提示如下

"{research_summary}" Using the above information, answer the following question or topic: "{question}" in a detailed report — The report should focus on the answer to the question, should be well structured, informative, in depth, with facts and numbers if available, a minimum of 1,200 words and with markdown syntax and apa format. Write all source urls at the end of the report in apa format. You should write your report only based on the given information and nothing else.

结果相当令人印象深刻,只有极少数样本中出现了轻微的幻觉,但可以合理地假设,随着 GPT 的不断改进,结果只会越来越好。

最终架构

既然我们已经回顾了 GPT Researcher 的必要步骤,现在让我们来分解一下最终的架构,如下所示

更具体地说

  • 生成一份研究问题大纲,以形成对任何给定任务的客观意见。
  • 对于每个研究问题,触发一个爬虫代理,从在线资源中抓取与给定任务相关的信息。
  • 对于每个抓取的资源,进行跟踪、过滤,并且只有在包含相关信息时才进行总结。
  • 最后,汇总所有总结的来源,并生成一份最终的研究报告。

展望未来

在线研究自动化的未来正朝着一次重大的颠覆性变革发展。随着人工智能的不断进步,AI代理能够为我们日常的任何需求执行全面的研究任务只是时间问题。AI研究可以颠覆金融、法律、学术、健康和零售等领域,将我们每次研究的时间减少95%,同时在不断增长的海量在线信息中优化事实性和无偏见的报告。

想象一下,如果一个 AI 最终能够理解和分析任何形式的在线内容——视频、图像、图表、表格、评论、文本、音频。再想象一下,如果它能够在单个提示中支持和分析数十万字的聚合信息。甚至想象一下,AI 最终能够在推理和分析方面取得进步,使其更适合得出新的、创新的研究结论。而且它能在几分钟甚至几秒钟内完成所有这些。

这一切都只是时间问题,也正是 GPT Researcher 的意义所在。