博客阅读聊天机器人使用GPT-4o

时间: 90 分钟级别: 高级GitHub

在本教程中,您将构建一个RAG系统,该系统将博客内容摄取与语义搜索功能相结合。OpenAI的GPT-4o LLM非常强大,但要扩展其使用,我们需要系统地提供上下文。

RAG通过检索相关文档来辅助问答过程,从而增强LLM的答案生成能力。这种设置展示了高级搜索和AI语言处理的集成,以改进信息检索和生成任务。

本教程的笔记本可在GitHub上获取。

数据隐私与主权: RAG应用程序通常依赖于敏感或专有的内部数据。为了保持对这些数据的控制,在自己的环境中运行整个堆栈变得至关重要。在Scaleway上部署的Qdrant混合云完美地满足了这一需求,提供了一个安全、可扩展的平台,同时充分利用了RAG的全部潜力。Scaleway提供了无服务器函数和无服务器工作,这两者都非常适合在大规模RAG案例中创建嵌入。

组件

  • 云主机: Scaleway上的托管Kubernetes 用于与 Qdrant 混合云兼容。
  • 向量数据库: Qdrant Hybrid Cloud 作为向量搜索引擎用于检索。
  • LLM: 由OpenAI开发的GPT-4o被用作生成答案的生成器。
  • 框架: LangChain 提供广泛的RAG功能。

Architecture diagram

Langchain 支持广泛的LLMs,本教程中使用GPT-4o作为主要生成器。您可以轻松地将其替换为您偏好的模型,该模型可能在您的场所启动,以完成完全私有的设置。为了简单起见,我们使用了OpenAI API,但LangChain使过渡变得无缝。

在Scaleway上部署Qdrant混合云

Scaleway KapsuleKosmos 是来自 Scaleway 的托管 Kubernetes 服务。它们抽象了管理和操作 Kubernetes 集群的复杂性。主要区别在于,Kapsule 集群仅由 Scaleway 实例组成。而 Kosmos 集群是一个托管的多云 Kubernetes 引擎,允许您将来自任何云提供商的实例连接到单个托管的控制平面。

  1. To start using managed Kubernetes on Scaleway, follow the 平台特定文档.
  2. Once your Kubernetes clusters are up, 您可以开始部署 Qdrant 混合云.

先决条件

为了准备使用Qdrant及相关库的环境,需要安装所有必需的Python包。这可以使用Poetry来完成,Poetry是一个用于Python依赖管理和打包的工具。代码片段导入了各种对即将进行的任务至关重要的库,包括用于解析HTML和XML文档的bs4,用于处理语言模型和文档加载器的langchain及其社区扩展,以及用于向量存储和检索的Qdrant。这些导入为将Qdrant与其他自然语言处理和机器学习任务工具一起使用奠定了基础。

Qdrant 将在特定的 URL 上运行,并且访问将受到 API 密钥的限制。请确保将它们都存储为环境变量:

export QDRANT_URL="https://qdrant.example.com"
export QDRANT_API_KEY="your-api-key"

可选: 每当你使用LangChain时,你也可以配置LangSmith,这将帮助我们跟踪、监控和调试LangChain应用程序。你可以在这里注册LangSmith。

export LANGCHAIN_TRACING_V2=true
export LANGCHAIN_API_KEY="your-api-key"
export LANGCHAIN_PROJECT="your-project"  # if not specified, defaults to "default"

现在你可以开始了:

import getpass
import os

import bs4
from langchain import hub
from langchain_community.document_loaders import WebBaseLoader
from langchain_qdrant import Qdrant
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter

设置OpenAI API密钥:

os.environ["OPENAI_API_KEY"] = getpass.getpass()

初始化语言模型:

llm = ChatOpenAI(model="gpt-4o")

在这里,我们配置了Embeddings和LLM。你可以使用Ollama或其他服务替换为你自己的模型。Scaleway提供了一些很棒的L4 GPU实例,你可以在这里用于计算。

下载并解析数据

开始处理博客文章内容时,过程包括加载和解析HTML内容。这是通过使用urllibBeautifulSoup实现的,这些工具专为此类任务设计。内容加载并解析后,使用Qdrant进行索引,Qdrant是一个用于管理和查询向量数据的强大工具。代码片段展示了如何通过指定博客的URL和要解析的特定HTML元素来加载、分块和索引博客文章的内容。此步骤对于准备数据以便使用Qdrant进行进一步处理和分析至关重要。

# Load, chunk and index the contents of the blog.
loader = WebBaseLoader(
    web_paths=("https://lilianweng.github.io/posts/2023-06-23-agent/",),
    bs_kwargs=dict(
        parse_only=bs4.SoupStrainer(
            class_=("post-content", "post-title", "post-header")
        )
    ),
)
docs = loader.load()

数据分块

在处理大型文档时,例如超过42,000个字符的博客文章,高效管理数据以进行处理至关重要。许多模型的上下文窗口有限,难以处理长输入,这使得提取或查找相关信息变得困难。为了克服这个问题,文档被分成较小的块。这种方法增强了模型处理和检索文档中最相关部分的能力。

在这个场景中,文档使用RecursiveCharacterTextSplitter分割成指定大小和重叠的块。这种方法确保在块之间不会丢失关键信息。分割后,这些块被索引到Qdrant——一个用于高效相似性搜索和嵌入存储的向量数据库。Qdrant.from_documents函数用于索引,文档是分割后的块,嵌入通过OpenAIEmbeddings生成。整个过程在内存数据库中完成,这意味着操作无需持久存储,并且集合被命名为“lilianweng”以供参考。

这种分块和索引策略显著提高了从大型文档中管理和检索信息的效率,使其成为处理数据处理工作流中大量文本的实用解决方案。

text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
splits = text_splitter.split_documents(docs)

vectorstore = Qdrant.from_documents(
    documents=splits,
    embedding=OpenAIEmbeddings(),
    collection_name="lilianweng",
    url=os.environ["QDRANT_URL"],
    api_key=os.environ["QDRANT_API_KEY"],
)

检索并生成内容

vectorstore 被用作检索器,基于向量相似性获取相关文档。hub.pull("rlm/rag-prompt") 函数用于从存储库中拉取特定的提示,该提示设计用于与检索到的文档和问题一起生成响应。

format_docs 函数将检索到的文档格式化为单个字符串,为后续处理做准备。这个格式化后的字符串与一个问题一起通过一系列操作传递。首先,上下文(格式化后的文档)和问题由检索器和提示处理。然后,结果被输入到一个大型语言模型(llm)中以生成内容。最后,使用StrOutputParser()将输出解析为字符串格式。

这一系列操作展示了信息检索和内容生成的复杂方法,利用了向量搜索的语义理解能力和大型语言模型的生成能力。

现在,使用博客中的相关片段检索并生成数据。

retriever = vectorstore.as_retriever()
prompt = hub.pull("rlm/rag-prompt")


def format_docs(docs):
    return "\n\n".join(doc.page_content for doc in docs)


rag_chain = (
    {"context": retriever | format_docs, "question": RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
)

调用RAG链

rag_chain.invoke("What is Task Decomposition?")

下一步:

我们为一个简单的聊天机器人打下了坚实的基础,但仍有许多工作要做。如果您希望使系统达到生产就绪状态,您应该考虑将机制实施到现有的技术栈中。我们建议

我们的向量数据库可以轻松托管在Scaleway上,这是我们值得信赖的Qdrant 混合云合作伙伴。这意味着Qdrant可以从您的Scaleway区域运行,但数据库本身仍然可以通过Qdrant Cloud的界面进行管理。这两个产品已经过兼容性和可扩展性测试,我们推荐他们的托管Kubernetes服务。 他们的法国部署区域(例如法国)在网络延迟和数据主权方面表现出色。对于托管GPU,可以尝试使用L4 GPU实例进行渲染

如果您有任何问题,请随时在我们的Discord社区上提问。

这个页面有用吗?

感谢您的反馈!🙏

我们很抱歉听到这个消息。😔 你可以在GitHub上编辑这个页面,或者创建一个GitHub问题。