当前位置: 首页 > article >正文

全新大模型框架Haystack,搭建RAG pipeline

大家好,在AI应用开发的赛道上,目前Haystack以其开源框架的优势,成为LLM技术领域的一匹黑马,对现有竞争者构成挑战。本文将介绍Haystack的亮点优势,并分析它为何能在众多LLM框架中脱颖而出,通过RAG应用实例来展示Haystack的实际应用能力。

1.Haystack简介

Haystack是一个强大的工具包,帮助开发者用少量代码创建AI应用,尤其擅长处理大量文本或文档;能够简化开发实用LLM应用的过程。简单来说,Haystack就像一套多功能的积木,可以灵活组合,可以搭建出各式各样的AI系统。

使用Haystack,能够实现多种应用场景,例如:

  • 基于大量文档回答问题的聊天机器人

  • 能够从众多文档中查找和提取特定信息的系统

  • 能够理解和处理文本、图像和其他类型数据的应用

在Python 3.10环境下,可以通过以下命令安装Haystack:

pip install haystack-ai

2.Haystack工作原理

Haystack的运作依赖于两个核心概念:

  • 组件:可以视为独立的工具,每个工具都承担着特定的任务。比如,某个组件可能专门用来检索相关文档,而另一个则负责生成文本回答。

  • 管道:决定了组件之间的连接方式。通过管道,我们定义了组件的工作顺序以及它们之间信息的传递路径。

利用这些组件的不同组合,开发者能够构建出处理复杂任务的AI系统。

3.Haystack核心优势

  • 灵活性:可以与许多不同的AI模型(如OpenAI、HuggingFace等)和数据存储系统(如ChromaDB、Pinecone,甚至是Neo4j)无缝协作。

  • 易用性:即使不精通AI的复杂技术细节,开发者也能轻松上手Haystack。

  • 可定制性:开发者可以根据特定需求,创建或调整组件。Haystack采用Pydantic结构,定制过程更加简便。

  • 应用多样性:支持构建不同类型的AI系统,从问答到信息提取。

4.构建RAG管道

安装好Haystack之后,接下来只需安装trafilatura和lxml,这两个工具用于提取HTML文档:

pip install trafilatura lxml_html_clean

这里将构建两个管道:一个负责文档的清洗与处理,另一个则用于实现RAG功能。

导入相关包:

import urllib.request
from haystack import Pipeline
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.components.retrievers import InMemoryEmbeddingRetriever
from haystack.components.converters import HTMLToDocument
from haystack.components.preprocessors import DocumentCleaner, DocumentSplitter
from haystack.components.embedders import OpenAIDocumentEmbedder, OpenAITextEmbedder
from haystack.components.writers import DocumentWriter
from haystack.components.builders import PromptBuilder
from haystack.components.generators import OpenAIGenerator

from dotenv import load_dotenv
load_dotenv()

将OpenAI密钥放在.env文件中:

OPENAI_API_KEY = 'YOUR KEY'

提取我们的文本,将其存储在文件夹中。

urllib.request.urlretrieve("https://www.oreilly.com/openbook/freedom/ch01.html", "free_as_in_freedom.html")

我们从连接两个管道的组件着手,这个组件负责将处理后的文档存储在内存中:

document_store = InMemoryDocumentStore()

接下来是管道的第一个组件和输入部分。利用之前创建的HTML文件:

text_file_converter = HTMLToDocument()

这个转换器可以接受路径、字符串或字节流作为输入,并返回一个文档列表。这些文档需要经过清洗,以提高可读性。这便是管道的下一步:

cleaner = DocumentCleaner()

cleaner组件的任务是提升文本文档的可读性,可以通过它删除空行、多余空格或重复的子字符串等。

随后,根据RAG模型的要求,需要将文档切割成块。这对于处理超出语言模型最大文本长度限制的长文本非常有用,同时也能加快问答的处理速度。在我们的案例中,将文档按句子分割,每块包含5个句子:

splitter = DocumentSplitter(split_by="sentence", split_length=5)

文档切割完成后,准备将其嵌入。这里使用OpenAI提供的OpenAIDocumentEmbedder,它负责计算文档列表的嵌入向量,并将这些向量存储在每个文档的嵌入字段中:

embedder = OpenAIDocumentEmbedder()

最后通过riter组件,它是第一个管道的输出部分,负责将文档列表写入最初定义的文档存储中,以便在下一个管道中使用:

writer = DocumentWriter(document_store)

如果想添加其他类型的文档,如Excel或PDF,需创建一个新的管道或调整现有管道,并将其存储在InMemoryDocumentStore组件中。在管道中逐个添加组件:

indexing_pipeline = Pipeline()

indexing_pipeline.add_component("converter", text_file_converter)
indexing_pipeline.add_component("cleaner", cleaner)
indexing_pipeline.add_component("splitter", splitter)
indexing_pipeline.add_component("embedder", embedder)
indexing_pipeline.add_component("writer", writer)

将这些组件连接起来:

indexing_pipeline.connect("converter.documents", "cleaner.documents")
indexing_pipeline.connect("cleaner.documents", "splitter.documents")
indexing_pipeline.connect("splitter.documents", "embedder.documents")
indexing_pipeline.connect("embedder.documents", "writer.documents")

运行管道:

indexing_pipeline.run(data={"sources": ["free_as_in_freedom.html"]})

输出结果:

Calculating embeddings: 100%|██████████| 2/2 [00:01<00:00, 1.10it/s]
{'embedder': {'meta': {'model': 'text-embedding-ada-002', 'usage': {'prompt_tokens': 5191, 'total_tokens': 5191}}}, 'writer': {'documents_written': 39}}

整个过程非常直接,在启动文档处理流程之前,需要指定HTML文件作为待处理的输入数据。

通过执行以下代码,可以查看第一个管道的结构:

indexing_pipeline.show()

现在已经集齐了构建RAG部分所需的所有组件,它们将助力系统最终能够响应我们的各种查询。

5.RAG管道

首先,要确定用于文本嵌入的模型。Haystack支持多种嵌入选项,包括OpenAI和HuggingFace,同时也在不断集成更多。为了简化操作,选择使用OpenAI的嵌入器:

text_embedder = OpenAITextEmbedder()

接下来,利用之前处理好并存储在document_store中的文档。可以根据业务需求,选择不同的检索策略,如topk、scalescore或filter等:

retriever = InMemoryEmbeddingRetriever(document_store)

这个组件负责输出经过处理、准备好进行嵌入的文档列表。现在完成RAG管道的最后两个部分,构建提示和选择语言模型(LLM)。

定义一个基本的提示模板:

template = """Given these documents, answer the question.
Documents:
{% for doc in documents %}
{{ doc.content }}
{% endfor %}
Question: {{query}}
Answer:"""
prompt_builder = PromptBuilder(template=template)

对于LLM,同样选择使用OpenAI模型:

llm = OpenAIGenerator()

将这些组件串联起来,正如之前所做的:

rag_pipeline = Pipeline()

rag_pipeline.add_component("text_embedder", text_embedder)
rag_pipeline.add_component("retriever", retriever)
rag_pipeline.add_component("prompt_builder", prompt_builder)
rag_pipeline.add_component("llm", llm)

连接各个组件:

rag_pipeline.connect("text_embedder.embedding", "retriever.query_embedding")
rag_pipeline.connect("retriever.documents", "prompt_builder.documents")
rag_pipeline.connect("prompt_builder", "llm")

输出的组件和连接概览如下:

Components
- text_embedder: OpenAITextEmbedder
- retriever: InMemoryEmbeddingRetriever
- prompt_builder: PromptBuilder
- llm: OpenAIGenerator
Connections
- text_embedder.embedding -> retriever.query_embedding (List[float])
- retriever.documents -> prompt_builder.documents (List[Document])
- prompt_builder.prompt -> llm.prompt (str)

最后,查看管道的完整结构:

rag_pipeline.show()

 RAG管道构建完成,它将能够根据提供的文档回答各种问题。

6.评估RAG管道

以Richard M. Stallman为例,他是麻省理工学院人工智能实验室的一位软件程序员,曾经历过一次设备故障的苦难。

query = " What is the profession of Richard M. Stallman and where does he works ?"
result = rag_pipeline.run(data={"prompt_builder": {"query":query}, "text_embedder": {"text": query}})
print(result["llm"]["replies"][0])

得到的答案是:

Richard M. Stallman is a software programmer and he works at the Massachusetts Institute of Technology's Artificial Intelligence Laboratory.

另一次,当他到达实验室时,发现打印机托盘里只有四页纸,而这四页还属于其他用户。更糟糕的是,这意味着Stallman的打印任务和另一位用户的打印任务的一部分,仍然卡在实验室计算机网络的电子管道中。

query = "Why did Stallman get frustrated when he tried to retrieve his print job from the new Xerox printer ?"

输出结果:

Stallman got frustrated when he tried to retrieve his print job from the new Xerox printer because only four pages in the printer's tray belonged to another user, meaning that Stallman's print job and the unfinished portion of somebody else's print job were still trapped somewhere within the electrical plumbing of the lab's computer network.

两次查询都完美回答,此外还可以查看请求中使用的令牌数量,以跟踪使用情况:

result['llm']['meta'][0]['usage']
#{'completion_tokens': 65, 'prompt_tokens': 1476, 'total_tokens': 1541}

综上所述,Haystack是开发者手中的得力助手,专门用来打造处理海量文本或文档的LLM人工智能应用。它配备了丰富的组件,这些组件能够像乐高积木一样,通过不同的组合方式,拼装出各种AI解决方案。尽管掌握Haystack需要一些编程技能,但它的核心目标是让AI应用的开发变得更加亲民,让广泛的开发者都能轻松驾驭。


http://www.kler.cn/a/374925.html

相关文章:

  • 第2章 JSP基础
  • wsl2.0(windows linux子系统)使用流程
  • 软件测试基础知识总结
  • 【Linux第七课--基础IO】内存级文件、重定向、缓冲区、文件系统、动态库静态库
  • 【网络安全】揭示 Web 缓存污染与欺骗漏洞
  • windows系统命令讲解
  • 从零开始的C++之旅——string类的模拟实现
  • 【Git】Git常用命令
  • (蓝桥杯C/C++)——常用库函数
  • 【Deno运行时】深入解析Deno:下一代JavaScript和TypeScript运行时
  • cisco网络安全技术第4章测试及考试
  • 高效扶贫:SpringBoot精准扶贫系统
  • 笔记整理—linux驱动开发部分(4)驱动框架
  • 【Nginx】编译安装(Centos)
  • Windows下Jenkins自动启动jar包
  • 技术总结(十九)
  • unity后端kbengine用DOTween让 移动同步丝滑
  • HJ106 字符逆序
  • 发布 NPM 包时,终端显示发布成功但实际上版本并没有更新,可能是由于以下原因
  • 基于 Postman 和 Elasticsearch 测试乐观锁的操作流程
  • Java的多态
  • LEADTOOLS 版本 23 现已发布,引入了 Excel API等众多新功能!
  • 就业市场变革:AI时代,我们将如何评估人才?
  • Python之groupby()及aggregate()方法
  • 手机实时提取SIM卡打电话的信令声音-新的篇章(三、Android虚拟声卡探索)
  • 每日互动基于 Apache DolphinScheduler 从容应对ClickHouse 大数据入库瓶颈